dor-services-client 8.7.0 → 9.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2816ff0e5fd31c5ad7a0953bcebfdb54d0bd03575ad2b1f894496800b79477d9
4
- data.tar.gz: 283c234b2ce026cf3c80c0db436c5223495c63313e2a8b3e6d8c1a3834b9809b
3
+ metadata.gz: 6420f39cd3b4f4d1e125929725e7a749fdef2b4a3b41008fd6d6d440708aaba8
4
+ data.tar.gz: 3690b2a21d44ad9cc830a04f58117731bc4ab53f5d495edc5c4a0846150cd737
5
5
  SHA512:
6
- metadata.gz: ddefa24ab3ce48accb2cdef01a1c09771dd88191bcc7e585ae1baead41d47986d981e8d1fa66ea361aec732716a0ffe7965925a769be97249648adb276f09056
7
- data.tar.gz: 399b9d02a94a887c4a2f5525df6ae8c6915e7c0dbe4fbba0fbb671389b4edb204f5060f85b274ae103cdfde3fd976d9c2fd288db6f9a315645964bdde3b42d48
6
+ metadata.gz: 1130a9e3510b4db1a1d383647de3e9c3c87f8b426c40586326ff88c300bb7508749c29eab8fcc35c5cb91db1cc0458fbc3b1949f12004bc3a4fa2cad9109db68
7
+ data.tar.gz: 63459db88fccc089c36c02b8a6496988edfa628844b04eb8991563c3fce014c88def669b5f452f48144a1e4c0bd87b2172bb1c674567295b31b280924f86124f
data/.rubocop.yml CHANGED
@@ -12,6 +12,9 @@ Metrics/BlockLength:
12
12
  - 'dor-services-client.gemspec'
13
13
  - 'spec/**/*'
14
14
 
15
+ RSpec/MultipleMemoizedHelpers:
16
+ Max: 10
17
+
15
18
  Gemspec/DateAssignment: # (new in 1.10)
16
19
  Enabled: true
17
20
  Layout/SpaceBeforeBrackets: # (new in 1.7)
data/.rubocop_todo.yml CHANGED
@@ -46,12 +46,6 @@ RSpec/MultipleExpectations:
46
46
  - 'spec/dor/services/client/object_spec.rb'
47
47
  - 'spec/dor/services/client/response_error_formatter_spec.rb'
48
48
 
49
- # Offense count: 7
50
- # Configuration parameters: AllowSubject, Max.
51
- RSpec/MultipleMemoizedHelpers:
52
- Exclude:
53
- - 'spec/dor/services/client/objects_spec.rb'
54
-
55
49
  # Offense count: 1
56
50
  # Cop supports --auto-correct.
57
51
  RSpec/MultipleSubjects:
@@ -25,7 +25,7 @@ Gem::Specification.new do |spec|
25
25
  spec.required_ruby_version = '>= 2.7', '< 4' # dor-services-app needs 2.7 due to fedora3
26
26
 
27
27
  spec.add_dependency 'activesupport', '>= 4.2', '< 8'
28
- spec.add_dependency 'cocina-models', '~> 0.73.0' # leave pinned to patch level until cocina-models hits 1.0
28
+ spec.add_dependency 'cocina-models', '~> 0.75.0' # leave pinned to patch level until cocina-models hits 1.0
29
29
  spec.add_dependency 'deprecation', '>= 0'
30
30
  spec.add_dependency 'faraday', '~> 2.0'
31
31
  spec.add_dependency 'faraday-retry'
@@ -26,23 +26,31 @@ module Dor
26
26
  end
27
27
 
28
28
  # Updates the object
29
- # @param [Cocina::Models::DRO,Cocina::Models::Collection,Cocina::Models::AdminPolicy] params model object
29
+ # @param [Cocina::Models::DROWithMetadata|CollectionWithMetadata|AdminPolicyWithMetadata|DRO|Collection|AdminPolicy] params model object
30
+ # @param [boolean] skip_lock do not provide ETag
30
31
  # @raise [NotFoundResponse] when the response is a 404 (object not found)
31
32
  # @raise [UnexpectedResponse] when the response is not successful.
32
- # @return [Cocina::Models::DRO,Cocina::Models::Collection,Cocina::Models::AdminPolicy] the returned model
33
- def update(params:)
33
+ # @raise [BadRequestError] when ETag not provided.
34
+ # @return [Cocina::Models::DROWithMetadata,Cocina::Models::CollectionWithMetadata,Cocina::Models::AdminPolicyWithMetadata] the returned model
35
+ # rubocop:disable Metrics/AbcSize
36
+ def update(params:, skip_lock: false)
37
+ # Raised if Cocina::Models::*WithMetadata not provided.
38
+ raise BadRequestError, 'ETag not provided.' unless skip_lock || params.respond_to?(:lock)
39
+
34
40
  resp = connection.patch do |req|
35
41
  req.url object_path
36
42
  req.headers['Content-Type'] = 'application/json'
37
43
  # asking the service to return JSON (else it'll be plain text)
38
44
  req.headers['Accept'] = 'application/json'
39
- req.body = params.to_json
45
+ req.headers['If-Match'] = params[:lock] unless skip_lock
46
+ req.body = build_json_from_cocina(params)
40
47
  end
41
48
 
42
49
  raise_exception_based_on_response!(resp) unless resp.success?
43
50
 
44
- Cocina::Models.build(JSON.parse(resp.body))
51
+ build_cocina_from_response(resp)
45
52
  end
53
+ # rubocop:enable Metrics/AbcSize
46
54
 
47
55
  # Pull in metadata from Symphony and updates descriptive metadata
48
56
  # @raise [NotFoundResponse] when the response is a 404 (object not found)
@@ -45,9 +45,14 @@ module Dor
45
45
  # Retrieves the Cocina model
46
46
  # @raise [NotFoundResponse] when the response is a 404 (object not found)
47
47
  # @raise [UnexpectedResponse] when the response is not successful.
48
- # @return [Cocina::Models::DRO,Cocina::Models::Collection,Cocina::Models::AdminPolicy] the returned model
48
+ # @return [Cocina::Models::DROWithMetadata,Cocina::Models::CollectionWithMetadata,Cocina::Models::AdminPolicyWithMetadata] the returned model
49
49
  def find
50
- find_with_metadata.first
50
+ resp = connection.get do |req|
51
+ req.url object_path
52
+ end
53
+ raise_exception_based_on_response!(resp) unless resp.success?
54
+
55
+ build_cocina_from_response(resp)
51
56
  end
52
57
 
53
58
  # Retrieves the Cocina model and response metadata
@@ -64,9 +69,12 @@ module Dor
64
69
  model = Cocina::Models.build(JSON.parse(resp.body))
65
70
 
66
71
  # Don't use #slice here as Faraday will downcase the keys.
67
- metadata = ObjectMetadata.new(updated_at: resp.headers['Last-Modified'], created_at: resp.headers['X-Created-At'])
72
+ metadata = ObjectMetadata.new(updated_at: resp.headers['Last-Modified'],
73
+ created_at: resp.headers['X-Created-At'],
74
+ etag: resp.headers['ETag'])
68
75
  [model, metadata]
69
76
  end
77
+ deprecation_deprecate find_with_metadata: 'Use find instead with provides models with metadata.'
70
78
 
71
79
  # Get a list of the collections. (Similar to Valkyrie's find_inverse_references_by)
72
80
  # @raise [UnexpectedResponse] if the request is unsuccessful.
@@ -9,11 +9,12 @@ module Dor
9
9
  class ObjectMetadata
10
10
  extend Deprecation
11
11
 
12
- attr_reader :created_at, :updated_at
12
+ attr_reader :created_at, :updated_at, :etag
13
13
 
14
- def initialize(created_at:, updated_at:)
14
+ def initialize(created_at:, updated_at:, etag: nil)
15
15
  @created_at = created_at
16
16
  @updated_at = updated_at
17
+ @etag = etag
17
18
  end
18
19
 
19
20
  def [](key)
@@ -12,20 +12,6 @@ module Dor
12
12
  # @param assign_doi [Boolean]
13
13
  # @return [Cocina::Models::RequestDRO,Cocina::Models::RequestCollection,Cocina::Models::RequestAPO] the returned model
14
14
  def register(params:, assign_doi: false)
15
- json_str = register_response(params: params, assign_doi: assign_doi)
16
- json = JSON.parse(json_str)
17
-
18
- Cocina::Models.build(json)
19
- end
20
-
21
- private
22
-
23
- # make the registration request to the server
24
- # @param params [Hash] optional params (see dor-services-app)
25
- # @param assign_doi [Boolean]
26
- # @raise [UnexpectedResponse] on an unsuccessful response from the server
27
- # @return [String] the raw JSON from the server
28
- def register_response(params:, assign_doi:)
29
15
  resp = connection.post do |req|
30
16
  req.url "#{api_version}/objects"
31
17
  req.headers['Content-Type'] = 'application/json'
@@ -34,9 +20,10 @@ module Dor
34
20
  req.params[:assign_doi] = true if assign_doi
35
21
  req.body = params.to_json
36
22
  end
37
- return resp.body if resp.success?
38
23
 
39
- raise_exception_based_on_response!(resp)
24
+ raise_exception_based_on_response!(resp) unless resp.success?
25
+
26
+ build_cocina_from_response(resp)
40
27
  end
41
28
  end
42
29
  end
@@ -3,7 +3,7 @@
3
3
  module Dor
4
4
  module Services
5
5
  class Client
6
- VERSION = '8.7.0'
6
+ VERSION = '9.0.0'
7
7
  end
8
8
  end
9
9
  end
@@ -30,6 +30,8 @@ module Dor
30
30
  NotFoundResponse
31
31
  when 409
32
32
  ConflictResponse
33
+ when 412
34
+ PreconditionFailedResponse
33
35
  else
34
36
  UnexpectedResponse
35
37
  end
@@ -37,6 +39,20 @@ module Dor
37
39
  ResponseErrorFormatter.format(response: response, object_identifier: object_identifier)
38
40
  end
39
41
  # rubocop:enable Metrics/MethodLength
42
+
43
+ def build_cocina_from_response(response)
44
+ cocina_object = Cocina::Models.build(JSON.parse(response.body))
45
+ Cocina::Models.with_metadata(cocina_object, response.headers['ETag'], created: date_from_header(response, 'X-Created-At'),
46
+ modified: date_from_header(response, 'Last-Modified'))
47
+ end
48
+
49
+ def build_json_from_cocina(cocina_object)
50
+ Cocina::Models.without_metadata(cocina_object).to_json
51
+ end
52
+
53
+ def date_from_header(response, key)
54
+ response.headers[key]&.to_datetime
55
+ end
40
56
  end
41
57
  end
42
58
  end
@@ -46,6 +46,10 @@ module Dor
46
46
  # Error that is raised when the remote server returns a 409 Conflict
47
47
  class ConflictResponse < UnexpectedResponse; end
48
48
 
49
+ # Error that is raised when the remote server returns a 412 Precondition Failed.
50
+ # This occurs when you sent an etag with If-Match, but the etag didn't match the latest version
51
+ class PreconditionFailedResponse < UnexpectedResponse; end
52
+
49
53
  # Error that is raised when the remote server returns a 400 Bad Request; apps should not retry the request
50
54
  class BadRequestError < UnexpectedResponse; end
51
55
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dor-services-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.7.0
4
+ version: 9.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Coyne
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2022-04-12 00:00:00.000000000 Z
12
+ date: 2022-04-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -37,14 +37,14 @@ dependencies:
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.73.0
40
+ version: 0.75.0
41
41
  type: :runtime
42
42
  prerelease: false
43
43
  version_requirements: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 0.73.0
47
+ version: 0.75.0
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: deprecation
50
50
  requirement: !ruby/object:Gem::Requirement