Clojure in the Cloud Everett Toews Developer JavaOne Sept. 29, 12:30 pm
Intro Developer
PMC and Committer on Apache jclouds
Intro Advocate
Operations
Co-author of The OpenStack Ops Guide docs.openstack.org/ops
Clojure
List
(2 3)
Clojure Vector
[2 3]
Clojure Map
{:key1 "value1" :key2 "value2"} :key2 "value2"}
Clojure Parens
(fn arg1 arg2) (sf arg1 arg2)
Clojure Prefix
(+ 2 3) ; 5
Clojure Functional
(defn add-7 [x] [x] (+ x 7)) (+ x 7))
(add-7 3) ; 10
(map add-7 [2 3]) ; (9 10)
Clojure Types
(add-7 "3") ; ClassCastException java.lang.String cannot be cast to java.lang.Number
Clojure Destructuring
1 (defn print-args 2 [f & rest] 3 (println f) 4 (println 5 (apply sorted-map rest)))
(print-args "first" :k3 "v3" :k1 "v1" :k3 "v3" :k1 "v1" :k2 "v2") :k2 "v2") ; first ; {:k1 v1, :k2 v2, :k3 v3}
Clojure Lambda
(map (fn [x] (+ x 7)) (fn [x] (+ x 7)) [2 3]) [2 3]) ; (9 10)
Clojure Macro
(defmacro when [test & body] [test & body] (list 'if test (list 'if test (cons 'do body))) (cons 'do body)))
(when true (+ 2 3)) ; 5
Clojure lein
lein new app github-comment-clj lein clean lein install lein test lein run lein repl
Clojure REPL
PrintEvalRead Loop
Cloud
SaaS
IaaS
Resources Accessible Via HTTP API
HTTP APIs
Documentation
Logging
Auth
Endpoint
Environment
Connect!
Request
Response
Headers
Body
JSON
Clojure in the Cloud
Conjecture in the Cloud ClojectureConjecture
Clojure in the Cloud Clojure > Java
Clojure in the Cloud Domain Modeling vsMaps
Example ExampleSurprise!
"""" {"key": "value"} Map Map
"" {"key": {BLAH}}ParseException
Example Example Changing Objects
"""" {"obj": "BLAH"} "" {"obj": {BLAH}} "" {"obj": [BLAH]}
Clojure in the Cloud Example Huge Objects
Clojure in the Cloud Maps
WARNING Demos Ahead
Clojure in the Cloud Compile/Run/printlnvsREPL
Demo lein repl
Clojure in the Cloud pom.xml/mvn/Classvs lein try
Clojure in the Cloud Demo lein try
Clojure in the Cloud Works For Me vs I Feel Your Pain
Clojure in the Cloud Demo lein repl :connect
Use Case
GitHubTwitter Rackspace Jenkins Developer 1.PR 2. Webhook 4. Comment 3. Status 5. Save
Talkin’ HTTP
HTTP Library
clj-http
Talkin’ HTTP Java SDK
Hosebird Client (hbc)
Talkin’ HTTP Clojure Bindings for Java SDK
Clojure Bindings for Java SDK Apache jclouds
Talkin’ HTTP Clojure SDK
twitter-apitentacles
twitter-api
:dependencies
1 [org.clojure/clojure "1.4.0"] ;; Clojure 2 [org.clojure/data.json "0.2.1"] ;; JSON 3 [http.async.client "0.5.2"] ;; HTTP 4 [clj-oauth "1.4.0"]] ;; OAuth
twitter-api Macros
1 (defmacro def-twitter-restful-method 2 [verb resource-path & rest] 3 (let [json-path (str resource-path ".json") 4 dashed-name (...) 5 clean-name (...) 6 fn-name (symbol clean-name)] 7 `(def-twitter-method ~fn-name ~verb ~json-path :api ~*rest-api* :callbacks (get- default-callbacks :sync :single)
1 (defmacro def-twitter-method 2 [fn-name default-verb resource-path & rest] 3 (let [rest-map (apply sorted-map rest)] 4 `(defn ~fn-name 5 [& {:as args#}] 6 (let [...] 7 (http-request verb# uri# arg-map#))))
1 (def-twitter-restful-method :get "statuses/home_timeline") 2 (statuses-home-timeline :oauth-creds twitter ‑ creds :params {:count 3}) ; {:headers {:content-length "7558",...} ; :status {:code 200,...} ; :body ; [{:text "Untappd but for Pho",...}...]}
1 (def-twitter-restful-method :post "statuses/update") 2 (statuses-update :oauth-creds twitter ‑ creds :params {:status ”Hi!"}) ; {:headers {:content-length ”1904",...} ; :status {:code 200,...} ; :body ; [{:text "Hi!",...}...]}
twitter-api Documentation
Logging
tentacles
:dependencies
1 [org.clojure/clojure "1.5.1"] ;; Clojure 2 [org.clojure/data.codec "0.1.0"] ;; Base64 3 [clj-http "0.4.0"] ;; HTTP 4 [cheshire "4.0.0"] ;; JSON 5 [com.cemerick/url "0.0.6"] ;; URLs 6 [environ "0.4.0"] ;; Env
tentacles Functions
1 (defn api-call 2 [method end-point positional query] 3 (let [query (query-map query) 4 all-pages? (query "all_pages") 5 req (make-request...) 6 exec-request-one (fn...(request req)) 7 exec-request (fn...)] 8 (exec-request req)))
1 (issues/create-comment "everett-toews” "github-comment-clj" 6 "Hi!" github-creds) ; {:url " ; :id , ; :user {:id ,...} ; :body "Hi!"}
tentacles Documentation
Logging
jclouds
:dependencies
1 [org.clojure/clojure "1.3.0"] ;; Clojure 2 [org.clojure/tools.logging "0.2.3"] ;; Log 3 [org.clojure/core.incubator "0.1.0"];; Inc 4 [org.apache.jclouds.labs/ rackspace-cloudfiles-us 1.8.0"] ;; BlobStore rackspace-cloudfiles-us 1.8.0"] ;; BlobStore
jclouds JavaClasses/Methods
1 (defn create-container 2 [^BlobStore blobstore container-name & 3 {:keys [location public-read?]}] 4 (let [cco (CreateContainerOptions.) 5 cco (if public-read?...)] 6 (.createContainerInLocation blobstore location container-name cco)))
1 (defn put-blob 2 [^BlobStore blobstore container-name blob & 3 {:keys [multipart?]}] 4 (let [options (if multipart?...)] 5 (.putBlob blobstore container-name blob options)))
1 (def my-blob (blob "my-file.log" :payload "my-file-contents")) ; #'blobstore.core/blob 2 (create-container blobstore "my-container") ; true 3 (put-blob blobstore "my-container" my-blob) ; "60e46aeaed dd7ae99858f03"
jclouds Documentation
Logging
Clojure in the Cloud
Thank You Clojure Made Simple Intro to Apache jclouds Everett Toews Developer