-
Notifications
You must be signed in to change notification settings - Fork 4
/
util.clj
71 lines (62 loc) · 2.66 KB
/
util.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/
(ns dev.gethop.payments.util
(:require [clojure.data.json :as json]
[diehard.core :as dh]
[org.httpkit.client :as http])
(:import [java.util UUID]))
(def ^:const gateway-timeout
"504 Gateway timeout The server, while acting as a gateway or proxy,
did not receive a timely response from the upstream server specified
by the URI (e.g. HTTP, FTP, LDAP) or some other auxiliary
server (e.g. DNS) it needed to access in attempting to complete the
request."
504)
(def ^:const bad-gateway
"502 Bad gateway The server, while acting as a gateway or proxy,
received an invalid response from the upstream server it accessed in
attempting to fulfill the request."
502)
(defn- fallback [_ exception]
(let [status (condp instance? exception
;; Socket layer related exceptions
java.net.UnknownHostException :unknown-host
java.net.ConnectException :connection-refused
;; HTTP layer related exceptions
org.httpkit.client.TimeoutException gateway-timeout
org.httpkit.client.AbortException bad-gateway)]
{:status status}))
(defn- retry-policy [max-retries backoff-ms]
(dh/retry-policy-from-config
{:max-retries max-retries
:backoff-ms backoff-ms
:retry-on [org.httpkit.client.TimeoutException
org.httpkit.client.AbortException]}))
(defn default-status-codes [code]
(cond
(keyword? code) code
(and (>= code 200) (< code 300)) :ok
(= code 400) :bad-request
(or (= code 401) (= code 403)) :access-denied
(= code 404) :not-found
:else :error))
(defn do-request [{:keys [api-key timeout max-retries backoff-ms idempotent-post-reqs?]} req-args]
(let [req (cond-> req-args
(and idempotent-post-reqs? (= :post (:method req-args)))
(assoc-in [:headers "Idempotency-Key"] (str (UUID/randomUUID)))
(:api-version req-args)
(assoc-in [:headers "Stripe-Version"] (:api-version req-args))
true
(assoc :oauth-token api-key
:timeout timeout))]
(dh/with-retry {:policy (retry-policy max-retries backoff-ms)
:fallback fallback}
(let [{:keys [status body error]} @(http/request req)]
(when error
(throw error))
(try
{:status status
:body (json/read-str body :key-fn keyword :eof-error? false)}
(catch Exception _
{:status bad-gateway}))))))