Skip to content

Commit

Permalink
Add back api compatability
Browse files Browse the repository at this point in the history
Also adds logging for deprecation warning.
  • Loading branch information
hugoduncan committed Nov 22, 2013
1 parent 309b9e4 commit bd2a95e
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 60 deletions.
15 changes: 13 additions & 2 deletions project.clj
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
(defproject clj-librato "0.0.4-SHAPSHOT"
:description "Clojure interface to the Librato service"
:dependencies [[org.clojure/clojure "1.5.1"]
[clj-http "0.7.5"]
[cheshire "5.2.0"]])
[org.clojure/tools.logging "0.2.6"]
[clj-http "0.7.5"
:exclusions [commons-logging]]
[cheshire "5.2.0"]]
:profiles
{:dev {:dependencies [[log4j/log4j "1.2.16"
:exclusions [javax.mail/mail
javax.jms/jms
com.sun.jdmk/jmxtools
com.sun.jmx/jmxri]]
[org.slf4j/slf4j-log4j12 "1.7.5"]
[org.slf4j/jcl-over-slf4j "1.7.5"]]}
:test {:resource-paths ["resources" "test-resources"]}})
136 changes: 83 additions & 53 deletions src/clj_librato/metrics.clj
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
[clj-http.client :as client]
[clj-http.conn-mgr :as conn-mgr]
[clojure.string :as string]
[clojure.tools.logging :as logging]
clj-http.util))

(def uri-base "https://metrics-api.librato.com/v1/")
Expand Down Expand Up @@ -44,42 +45,47 @@
(defn request
"Constructs the HTTP client request map.
options will be merged verbatim into the request map."
([user api-key params options]
{:pre [(or (nil? options)(map? options))]}
(merge
options
{:basic-auth [user api-key]
:content-type :json
:accept :json
:throw-entire-message? true
:query-params (unparse-kw params)}))

([user api-key params body options]
(assoc (request user api-key params options)
:body (json/generate-string (unparse-kw body)))))

(defn collate [user api-key gauges counters options]
([user api-key params]
{:basic-auth [user api-key]
:content-type :json
:accept :json
:throw-entire-message? true
:query-params (unparse-kw params)})
([user api-key params body]
(assoc (request user api-key params)
:body (json/generate-string (unparse-kw body)))))

(defn collate
"Posts a set of gauges and counters. options is a map of clj-http options."
(assert (every? :name gauges))
(assert (every? :name counters))
(assert (every? :value gauges))
(assert (every? :value counters))
(client/post (uri "metrics")
(request user api-key {} {:gauges gauges :counters counters}
options)))
([user api-key gauges counters]
(collate user api-key gauges counters nil))
([user api-key gauges counters options]
(assert (every? :name gauges))
(assert (every? :name counters))
(assert (every? :value gauges))
(assert (every? :value counters))
(client/post (uri "metrics")
(merge
options
(request user api-key {}
{:gauges gauges :counters counters})))))

(defn metric
"Gets a metric by name.
See http://dev.librato.com/v1/get/metrics"
([user api-key name]
(metric user api-key name {} nil))
([user api-key name params]
(metric user api-key name params nil))

([user api-key name params options]
(assert name)
(try+
(let [body (-> (client/get (uri "metrics" name)
(request user api-key params options))
(merge
options
(request user api-key params)))
:body json/parse-string parse-kw)]
(assoc body :measurements
(into {} (map (fn [[source measurements]]
Expand All @@ -93,44 +99,68 @@
"Creates a new annotation, and returns the created annotation as a map.
http://dev.librato.com/v1/post/annotations/:name"
[user api-key name annotation options]
{:pre [(or (nil? options)(map? options))]}
(assert name)
(-> (client/post (uri "annotations" name)
(request user api-key {} annotation options))
:body
json/parse-string
parse-kw))
([user api-key name annotation]
(create-annotation user api-key name annotation))
([user api-key name annotation options]
{:pre [(or (nil? options)(map? options))]}
(assert name)
(-> (client/post (uri "annotations" name)
(merge
options
(request user api-key {} annotation)))
:body
json/parse-string
parse-kw)))

(defn update-annotation
"Updates an annotation.
http://dev.librato.com/v1/put/annotations/:name/events/:id"
[user api-key name id annotation options]
(assert name)
(assert id)
(client/put (uri "annotations" name id)
(request user api-key {} annotation options)))

(defn annotate
"Creates or updates an annotation. If id is given, updates. If id is
missing, creates a new annotation."
([user api-key name annotation options]
(create-annotation user api-key name annotation options))
([user api-key name id annotation]
(update-annotation user api-key name id annotation nil))
([user api-key name id annotation options]
(update-annotation user api-key name id annotation options)))
(assert name)
(assert id)
(client/put (uri "annotations" name id)
(merge
options
(request user api-key {} annotation)))))

(let [warn-on-deprecate (atom true)]
;; Deprecated due to argument ambiguity.
;; A future version could rename create-annotation as annotate.
(defn annotate
"Creates or updates an annotation. If id is given, updates. If id is
missing, creates a new annotation."
([user api-key name annotation]
(create-annotation user api-key name annotation nil))
([user api-key name annotation options]
(if (map? annotation)
(create-annotation user api-key name annotation options)
(do
;; user api-key name id annotation
(update-annotation user api-key name annotation options)
(when @warn-on-deprecate
(reset! warn-on-deprecate false)
(logging/warn
(str "`annotate` called for annotation update is deprecated. "
"Please use update-annotation."))))))))

(defn annotation
"Find a particular annotation event.
See http://dev.librato.com/v1/get/annotations/:name/events/:id"
[user api-key name id options]
(assert name)
(assert id)
(try+
(-> (client/get (uri "annotations" name id)
(request user api-key {} options))
:body
json/parse-string
parse-kw)
(catch [:status 404] _ nil)))
([user api-key name id]
(annotation user api-key name id nil))
([user api-key name id options]
(assert name)
(assert id)
(try+
(-> (client/get (uri "annotations" name id)
(merge
options
(request user api-key {})))
:body
json/parse-string
parse-kw)
(catch [:status 404] _ nil))))
83 changes: 78 additions & 5 deletions test/clj_librato/metrics_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,46 @@
(is (= (unparse-kw {:hello-there [{:tiny-kitten 3}]})
{"hello_there" [{"tiny_kitten" 3}]})))

(deftest collate-test
(testing "reject nil names"
(is (thrown? java.lang.AssertionError
(collate user apikey [{:name nil}] [])))
(is (thrown? java.lang.AssertionError
(collate user apikey [] [{:name nil}]))))

(testing "reject nil values"
(is (thrown? java.lang.AssertionError
(collate user apikey [{:name "foo"
:value nil}] [])))
(is (thrown? java.lang.AssertionError
(collate user apikey [] [{:name "foo"
:value nil}]))))

(testing "gauge"
(let [gauge {:name "test.gauge"
:source "clj-librato"
:value (/ (rand-int 1000) (rand-int 1000))
:measure-time (now)}]
; Submit gauge
(collate user apikey [gauge] [])

; Confirm receipt
(let [metric (metric user apikey (:name gauge)
{:end-time (:measure-time gauge)
:count 1
:resolution 1})
m (-> metric
:measurements
(get (:source gauge))
(first))]
(is (= (:name metric) (:name gauge)))
(is (= (:type metric) "gauge"))
(is m)
(is (= (:measure-time m) (:measure-time gauge)))
(is (= (:value m) (double (:value gauge))))
(is (= (:count m) 1)))
)))

(defn test-value
[]
{:name "test.gauge"
Expand Down Expand Up @@ -53,7 +93,7 @@
(is (= (:value m) (double (:value gauge))))
(is (= (:count m) 1)))))))))

(deftest collate-test
(deftest collate-with-http-options-test
(testing "reject nil names"
(is (thrown? java.lang.AssertionError
(collate user apikey [{:name nil}] [] {})))
Expand All @@ -75,6 +115,34 @@
(is cm "connection manager created")
(test-collate-and-guage {:connection-manager cm}))))

(deftest annotate-test
(let [name "test.annotations"
event {:title (str "A test event: " (rand 10000000))
:source "clj-librato"
:description "Testing clj-librato annotations"
:start-time (now)
:end-time (+ 10 (now))}
res (annotate user apikey name event)
e (annotation user apikey name (:id res))]

; Verify annotation was created.
(is res)
(is e)
(is (= res e))
(is (= (:title e) (:title event)))
(is (= (:description e) (:description event)))
(is (= (:source e) (:source event)))
(is (= (:start-time e) (:start-time event)))
(is (= (:end-time e) (:end-time event)))

; Update annotation
(annotate user apikey name (:id res)
{:end-time (inc (:end-time event))})

; Verify update was applied.
(is (= (inc (:end-time event))
(:end-time (annotation user apikey name (:id res)))))))

(defn test-annotation
[]
{:title (str "A test event: " (rand 10000000))
Expand Down Expand Up @@ -105,14 +173,14 @@
(is (annotation= a annot-map) "has matching attributes")))

(testing "and can be updated"
(annotate user apikey name (:id res)
{:end-time (inc (:end-time annot-map))}
options)
(update-annotation user apikey name (:id res)
{:end-time (inc (:end-time annot-map))}
options)
(is (= (inc (:end-time annot-map))
(:end-time (annotation user apikey name (:id res) options)))
"updated attribute matches")))))))

(deftest annotate-test
(deftest annotate-with-http-options-test
(testing "with no http options"
(test-annotate nil))
(testing "with persistent http options"
Expand All @@ -121,6 +189,11 @@
(test-annotate {:connection-manager cm}))))

(deftest annotation-test
; 404s return nil
(is (nil? (annotation user apikey "asdilhugflsdbfg" 1234)))
(is (nil? (annotation user apikey name 2345235624534))))

(deftest annotation-with-http-options-test
; 404s return nil
(is (nil? (annotation user apikey "asdilhugflsdbfg" 1234 {})))
(is (nil? (annotation user apikey name 2345235624534 {}))))

0 comments on commit bd2a95e

Please sign in to comment.