springcm-sdk 0.3.6 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -1
- data/bin/console +0 -0
- data/exe/springcm +0 -0
- data/lib/springcm-sdk/client.rb +35 -4
- data/lib/springcm-sdk/middleware/auth_expired.rb +20 -0
- data/lib/springcm-sdk/middleware/rate_limit.rb +21 -0
- data/lib/springcm-sdk/middleware/retry_connection_failed.rb +30 -0
- data/lib/springcm-sdk/middleware.rb +3 -0
- data/lib/springcm-sdk/version.rb +1 -1
- data/lib/springcm-sdk.rb +12 -0
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4ede0e8cbe39a1ba56490a8747d394136877c4ba297f42bc618d665a37822b5b
|
4
|
+
data.tar.gz: 2c6c5bf9194b9f63f937f491cd3522d8175db3d8aabd5cf799b8a09aba7689e6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9aee61e667d073e51bc57f7e8aa00c67e6f47067cc106b11e1caee6306836e390035df29d63714f7f10c8d6351bbca8eaabca34ef95a65a4cc71eecbd60f9874
|
7
|
+
data.tar.gz: 40aeda6cd074142c6546a3451fd29c495dc1f1a73bebce8dab2d2382f730e268cc5690de41d9c89b7b5203d149a5915a7997802e871b7bc559c3e70558271512
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,16 @@ All notable changes to springcm-sdk will be documented in this file.
|
|
4
4
|
|
5
5
|
## [Unreleased]
|
6
6
|
|
7
|
+
## [0.4.0] - 2019-12-27
|
8
|
+
### Added
|
9
|
+
* Faraday middleware for authorization expiration and rate limit handling.
|
10
|
+
* Faraday middleware for retrying on Faraday::ConnectionFailed. Can be
|
11
|
+
disabled via new Client options.
|
12
|
+
|
13
|
+
### Changed
|
14
|
+
* Adjust auth window to re-authenticate no more than 5 minutes before
|
15
|
+
access token expiration.
|
16
|
+
|
7
17
|
## [0.3.6] - 2019-12-23
|
8
18
|
### Changed
|
9
19
|
* Fix resource list behavior for history items. Was returning the document's
|
@@ -79,7 +89,7 @@ All notable changes to springcm-sdk will be documented in this file.
|
|
79
89
|
### Added
|
80
90
|
* Initial release to reserve gem name
|
81
91
|
|
82
|
-
[Unreleased]: https://github.com/paulholden2/springcm-sdk/compare/0.
|
92
|
+
[Unreleased]: https://github.com/paulholden2/springcm-sdk/compare/0.4.0...HEAD
|
83
93
|
[0.1.0]: https://github.com/paulholden2/springcm-sdk/releases/tag/0.1.0
|
84
94
|
[0.1.1]: https://github.com/paulholden2/springcm-sdk/releases/tag/0.1.1
|
85
95
|
[0.1.2]: https://github.com/paulholden2/springcm-sdk/releases/tag/0.1.2
|
@@ -91,3 +101,4 @@ All notable changes to springcm-sdk will be documented in this file.
|
|
91
101
|
[0.3.4]: https://github.com/paulholden2/springcm-sdk/releases/tag/0.3.4
|
92
102
|
[0.3.5]: https://github.com/paulholden2/springcm-sdk/releases/tag/0.3.5
|
93
103
|
[0.3.6]: https://github.com/paulholden2/springcm-sdk/releases/tag/0.3.6
|
104
|
+
[0.4.0]: https://github.com/paulholden2/springcm-sdk/releases/tag/0.4.0
|
data/bin/console
CHANGED
File without changes
|
data/exe/springcm
CHANGED
File without changes
|
data/lib/springcm-sdk/client.rb
CHANGED
@@ -3,19 +3,31 @@ require "json"
|
|
3
3
|
require "springcm-sdk/account"
|
4
4
|
require "springcm-sdk/folder"
|
5
5
|
require "springcm-sdk/document"
|
6
|
+
require "springcm-sdk/middleware"
|
6
7
|
|
7
8
|
module Springcm
|
8
9
|
class Client
|
10
|
+
# Default API client options
|
11
|
+
DEFAULT_OPTIONS = {
|
12
|
+
# If true, the client will use a simple retry mechanism when connection
|
13
|
+
# to the API server fails due to e.g. temporary Internet service outage.
|
14
|
+
# The connection is re-attempted up to five times, delaying 2 ** n
|
15
|
+
# seconds between attempts, where n is the number of previous attempts.
|
16
|
+
retry_connection_failed: true
|
17
|
+
}.freeze
|
18
|
+
|
9
19
|
attr_reader :access_token
|
10
20
|
|
11
21
|
# @param data_center [String] Data center name, e.g. uatna11
|
12
22
|
# @param client_id [String] Your API client ID
|
13
23
|
# @param client_secret [String] Your API client secret
|
14
|
-
|
24
|
+
# @parma options [Hash] API client options
|
25
|
+
def initialize(data_center, client_id, client_secret, options=DEFAULT_OPTIONS)
|
15
26
|
if !["na11", "uatna11", "eu11", "eu21", "na21", "us11"].include?(data_center)
|
16
27
|
raise Springcm::ConnectionInfoError.new("Invalid data center '#{data_center.to_s}'")
|
17
28
|
end
|
18
29
|
|
30
|
+
@options = options
|
19
31
|
@data_center = data_center
|
20
32
|
@client_id = client_id
|
21
33
|
@client_secret = client_secret
|
@@ -28,7 +40,12 @@ module Springcm
|
|
28
40
|
# @param safe If truthy, connection failure does not raise an exception
|
29
41
|
# @return [Boolean] Whether connection was successful
|
30
42
|
def connect(safe=true)
|
31
|
-
conn = Faraday.new(url: auth_url)
|
43
|
+
conn = Faraday.new(url: auth_url) do |conn|
|
44
|
+
conn.request :retry, retry_statuses: [429], exceptions: [Springcm::RateLimitExceededError]
|
45
|
+
conn.use Springcm::Middleware::RateLimit
|
46
|
+
conn.use Springcm::Middleware::RetryConnectionFailed if @options[:retry_connection_failed]
|
47
|
+
conn.adapter :net_http
|
48
|
+
end
|
32
49
|
res = conn.post do |req|
|
33
50
|
req.headers['Content-Type'] = 'application/json'
|
34
51
|
req.body = {
|
@@ -39,7 +56,7 @@ module Springcm
|
|
39
56
|
if res.success?
|
40
57
|
data = JSON.parse(res.body)
|
41
58
|
@access_token = data.fetch("access_token")
|
42
|
-
@expiry = Time.now + data.fetch("expires_in")
|
59
|
+
@expiry = Time.now + data.fetch("expires_in") - 300
|
43
60
|
else
|
44
61
|
@access_token = nil
|
45
62
|
@expiry = nil
|
@@ -169,15 +186,29 @@ module Springcm
|
|
169
186
|
end
|
170
187
|
|
171
188
|
def authorized_connection(*options)
|
189
|
+
if !authenticated?
|
190
|
+
connect!
|
191
|
+
end
|
192
|
+
|
172
193
|
Faraday.new(*options) do |conn|
|
173
194
|
options = [{
|
174
195
|
max: 10,
|
175
196
|
interval: 1,
|
176
197
|
interval_randomness: 0.5,
|
177
198
|
backoff_factor: 2,
|
178
|
-
retry_statuses: [429]
|
199
|
+
retry_statuses: [401, 429],
|
200
|
+
exceptions: [Springcm::AuthExpiredError, Springcm::RateLimitExceededError],
|
201
|
+
retry_block: -> (env, options, retries, exception) {
|
202
|
+
if exception.class == Springcm::AuthExpiredError
|
203
|
+
connect!
|
204
|
+
env.request_headers['Authorization'] = "bearer #{@access_token}"
|
205
|
+
end
|
206
|
+
}
|
179
207
|
}]
|
180
208
|
conn.request :retry, *options
|
209
|
+
conn.use Springcm::Middleware::RateLimit
|
210
|
+
conn.use Springcm::Middleware::AuthExpire
|
211
|
+
conn.use Springcm::Middleware::RetryConnectionFailed if @options[:retry_connection_failed]
|
181
212
|
conn.adapter :net_http
|
182
213
|
conn.authorization('bearer', @access_token)
|
183
214
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Springcm
|
2
|
+
module Middleware
|
3
|
+
class AuthExpire
|
4
|
+
attr_reader :options
|
5
|
+
|
6
|
+
def initialize(app, options={})
|
7
|
+
@app = app
|
8
|
+
@options = options
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
@app.call(env).on_complete do |response_env|
|
13
|
+
if response_env[:status] == 401
|
14
|
+
raise Springcm::AuthExpiredError.new
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Springcm
|
2
|
+
module Middleware
|
3
|
+
class RateLimit
|
4
|
+
attr_reader :options
|
5
|
+
|
6
|
+
def initialize(app, options={})
|
7
|
+
@app = app
|
8
|
+
@options = options
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
@app.call(env).on_complete do |response_env|
|
13
|
+
body = JSON.parse(response_env[:body])
|
14
|
+
if body.fetch("Error", {}).fetch("ErrorCode", nil) == 103
|
15
|
+
raise Springcm::RateLimitExceededError.new
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Springcm
|
2
|
+
module Middleware
|
3
|
+
class RetryConnectionFailed
|
4
|
+
attr_reader :options
|
5
|
+
|
6
|
+
def initialize(app, options={ retries: 5 })
|
7
|
+
@app = app
|
8
|
+
@options = options
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
retries = @options[:retries]
|
13
|
+
delay = 1
|
14
|
+
begin
|
15
|
+
@app.call(env).on_complete do |response_env|
|
16
|
+
end
|
17
|
+
rescue Faraday::ConnectionFailed => err
|
18
|
+
if retries > 0
|
19
|
+
retries -= 1
|
20
|
+
sleep delay
|
21
|
+
delay *= 2
|
22
|
+
retry
|
23
|
+
else
|
24
|
+
raise err
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/springcm-sdk/version.rb
CHANGED
data/lib/springcm-sdk.rb
CHANGED
@@ -20,4 +20,16 @@ module Springcm
|
|
20
20
|
super("Invalid Client Id or Client Secret")
|
21
21
|
end
|
22
22
|
end
|
23
|
+
|
24
|
+
class AuthExpiredError < Error
|
25
|
+
def initialize
|
26
|
+
super("Authorization expired")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class RateLimitExceededError < Error
|
31
|
+
def initialize
|
32
|
+
super("Rate limit exceeded")
|
33
|
+
end
|
34
|
+
end
|
23
35
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: springcm-sdk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul Holden
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-12-
|
11
|
+
date: 2019-12-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -167,6 +167,10 @@ files:
|
|
167
167
|
- lib/springcm-sdk/folder.rb
|
168
168
|
- lib/springcm-sdk/helpers.rb
|
169
169
|
- lib/springcm-sdk/history_item.rb
|
170
|
+
- lib/springcm-sdk/middleware.rb
|
171
|
+
- lib/springcm-sdk/middleware/auth_expired.rb
|
172
|
+
- lib/springcm-sdk/middleware/rate_limit.rb
|
173
|
+
- lib/springcm-sdk/middleware/retry_connection_failed.rb
|
170
174
|
- lib/springcm-sdk/mixins/access_level.rb
|
171
175
|
- lib/springcm-sdk/mixins/attributes.rb
|
172
176
|
- lib/springcm-sdk/mixins/documents.rb
|
@@ -183,7 +187,7 @@ metadata:
|
|
183
187
|
allowed_push_host: https://rubygems.org
|
184
188
|
homepage_uri: https://github.com/paulholden2/springcm-sdk
|
185
189
|
source_code_uri: https://github.com/paulholden2/springcm-sdk
|
186
|
-
documentation_uri: https://rubydoc.info/github/paulholden2/springcm-sdk/0.
|
190
|
+
documentation_uri: https://rubydoc.info/github/paulholden2/springcm-sdk/0.4.0
|
187
191
|
changelog_uri: https://github.com/paulholden2/springcm-sdk/blob/master/CHANGELOG.md
|
188
192
|
post_install_message:
|
189
193
|
rdoc_options: []
|