ocean-rails 3.7.5 → 3.7.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/ocean/api_remote_resource.rb +62 -11
- data/lib/ocean/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e0d5bb7e0b732f82788e637801f4bf837caebb9f
|
4
|
+
data.tar.gz: c15a1ac82c55631de85ed86e300f418624390828
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d7439c51c1d41f0fcd25b9c421714d80e00eec7d47762aabf4eeec5665c319b80d24c6c37fedcc8d154e02be8032e923e91125af57f7f3178f2ce73b6af42479
|
7
|
+
data.tar.gz: 4489f66cd54b17affb9a80cfb10646cc3046529cd83aa34f637d96f072c85025eafc891b7a6533e16ddd9e0368022b796a5bafef527877592362bac95bed5465
|
@@ -14,6 +14,7 @@ class Api
|
|
14
14
|
# thing.status => 200
|
15
15
|
# thing.status_message => "OK"
|
16
16
|
# thing.response => #<an Api::Response instance>
|
17
|
+
# thing.etag => "e4552f0ae517f0352f0ae56222fa0733ea52f0ae5e0"
|
17
18
|
#
|
18
19
|
# The last raw body can be read:
|
19
20
|
#
|
@@ -82,12 +83,14 @@ class Api
|
|
82
83
|
#
|
83
84
|
# Exceptions:
|
84
85
|
#
|
85
|
-
# GetFailed
|
86
|
-
#
|
87
|
-
#
|
88
|
-
#
|
89
|
-
#
|
90
|
-
#
|
86
|
+
# GetFailed raised when the GET to obtain the resource has failed.
|
87
|
+
# ConditionalGetFailed raised when a Conditional Get to refresh the resource has failed.
|
88
|
+
# PutFailed raised when a PUT on the resource has failed.
|
89
|
+
# PostFailed raised when a POST to the resource has failed.
|
90
|
+
# DeleteFailed raised when a DELETE of the resource has failed.
|
91
|
+
# UnparseableJson raised when the response body doesn't parse as JSON.
|
92
|
+
# JsonIsNoResource raised when the structure of the parsed JSON body is not a resource.
|
93
|
+
# HyperlinkMissing raised when a hyperlink isn't available.
|
91
94
|
#
|
92
95
|
# To parse as a resource, the JSON must be a wrapped Ocean resource of this format:
|
93
96
|
#
|
@@ -109,10 +112,11 @@ class Api
|
|
109
112
|
# thing.refresh
|
110
113
|
# thing.refresh!
|
111
114
|
#
|
112
|
-
#
|
115
|
+
# Both return the resource itself, so you can do
|
113
116
|
#
|
114
117
|
# thing.refresh['updated_at']
|
115
118
|
#
|
119
|
+
#
|
116
120
|
# NB: this class can also be used to fetch any JSON data. E.g.:
|
117
121
|
#
|
118
122
|
# Api::RemoteResource.get("http://example.com/anything").raw
|
@@ -122,14 +126,13 @@ class Api
|
|
122
126
|
# +nil+, you can always chack +#status+, +#status_message+, and/or +#headers+ to determine what
|
123
127
|
# went wrong. After fetching non-resource data, +#present?+ will always be false.
|
124
128
|
#
|
125
|
-
# TODO:
|
126
|
-
# 2. Implement refresh.
|
129
|
+
# TODO: If .get or .get! retrieve an Ocean collection, let them return an array of RemoteResources.
|
127
130
|
#
|
128
131
|
class RemoteResource
|
129
132
|
|
130
133
|
attr_reader :uri, :content_type, :retries, :backoff_time, :backoff_rate, :backoff_max
|
131
134
|
attr_reader :raw, :resource, :resource_type, :status, :headers, :credentials, :x_api_token
|
132
|
-
attr_reader :status_message, :response
|
135
|
+
attr_reader :status_message, :response, :etag
|
133
136
|
|
134
137
|
def initialize(uri, type="application/json",
|
135
138
|
credentials: nil, x_api_token: nil,
|
@@ -186,6 +189,8 @@ class Api
|
|
186
189
|
class UnparseableJson < StandardError; end
|
187
190
|
class JsonIsNoResource < StandardError; end
|
188
191
|
class HyperlinkMissing < StandardError; end
|
192
|
+
class ConditionalGetFailed < StandardError; end
|
193
|
+
|
189
194
|
|
190
195
|
def self.get!(*args)
|
191
196
|
_retrieve new(*args)
|
@@ -290,10 +295,30 @@ class Api
|
|
290
295
|
end
|
291
296
|
|
292
297
|
|
298
|
+
def refresh!
|
299
|
+
if present? && etag.present?
|
300
|
+
_conditional_get
|
301
|
+
else
|
302
|
+
get!
|
303
|
+
end
|
304
|
+
self
|
305
|
+
end
|
306
|
+
|
307
|
+
def refresh
|
308
|
+
if present? && etag.present?
|
309
|
+
_conditional_get rescue nil
|
310
|
+
else
|
311
|
+
get
|
312
|
+
end
|
313
|
+
self
|
314
|
+
end
|
315
|
+
|
316
|
+
|
293
317
|
private
|
294
318
|
|
295
319
|
attr_accessor :present
|
296
320
|
attr_writer :raw, :resource, :resource_type, :status, :headers, :status_message, :response
|
321
|
+
attr_writer :etag
|
297
322
|
|
298
323
|
|
299
324
|
def self._credentials(rr)
|
@@ -310,7 +335,9 @@ class Api
|
|
310
335
|
|
311
336
|
def self._retrieve(rr)
|
312
337
|
credentials, token = _credentials(rr)
|
313
|
-
response = Api.request Api.internalize_uri(rr.uri), :get,
|
338
|
+
response = Api.request Api.internalize_uri(rr.uri), :get,
|
339
|
+
headers: {},
|
340
|
+
credentials: credentials, x_api_token: token,
|
314
341
|
retries: rr.retries, backoff_time: rr.backoff_time, backoff_rate: rr.backoff_rate,
|
315
342
|
backoff_max: rr.backoff_max
|
316
343
|
rr.send :response=, response
|
@@ -327,6 +354,27 @@ class Api
|
|
327
354
|
rr
|
328
355
|
end
|
329
356
|
|
357
|
+
def _conditional_get
|
358
|
+
credentials, token = RemoteResource._credentials(self)
|
359
|
+
response = Api.request Api.internalize_uri(uri), :get,
|
360
|
+
headers: {"If-None-Match" => etag},
|
361
|
+
credentials: credentials, x_api_token: token,
|
362
|
+
retries: retries, backoff_time: backoff_time, backoff_rate: backoff_rate,
|
363
|
+
backoff_max: backoff_max
|
364
|
+
send :response=, response
|
365
|
+
return if response.status == 304
|
366
|
+
send :status=, response.status
|
367
|
+
send :status_message=, response.message
|
368
|
+
send :headers=, response.headers
|
369
|
+
raise ConditionalGetFailed, "#{response.status} #{response.message}" unless response.success?
|
370
|
+
begin
|
371
|
+
raw = response.body
|
372
|
+
rescue JSON::ParserError
|
373
|
+
raise UnparseableJson
|
374
|
+
end
|
375
|
+
_setup raw, response
|
376
|
+
end
|
377
|
+
|
330
378
|
|
331
379
|
def _setup(body, response)
|
332
380
|
self.raw = body
|
@@ -337,6 +385,7 @@ class Api
|
|
337
385
|
self.status = response.status
|
338
386
|
self.status_message = response.message
|
339
387
|
self.headers = response.headers
|
388
|
+
self.etag = headers['ETag']
|
340
389
|
self.present = true
|
341
390
|
end
|
342
391
|
|
@@ -374,6 +423,7 @@ class Api
|
|
374
423
|
return if resource_type && type != resource_type
|
375
424
|
self.resource = resource
|
376
425
|
self.resource_type = type
|
426
|
+
self.etag = headers['ETag']
|
377
427
|
self.present = true
|
378
428
|
end
|
379
429
|
|
@@ -397,6 +447,7 @@ class Api
|
|
397
447
|
type, resource = verify_resource(response.body)
|
398
448
|
created = RemoteResource.new(post_uri)
|
399
449
|
created.send :_setup, raw, response
|
450
|
+
created.send :etag=, nil
|
400
451
|
created
|
401
452
|
end
|
402
453
|
|
data/lib/ocean/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ocean-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.7.
|
4
|
+
version: 3.7.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Bengtson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-10-
|
11
|
+
date: 2014-10-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: typhoeus
|