Clojure in the Cloud

118
Clojure in the Cloud Everett Toews Developer Advocate @everett_toews JavaOne Sept. 29, 2014 @ 12:30 pm

description

Clojure in the Cloud. JavaOne. Sept. 29, 2014 @ 12: 3 0 p m. Everett Toews Developer Advocate @ everett_toews. Intro. Developer. PMC and Committer on Apache jclouds. Intro. Advocate. Intro. Operations. Co-author of The OpenStack Ops Guide. docs.openstack.org /ops. Clojure. - PowerPoint PPT Presentation

Transcript of Clojure in the Cloud

Page 1: Clojure in the Cloud

Clojurein the Cloud

Everett Toews

Developer Advocate

@everett_toews

JavaOneSept. 29, 2014 @ 12:30 pm

Page 2: Clojure in the Cloud

Intro

Developer

Page 3: Clojure in the Cloud

PMC and Committer on Apache jclouds

Page 4: Clojure in the Cloud

Intro

Advocate

Page 5: Clojure in the Cloud
Page 6: Clojure in the Cloud

Intro

Operations

Page 7: Clojure in the Cloud

Co-author of The OpenStack Ops Guide

docs.openstack.org/ops

Page 8: Clojure in the Cloud

Clojure

Page 9: Clojure in the Cloud
Page 10: Clojure in the Cloud

Clojure

List

Page 11: Clojure in the Cloud

(2 3)

Page 12: Clojure in the Cloud

Clojure

Vector

Page 13: Clojure in the Cloud

[2 3]

Page 14: Clojure in the Cloud

Clojure

Map

Page 15: Clojure in the Cloud

{:key1 "value1"

:key2 "value2"}

Page 16: Clojure in the Cloud

Clojure

Parens

Page 17: Clojure in the Cloud

(fn arg1 arg2)

(sf arg1 arg2)

Page 18: Clojure in the Cloud

Clojure

Prefix

Page 19: Clojure in the Cloud

(+ 2 3)

; 5

Page 20: Clojure in the Cloud

Clojure

Functional

Page 21: Clojure in the Cloud

(defn add-7

[x]

(+ x 7))

Page 22: Clojure in the Cloud

(add-7 3)

; 10

Page 23: Clojure in the Cloud

(map add-7 [2 3])

; (9 10)

Page 24: Clojure in the Cloud

Clojure

Types

Page 25: Clojure in the Cloud

(add-7 "3"); ClassCastException java.lang.String cannot be cast to java.lang.Number

Page 26: Clojure in the Cloud

Clojure

Destructuring

Page 27: Clojure in the Cloud

1 (defn print-args

2 [f & rest]

3 (println f)

4 (println

5 (apply sorted-map rest)))

Page 28: Clojure in the Cloud

(print-args "first"

:k3 "v3" :k1 "v1"

:k2 "v2")

; first

; {:k1 v1, :k2 v2, :k3 v3}

Page 29: Clojure in the Cloud

Clojure

Lambda

Page 30: Clojure in the Cloud

(map

(fn [x] (+ x 7))

[2 3])

; (9 10)

Page 31: Clojure in the Cloud

Clojure

Macro

Page 32: Clojure in the Cloud

(defmacro when

[test & body]

(list 'if test

(cons 'do body)))

Page 33: Clojure in the Cloud

(when true (+ 2 3))

; 5

Page 34: Clojure in the Cloud

Clojure

lein

Page 35: Clojure in the Cloud

lein new app github-comment-clj

lein clean

lein install

lein test

lein run

lein repl

Page 36: Clojure in the Cloud

Clojure

REPL

Page 37: Clojure in the Cloud

PrintEvalRead

Loop

Page 38: Clojure in the Cloud

Cloud

Page 39: Clojure in the Cloud
Page 40: Clojure in the Cloud

Cloud

SaaS

Page 41: Clojure in the Cloud

Cloud

IaaS

Page 42: Clojure in the Cloud

Cloud

Resources

Accessible Via

HTTP API

Page 43: Clojure in the Cloud

HTTP APIs

Page 44: Clojure in the Cloud
Page 45: Clojure in the Cloud

HTTP APIs

Documentation

Page 46: Clojure in the Cloud

HTTP APIs

Logging

Page 47: Clojure in the Cloud

HTTP APIs

Auth

Page 48: Clojure in the Cloud

HTTP APIs

Endpoint

Page 49: Clojure in the Cloud

HTTP APIs

Environment

Page 50: Clojure in the Cloud

HTTP APIs

Connect!

Page 51: Clojure in the Cloud

HTTP APIs

Request

Page 52: Clojure in the Cloud

HTTP APIs

Response

Page 53: Clojure in the Cloud

HTTP APIs

Headers

Page 54: Clojure in the Cloud

HTTP APIs

Body

Page 55: Clojure in the Cloud

HTTP APIs

JSON

Page 56: Clojure in the Cloud

Clojurein theCloud

Page 57: Clojure in the Cloud
Page 58: Clojure in the Cloud

Conjecture in the Cloud

Clojecture

Conjecture

Page 59: Clojure in the Cloud

Clojure in the Cloud

Clojure > Java

Page 60: Clojure in the Cloud

Clojure in the Cloud

Domain Modeling

vs

Maps

Page 61: Clojure in the Cloud

Example

Example

Surprise!

Page 62: Clojure in the Cloud

{"key": "value"}

Map<String, String>

Page 63: Clojure in the Cloud

{"key": {BLAH}}

ParseException

Page 64: Clojure in the Cloud

Example

Example

Changing Objects

Page 65: Clojure in the Cloud

{"obj": "BLAH"}

{"obj": {BLAH}}

{"obj": [BLAH]}

Page 66: Clojure in the Cloud

Clojure in the Cloud

Example

Huge Objects

Page 67: Clojure in the Cloud
Page 68: Clojure in the Cloud

Clojure in the Cloud

Maps

Page 69: Clojure in the Cloud

WARNINGDemos Ahead

Page 70: Clojure in the Cloud
Page 71: Clojure in the Cloud

Clojure in the Cloud

Compile/Run/println

vs

REPL

Page 72: Clojure in the Cloud

Clojure in the Cloud

Demo

lein repl

Page 73: Clojure in the Cloud

Clojure in the Cloud

pom.xml/mvn/Class

vs

lein try

Page 74: Clojure in the Cloud

Clojure in the Cloud

Demo

lein try

Page 75: Clojure in the Cloud

Clojure in the Cloud

Works For Me

vs

I Feel Your Pain

Page 76: Clojure in the Cloud

Clojure in the Cloud

Demo

lein repl :connect

Page 77: Clojure in the Cloud

Use Case

Page 78: Clojure in the Cloud

GitHub Twitter

Rackspace

Jenkins

Developer

1.PR2. Webhook

4. Comment

3. Status

5. Save

Page 79: Clojure in the Cloud

Talkin’ HTTP

Page 80: Clojure in the Cloud
Page 81: Clojure in the Cloud

Talkin’ HTTP

HTTP Library

Page 82: Clojure in the Cloud

HTTP Library

clj-http

Page 83: Clojure in the Cloud

Talkin’ HTTP

Java SDK

Page 84: Clojure in the Cloud

Java SDK

Hosebird Client

(hbc)

Page 85: Clojure in the Cloud

Talkin’ HTTP

Clojure Bindings for

Java SDK

Page 86: Clojure in the Cloud

Clojure Bindings for Java SDK

Apache jclouds

Page 87: Clojure in the Cloud

Talkin’ HTTP

Clojure SDK

Page 88: Clojure in the Cloud

Clojure SDK

twitter-api

tentacles

Page 89: Clojure in the Cloud

twitter-api

Page 90: Clojure in the Cloud

twitter-api

:dependencies

Page 91: Clojure in the Cloud

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

Page 92: Clojure in the Cloud

twitter-api

Macros

Page 93: Clojure in the Cloud

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) ~@rest)))

Page 94: Clojure in the Cloud

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#))))

Page 95: Clojure in the Cloud

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", ...} ...]}

Page 96: Clojure in the Cloud

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!", ...} ...]}

Page 97: Clojure in the Cloud

twitter-api

Documentation

Page 98: Clojure in the Cloud

twitter-api

Logging

Page 99: Clojure in the Cloud

tentacles

Page 100: Clojure in the Cloud

tentacles

:dependencies

Page 101: Clojure in the Cloud

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

Page 102: Clojure in the Cloud

tentacles

Functions

Page 103: Clojure in the Cloud

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)))

Page 104: Clojure in the Cloud

1 (issues/create-comment "everett-toews” "github-comment-clj" 6 "Hi!" github-creds)

; {:url "https://...",

; :id 378246,

; :user {:id 9775324, ...}

; :body "Hi!"}

Page 105: Clojure in the Cloud

tentacles

Documentation

Page 106: Clojure in the Cloud

tentacles

Logging

Page 107: Clojure in the Cloud

jclouds

Page 108: Clojure in the Cloud

jclouds

:dependencies

Page 109: Clojure in the Cloud

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

Page 110: Clojure in the Cloud

jclouds

Java

Classes/Methods

Page 111: Clojure in the Cloud

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)))

Page 112: Clojure in the Cloud

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)))

Page 113: Clojure in the Cloud

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)

; "60e46aeaed758964902dd7ae99858f03"

Page 114: Clojure in the Cloud

jclouds

Documentation

Page 115: Clojure in the Cloud

jclouds

Logging

Page 116: Clojure in the Cloud

Clojurein theCloud

Page 117: Clojure in the Cloud
Page 118: Clojure in the Cloud

Thank You

Clojure Made Simple

Intro to Apache jclouds

Everett Toews

Developer Advocate

@everett_toews