Clojure in the Cloud Everett Toews Developer JavaOne Sept. 29, 12:30 pm.

Post on 08-Jan-2018

213 views 0 download

description

PMC and Committer on Apache jclouds

transcript

Clojurein the Cloud

Everett ToewsDeveloper Advocate@everett_toews

JavaOneSept. 29, 2014 @ 12:30 pm

Intro

Developer

PMC and Committer on Apache jclouds

Intro

Advocate

Intro

Operations

Co-author of The OpenStack Ops Guide

docs.openstack.org/ops

Clojure

Clojure

List

(2 3)

Clojure

Vector

[2 3]

Clojure

Map

{:key1 "value1" :key2 "value2"}

Clojure

Parens

(fn arg1 arg2)(sf arg1 arg2)

Clojure

Prefix

(+ 2 3); 5

Clojure

Functional

(defn add-7 [x] (+ 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" :k2 "v2"); first; {:k1 v1, :k2 v2, :k3 v3}

Clojure

Lambda

(map (fn [x] (+ x 7)) [2 3]); (9 10)

Clojure

Macro

(defmacro when [test & body] (list 'if test (cons 'do body)))

(when true (+ 2 3)); 5

Clojure

lein

lein new app github-comment-cljlein cleanlein installlein testlein runlein repl

Clojure

REPL

PrintEvalRead

Loop

Cloud

Cloud

SaaS

Cloud

IaaS

Cloud

ResourcesAccessible Via

HTTP API

HTTP APIs

HTTP APIs

Documentation

HTTP APIs

Logging

HTTP APIs

Auth

HTTP APIs

Endpoint

HTTP APIs

Environment

HTTP APIs

Connect!

HTTP APIs

Request

HTTP APIs

Response

HTTP APIs

Headers

HTTP APIs

Body

HTTP APIs

JSON

Clojurein theCloud

Conjecture in the Cloud

ClojectureConjecture

Clojure in the Cloud

Clojure > Java

Clojure in the Cloud

Domain Modelingvs

Maps

Example

ExampleSurprise!

{"key": "value"}Map<String, String>

{"key": {BLAH}}ParseException

Example

ExampleChanging Objects

{"obj": "BLAH"}{"obj": {BLAH}}{"obj": [BLAH]}

Clojure in the Cloud

ExampleHuge Objects

Clojure in the Cloud

Maps

WARNINGDemos Ahead

Clojure in the Cloud

Compile/Run/printlnvs

REPL

Clojure in the Cloud

Demolein repl

Clojure in the Cloud

pom.xml/mvn/Classvs

lein try

Clojure in the Cloud

Demolein try

Clojure in the Cloud

Works For Mevs

I Feel Your Pain

Clojure in the Cloud

Demolein repl :connect

Use Case

GitHub Twitter

Rackspace

Jenkins

Developer

1.PR2. Webhook

4. Comment

3. Status

5. Save

Talkin’ HTTP

Talkin’ HTTP

HTTP Library

HTTP Library

clj-http

Talkin’ HTTP

Java SDK

Java SDK

Hosebird Client (hbc)

Talkin’ HTTP

Clojure Bindings forJava SDK

Clojure Bindings for Java SDK

Apache jclouds

Talkin’ HTTP

Clojure SDK

Clojure SDK

twitter-apitentacles

twitter-api

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

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

twitter-api

Logging

tentacles

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 "https://...",

; :id 378246,

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

; :body "Hi!"}

tentacles

Documentation

tentacles

Logging

jclouds

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

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)

; "60e46aeaed758964902dd7ae99858f03"

jclouds

Documentation

jclouds

Logging

Clojurein theCloud

Thank YouClojure Made Simple

Intro to Apache jcloudsEverett ToewsDeveloper Advocate@everett_toews