dor-services-client 9.0.0 → 10.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: 6420f39cd3b4f4d1e125929725e7a749fdef2b4a3b41008fd6d6d440708aaba8
4
- data.tar.gz: 3690b2a21d44ad9cc830a04f58117731bc4ab53f5d495edc5c4a0846150cd737
3
+ metadata.gz: 92add95b112e8d9c6cdce2ba2e91e08d4a49cb4d3329868c34441fe272fcc9c2
4
+ data.tar.gz: 18e2a92e7a11955f46ce18f832a0942dbbac87e300d3910e9cbddbb8ee7681fa
5
5
  SHA512:
6
- metadata.gz: 1130a9e3510b4db1a1d383647de3e9c3c87f8b426c40586326ff88c300bb7508749c29eab8fcc35c5cb91db1cc0458fbc3b1949f12004bc3a4fa2cad9109db68
7
- data.tar.gz: 63459db88fccc089c36c02b8a6496988edfa628844b04eb8991563c3fce014c88def669b5f452f48144a1e4c0bd87b2172bb1c674567295b31b280924f86124f
6
+ metadata.gz: aab5c196702ecdf1fca112cc9e65ab4e0136a9f4d79a0f96e8b31a7d4b71cf3d2daa978cf59234190fba35d0674f31449f6a8c4ac5a2fac9c9fd38e933a4102e
7
+ data.tar.gz: 8882218dba3fa8266a19ea4c299569fd62c1b41b32119bf897b65d4333687df943c407e84bb3f48d213317caa40b8245ea4810eaf6e69f32b836bc6e262cc2aa
data/.rubocop.yml CHANGED
@@ -13,6 +13,9 @@ Metrics/BlockLength:
13
13
  - 'spec/**/*'
14
14
 
15
15
  RSpec/MultipleMemoizedHelpers:
16
+ Enabled: false
17
+
18
+ RSpec/ExampleLength:
16
19
  Max: 10
17
20
 
18
21
  Gemspec/DateAssignment: # (new in 1.10)
data/.rubocop_todo.yml CHANGED
@@ -25,12 +25,6 @@ RSpec/AnyInstance:
25
25
  - 'spec/dor/services/client/metadata_spec.rb'
26
26
  - 'spec/dor/services/client/object_version_spec.rb'
27
27
 
28
- # Offense count: 1
29
- # Configuration parameters: Max, CountAsOne.
30
- RSpec/ExampleLength:
31
- Exclude:
32
- - 'spec/dor/services/client/metadata_spec.rb'
33
-
34
28
  # Offense count: 6
35
29
  RSpec/IdenticalEqualityAssertion:
36
30
  Exclude:
@@ -20,9 +20,9 @@ module Dor
20
20
 
21
21
  # This method needs its own exception handling logic due to how the endpoint service (SearchWorks) operates
22
22
  # raise a NotFoundResponse because the resource being requested was not found in the ILS (via dor-services-app)
23
- raise NotFoundResponse, ResponseErrorFormatter.format(response: resp) if resp.success? && resp.body.blank?
23
+ raise NotFoundResponse.new(response: resp) if resp.success? && resp.body.blank?
24
24
 
25
- raise UnexpectedResponse, ResponseErrorFormatter.format(response: resp)
25
+ raise UnexpectedResponse.new(response: resp)
26
26
  end
27
27
 
28
28
  # Gets MARCXML corresponding to a barcode or catkey
@@ -45,9 +45,9 @@ module Dor
45
45
  # DOR Services App does not respond with a 404 when no match in Symphony.
46
46
  # Rather, it responds with a 500 containing "Record not found in Symphony" in the body.
47
47
  # raise a NotFoundResponse because the resource being requested was not found in the ILS (via dor-services-app)
48
- raise NotFoundResponse, ResponseErrorFormatter.format(response: resp) if !resp.success? && resp.body.match?(/Record not found in Symphony/)
48
+ raise NotFoundResponse.new(response: resp) if !resp.success? && resp.body.match?(/Record not found in Symphony/)
49
49
 
50
- raise UnexpectedResponse, ResponseErrorFormatter.format(response: resp) unless resp.success?
50
+ raise UnexpectedResponse.new(response: resp) unless resp.success?
51
51
 
52
52
  resp.body
53
53
  end
@@ -33,16 +33,19 @@ module Dor
33
33
  # @raise [BadRequestError] when ETag not provided.
34
34
  # @return [Cocina::Models::DROWithMetadata,Cocina::Models::CollectionWithMetadata,Cocina::Models::AdminPolicyWithMetadata] the returned model
35
35
  # rubocop:disable Metrics/AbcSize
36
+ # rubocop:disable Metrics/MethodLength
36
37
  def update(params:, skip_lock: false)
38
+ raise ArgumentError, 'Cocina object not provided.' unless params.respond_to?(:externalIdentifier)
39
+
37
40
  # Raised if Cocina::Models::*WithMetadata not provided.
38
- raise BadRequestError, 'ETag not provided.' unless skip_lock || params.respond_to?(:lock)
41
+ raise ArgumentError, 'ETag not provided.' unless skip_lock || params.respond_to?(:lock)
39
42
 
40
43
  resp = connection.patch do |req|
41
44
  req.url object_path
42
45
  req.headers['Content-Type'] = 'application/json'
43
46
  # asking the service to return JSON (else it'll be plain text)
44
47
  req.headers['Accept'] = 'application/json'
45
- req.headers['If-Match'] = params[:lock] unless skip_lock
48
+ req.headers['If-Match'] = params.lock unless skip_lock
46
49
  req.body = build_json_from_cocina(params)
47
50
  end
48
51
 
@@ -51,6 +54,7 @@ module Dor
51
54
  build_cocina_from_response(resp)
52
55
  end
53
56
  # rubocop:enable Metrics/AbcSize
57
+ # rubocop:enable Metrics/MethodLength
54
58
 
55
59
  # Pull in metadata from Symphony and updates descriptive metadata
56
60
  # @raise [NotFoundResponse] when the response is a 404 (object not found)
@@ -53,15 +53,19 @@ module Dor
53
53
 
54
54
  # Open new version for an object
55
55
  # @param params [Hash] optional params (see dor-services-app)
56
- # @raise [MalformedResponse] when the response is not parseable.
57
56
  # @raise [NotFoundResponse] when the response is a 404 (object not found)
58
57
  # @raise [UnexpectedResponse] when the response is not successful.
59
- # @return [String] the current version
58
+ # @return [Cocina::Models::DROWithMetadata|CollectionWithMetadata|AdminPolicyWithMetadata] cocina model with updated version
60
59
  def open(**params)
61
- version = open_new_version_response(**params)
62
- raise MalformedResponse, "Version of #{object_identifier} is empty" if version.empty?
60
+ resp = connection.post do |req|
61
+ req.url open_new_version_path
62
+ req.headers['Content-Type'] = 'application/json'
63
+ req.body = params.to_json if params.any?
64
+ end
63
65
 
64
- version
66
+ raise_exception_based_on_response!(resp) unless resp.success?
67
+
68
+ build_cocina_from_response(resp)
65
69
  end
66
70
 
67
71
  # Close current version for an object
@@ -99,22 +103,6 @@ module Dor
99
103
  "#{api_version}/objects/#{object_identifier}"
100
104
  end
101
105
 
102
- # Make request to server to open a new version
103
- # @param params [Hash] optional params (see dor-services-app)
104
- # @raise [NotFoundResponse] when the response is a 404 (object not found)
105
- # @raise [UnexpectedResponse] on an unsuccessful response from the server
106
- # @return [String] the plain text from the server
107
- def open_new_version_response(**params)
108
- resp = connection.post do |req|
109
- req.url open_new_version_path
110
- req.headers['Content-Type'] = 'application/json'
111
- req.body = params.to_json if params.any?
112
- end
113
- return resp.body if resp.success?
114
-
115
- raise_exception_based_on_response!(resp)
116
- end
117
-
118
106
  def base_path
119
107
  "#{object_path}/versions"
120
108
  end
@@ -8,9 +8,9 @@ module Dor
8
8
  # API calls that are about a repository objects
9
9
  class Objects < VersionedService
10
10
  # Creates a new object in DOR
11
- # @param params [Cocina::Models::RequestDRO,Cocina::Models::RequestCollection,Cocina::Models::RequestAPO]
11
+ # @param params [Cocina::Models::RequestDRO,Cocina::Models::RequestCollection,Cocina::Models::RequestAdminPolicy]
12
12
  # @param assign_doi [Boolean]
13
- # @return [Cocina::Models::RequestDRO,Cocina::Models::RequestCollection,Cocina::Models::RequestAPO] the returned model
13
+ # @return [Cocina::Models::DROWithMetadata,Cocina::Models::CollectionWithMetadata,Cocina::Models::AdminPolicyWithMetadata] the returned model
14
14
  def register(params:, assign_doi: false)
15
15
  resp = connection.post do |req|
16
16
  req.url "#{api_version}/objects"
@@ -3,7 +3,7 @@
3
3
  module Dor
4
4
  module Services
5
5
  class Client
6
- VERSION = '9.0.0'
6
+ VERSION = '10.0.0'
7
7
  end
8
8
  end
9
9
  end
@@ -5,6 +5,16 @@ module Dor
5
5
  class Client
6
6
  # @abstract API calls to a versioned endpoint
7
7
  class VersionedService
8
+ EXCEPTION_CLASS = {
9
+ 400 => BadRequestError,
10
+ 401 => UnauthorizedResponse,
11
+ 404 => NotFoundResponse,
12
+ 409 => ConflictResponse,
13
+ 412 => PreconditionFailedResponse
14
+ }.freeze
15
+
16
+ JSON_API_MIME_TYPE = 'application/vnd.api+json'
17
+
8
18
  def initialize(connection:, version:)
9
19
  @connection = connection
10
20
  @api_version = version
@@ -19,26 +29,17 @@ module Dor
19
29
 
20
30
  attr_reader :connection, :api_version
21
31
 
22
- # rubocop:disable Metrics/MethodLength
23
32
  def raise_exception_based_on_response!(response, object_identifier = nil)
24
- exception_class = case response.status
25
- when 400
26
- BadRequestError
27
- when 401
28
- UnauthorizedResponse
29
- when 404
30
- NotFoundResponse
31
- when 409
32
- ConflictResponse
33
- when 412
34
- PreconditionFailedResponse
35
- else
36
- UnexpectedResponse
37
- end
38
- raise exception_class,
39
- ResponseErrorFormatter.format(response: response, object_identifier: object_identifier)
33
+ data = if response.headers.fetch('content-type', '').start_with?(JSON_API_MIME_TYPE)
34
+ JSON.parse(response.body)
35
+ else
36
+ {}
37
+ end
38
+ exception_class = EXCEPTION_CLASS.fetch(response.status, UnexpectedResponse)
39
+ raise exception_class.new(response: response,
40
+ object_identifier: object_identifier,
41
+ errors: data.fetch('errors', []))
40
42
  end
41
- # rubocop:enable Metrics/MethodLength
42
43
 
43
44
  def build_cocina_from_response(response)
44
45
  cocina_object = Cocina::Models.build(JSON.parse(response.body))
@@ -38,7 +38,26 @@ module Dor
38
38
 
39
39
  # Error that is raised when the remote server returns some unexpected response
40
40
  # this could be any 4xx or 5xx status (except the ones that are direct children of the Error class above)
41
- class UnexpectedResponse < Error; end
41
+ class UnexpectedResponse < Error
42
+ # @param [Faraday::Response] response
43
+ # @param [String] object_identifier (nil)
44
+ # @param [Hash<String,Object>] errors (nil) the JSON-API errors object
45
+ # rubocop:disable Lint/MissingSuper
46
+ def initialize(response:, object_identifier: nil, errors: nil)
47
+ @response = response
48
+ @object_identifier = object_identifier
49
+ @errors = errors
50
+ end
51
+ # rubocop:enable Lint/MissingSuper
52
+
53
+ attr_accessor :errors
54
+
55
+ def to_s
56
+ return errors.map { |e| "#{e['title']} (#{e['detail']})" }.join(', ') if errors.present?
57
+
58
+ ResponseErrorFormatter.format(response: @response, object_identifier: @object_identifier)
59
+ end
60
+ end
42
61
 
43
62
  # Error that is raised when the remote server returns a 401 Unauthorized
44
63
  class UnauthorizedResponse < UnexpectedResponse; end
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: 9.0.0
4
+ version: 10.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-20 00:00:00.000000000 Z
12
+ date: 2022-04-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport