ocean-rails 3.7.5 → 3.7.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b4618f9060b2df689ac48bed4bb607fd7e1c939b
4
- data.tar.gz: 58a774e1cdca3c245e5d804170ab90e5ceee1319
3
+ metadata.gz: e0d5bb7e0b732f82788e637801f4bf837caebb9f
4
+ data.tar.gz: c15a1ac82c55631de85ed86e300f418624390828
5
5
  SHA512:
6
- metadata.gz: 0d14cbed87fa91c0d77ce24009b25d10fb07d463609f9afc40486a6d76ff7ad2726769dcbe80ebda538cd94c09ed771c690279b0488a0220774357dcc5d1d6df
7
- data.tar.gz: 074db59dc54f1773f89b0068eceb0b1789aa3fba4a144b7c16ef73b809f27c9a6ce9a7f27cb05fc3231d5609a9b37d0b0d3d0ee5d31e081cfee630504b4cb0b7
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 raised when the GET to obtain the remote resource has failed.
86
- # PutFailed raised when a PUT on the remote resource has failed.
87
- # PostFailed raised when a POST to the remote resource has failed.
88
- # DeleteFailed raised when a DELETE of the remote resource has failed.
89
- # UnparseableJson raised when the response body doesn't parse as JSON.
90
- # JsonIsNoResource raised when the structure of the parsed JSON body is not a resource.
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
- # #refresh returns the resource itself, so you can do
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: 1. If .get or .get! retrieve an Ocean collection, let them return an array of RemoteResources.
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, headers: {}, credentials: credentials, x_api_token: token,
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
@@ -1,3 +1,3 @@
1
1
  module Ocean
2
- VERSION = "3.7.5"
2
+ VERSION = "3.7.6"
3
3
  end
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.5
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-06 00:00:00.000000000 Z
11
+ date: 2014-10-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: typhoeus