dor-services-client 12.17.0 → 13.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: 28239d64f9889da5c2eb01d1f7c1a724454a3f9d6e5dc04454e6d537d8b1530c
4
- data.tar.gz: abffc94573aa3106b599477bff35c786c4ce4d6ba6bc41e9dea37dc43e8b220a
3
+ metadata.gz: 52d7f1922fb592d9b86bc19bb2613ea2649b294a83e6dc898795514ef75889ab
4
+ data.tar.gz: 3f455ceee20044d6b2dda3f9f74f25100349a7f390c9de462df2621b051e29da
5
5
  SHA512:
6
- metadata.gz: 70a705670a2f0ac259b7af85806f909311d2222eb0af263d1bcbd2d96bffb0cf34185e2a9a38f4ba8cd5e1da1f3f9d1c01d4d0c490ddf29873a421d40402212e
7
- data.tar.gz: 5ff867b49a8d5a552a6d0d5ffada7298fec9d8e19df029f8b79de2899ed1ab65b4058ddf4c0986ae99f1e6c63749bea999e3f165e3bb369416986f19e7e488ad
6
+ metadata.gz: 3a11dbc88113dbb5844d483c4514616ddbea9de1c5cce7afcab3e38b1f466e0f4c1f63cf6fe58953a7b6321b02eb408e2196a240ae8850d25b51d32a1785a48f
7
+ data.tar.gz: f322703d6d85a737bebc790701235f4765c4e2fd7fee248704c1c5dc1c027f991b082634765b415cbfb483e4d2f5c664712e500b67af82823fe00c194037639f
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- dor-services-client (12.17.0)
4
+ dor-services-client (13.0.0)
5
5
  activesupport (>= 4.2, < 8)
6
6
  cocina-models (~> 0.91.0)
7
7
  deprecation
@@ -23,7 +23,7 @@ GEM
23
23
  attr_extras (7.1.0)
24
24
  base64 (0.1.1)
25
25
  byebug (11.1.3)
26
- cocina-models (0.91.0)
26
+ cocina-models (0.91.2)
27
27
  activesupport
28
28
  deprecation
29
29
  dry-struct (~> 1.0)
@@ -69,7 +69,8 @@ GEM
69
69
  activesupport (>= 3.0, < 8.0)
70
70
  equivalent-xml (0.6.0)
71
71
  nokogiri (>= 1.4.3)
72
- faraday (2.7.10)
72
+ faraday (2.7.11)
73
+ base64
73
74
  faraday-net_http (>= 2.0, < 3.1)
74
75
  ruby2_keywords (>= 0.0.4)
75
76
  faraday-net_http (3.0.2)
@@ -80,7 +81,7 @@ GEM
80
81
  concurrent-ruby (~> 1.0)
81
82
  ice_nine (0.11.2)
82
83
  json (2.6.3)
83
- jsonpath (1.1.3)
84
+ jsonpath (1.1.4)
84
85
  multi_json
85
86
  language_server-protocol (3.17.0.3)
86
87
  minitest (5.20.0)
@@ -120,7 +121,7 @@ GEM
120
121
  rspec-support (3.12.1)
121
122
  rss (0.3.0)
122
123
  rexml
123
- rubocop (1.56.3)
124
+ rubocop (1.56.4)
124
125
  base64 (~> 0.1.1)
125
126
  json (~> 2.3)
126
127
  language_server-protocol (>= 3.17.0)
@@ -134,11 +135,11 @@ GEM
134
135
  unicode-display_width (>= 2.4.0, < 3.0)
135
136
  rubocop-ast (1.29.0)
136
137
  parser (>= 3.2.1.0)
137
- rubocop-capybara (2.18.0)
138
+ rubocop-capybara (2.19.0)
138
139
  rubocop (~> 1.41)
139
- rubocop-factory_bot (2.23.1)
140
+ rubocop-factory_bot (2.24.0)
140
141
  rubocop (~> 1.33)
141
- rubocop-rspec (2.24.0)
142
+ rubocop-rspec (2.24.1)
142
143
  rubocop (~> 1.33)
143
144
  rubocop-capybara (~> 2.17)
144
145
  rubocop-factory_bot (~> 2.22)
@@ -157,12 +158,12 @@ GEM
157
158
  thor (1.2.2)
158
159
  tzinfo (2.0.6)
159
160
  concurrent-ruby (~> 1.0)
160
- unicode-display_width (2.4.2)
161
+ unicode-display_width (2.5.0)
161
162
  webmock (3.19.1)
162
163
  addressable (>= 2.8.0)
163
164
  crack (>= 0.3.2)
164
165
  hashdiff (>= 0.4.0, < 2.0.0)
165
- zeitwerk (2.6.11)
166
+ zeitwerk (2.6.12)
166
167
 
167
168
  PLATFORMS
168
169
  x86_64-darwin-19
data/README.md CHANGED
@@ -78,18 +78,6 @@ background_jobs_client = Dor::Services::Client.background_job_results
78
78
  # Show results of background job
79
79
  background_jobs_client.show(job_id: 123)
80
80
 
81
- # Perform MARCXML operations
82
- marcxml_client = Dor::Services::Client.marcxml
83
-
84
- # Retrieve MARCXML for a given barcode
85
- marcxml_client.marcxml(barcode: '123456789')
86
-
87
- # Retrieve MARCXML for a given catkey
88
- marcxml_client.marcxml(catkey: '987654321')
89
-
90
- # Retrieve MARCXML for a given FOLIO instance HRID
91
- marcxml_client.marcxml(folio_instance_hrid: 'in000123')
92
-
93
81
  # For performing operations on a known, registered object
94
82
  object_client = Dor::Services::Client.object(object_identifier)
95
83
 
@@ -141,6 +129,9 @@ object_client.version.close
141
129
  # Return the Cocina metadata
142
130
  object_client.find
143
131
 
132
+ # Returns "lite" Cocina metadata (excluding specified attributes)
133
+ object_client.find_lite(structural: false, geographic: false)
134
+
144
135
  # Query for an object's collections
145
136
  object_client.collections
146
137
 
@@ -6,7 +6,7 @@ module Dor
6
6
  module Services
7
7
  class Client
8
8
  # API calls that are about a repository object
9
- class Object < VersionedService
9
+ class Object < VersionedService # rubocop:disable Metrics/ClassLength
10
10
  extend Deprecation
11
11
  attr_reader :object_identifier
12
12
 
@@ -52,6 +52,35 @@ module Dor
52
52
  build_cocina_from_response(resp, validate: validate)
53
53
  end
54
54
 
55
+ BASE_ALLOWED_FIELDS = %i[external_identifier cocina_version label version administrative description].freeze
56
+ DRO_ALLOWED_FIELDS = BASE_ALLOWED_FIELDS + %i[content_type access identification structural geographic]
57
+
58
+ # rubocop:disable Metrics/MethodLength
59
+ # rubocop:disable Metrics/AbcSize
60
+ # rubocop:disable Metrics/CyclomaticComplexity
61
+ # rubocop:disable Metrics/ParameterLists
62
+ def find_lite(administrative: true, description: true, access: true, structural: true, identification: true, geographic: true)
63
+ fields = []
64
+ fields << :administrative if administrative
65
+ fields << :description if description
66
+ fields << :access if access
67
+ fields << :structural if structural
68
+ fields << :identification if identification
69
+ fields << :geographic if geographic
70
+
71
+ resp = connection.post '/graphql', query(fields),
72
+ 'Content-Type' => 'application/json'
73
+ raise_exception_based_on_response!(resp) unless resp.success?
74
+ resp_json = JSON.parse(resp.body)
75
+ # GraphQL returns 200 even when an error
76
+ raise_graphql_exception(resp, resp_json)
77
+ Cocina::Models.build_lite(resp_json['data']['cocinaObject'])
78
+ end
79
+ # rubocop:enable Metrics/MethodLength
80
+ # rubocop:enable Metrics/AbcSize
81
+ # rubocop:enable Metrics/CyclomaticComplexity
82
+ # rubocop:enable Metrics/ParameterLists
83
+
55
84
  # Get a list of the collections. (Similar to Valkyrie's find_inverse_references_by)
56
85
  # @raise [UnexpectedResponse] if the request is unsuccessful.
57
86
  # @return [Array<Cocina::Models::DRO>]
@@ -140,6 +169,35 @@ module Dor
140
169
  def object_path
141
170
  "#{api_version}/objects/#{object_identifier}"
142
171
  end
172
+
173
+ DEFAULT_FIELDS = %i[externalIdentifier type version label cocinaVersion].freeze
174
+
175
+ def query(fields)
176
+ all_fields = DEFAULT_FIELDS + fields
177
+ {
178
+ query:
179
+ <<~GQL
180
+ {
181
+ cocinaObject(externalIdentifier: "#{object_identifier}") {
182
+ #{all_fields.join("\n")}
183
+ }
184
+ }
185
+ GQL
186
+ }.to_json
187
+ end
188
+
189
+ def raise_graphql_exception(resp, resp_json)
190
+ return unless resp_json['errors'].present?
191
+
192
+ exception_class = not_found_exception?(resp_json['errors'].first) ? NotFoundResponse : UnexpectedResponse
193
+ raise exception_class.new(response: resp,
194
+ object_identifier: object_identifier,
195
+ graphql_errors: resp_json['errors'])
196
+ end
197
+
198
+ def not_found_exception?(error)
199
+ error['message'] == 'Cocina object not found'
200
+ end
143
201
  end
144
202
  end
145
203
  end
@@ -3,7 +3,7 @@
3
3
  module Dor
4
4
  module Services
5
5
  class Client
6
- VERSION = '12.17.0'
6
+ VERSION = '13.0.0'
7
7
  end
8
8
  end
9
9
  end
@@ -43,17 +43,21 @@ module Dor
43
43
  # @param [Faraday::Response] response
44
44
  # @param [String] object_identifier (nil)
45
45
  # @param [Hash<String,Object>] errors (nil) the JSON-API errors object
46
+ # @param [Hash<String,Object>] graphql_errors (nil) the GraphQL errors object
46
47
  # rubocop:disable Lint/MissingSuper
47
- def initialize(response:, object_identifier: nil, errors: nil)
48
+ def initialize(response:, object_identifier: nil, errors: nil, graphql_errors: nil)
48
49
  @response = response
49
50
  @object_identifier = object_identifier
50
51
  @errors = errors
52
+ @graphql_errors = graphql_errors
51
53
  end
52
54
  # rubocop:enable Lint/MissingSuper
53
55
 
54
- attr_accessor :errors
56
+ attr_accessor :errors, :graphql_errors
55
57
 
56
58
  def to_s
59
+ # For GraphQL errors, see https://graphql-ruby.org/errors/execution_errors
60
+ return graphql_errors.map { |e| e['message'] }.join(', ') if graphql_errors.present?
57
61
  return errors.map { |e| "#{e['title']} (#{e['detail']})" }.join(', ') if errors.present?
58
62
 
59
63
  ResponseErrorFormatter.format(response: @response, object_identifier: @object_identifier)
@@ -107,11 +111,6 @@ module Dor
107
111
  @background_job_results ||= BackgroundJobResults.new(connection: connection, version: DEFAULT_VERSION)
108
112
  end
109
113
 
110
- # @return [Dor::Services::Client::Marcxml] an instance of the `Client::Marcxml` class
111
- def marcxml
112
- @marcxml ||= Marcxml.new(connection: connection, version: DEFAULT_VERSION)
113
- end
114
-
115
114
  class << self
116
115
  # @param [String] url the base url of the endpoint the client should connect to (required)
117
116
  # @param [String] token a bearer token for HTTP authentication (required)
@@ -127,8 +126,7 @@ module Dor
127
126
  self
128
127
  end
129
128
 
130
- delegate :background_job_results, :marcxml, :objects, :object,
131
- :virtual_objects, :administrative_tags, to: :instance
129
+ delegate :background_job_results, :objects, :object, :virtual_objects, :administrative_tags, to: :instance
132
130
  end
133
131
 
134
132
  attr_writer :url, :token, :connection, :enable_get_retries
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: 12.17.0
4
+ version: 13.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: 2023-09-13 00:00:00.000000000 Z
12
+ date: 2023-10-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -245,7 +245,6 @@ files:
245
245
  - lib/dor/services/client/connection_wrapper.rb
246
246
  - lib/dor/services/client/error_faraday_middleware.rb
247
247
  - lib/dor/services/client/events.rb
248
- - lib/dor/services/client/marcxml.rb
249
248
  - lib/dor/services/client/members.rb
250
249
  - lib/dor/services/client/mutate.rb
251
250
  - lib/dor/services/client/object.rb
@@ -279,7 +278,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
279
278
  - !ruby/object:Gem::Version
280
279
  version: '0'
281
280
  requirements: []
282
- rubygems_version: 3.3.7
281
+ rubygems_version: 3.4.19
283
282
  signing_key:
284
283
  specification_version: 4
285
284
  summary: A client for dor-services-app
@@ -1,48 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Dor
4
- module Services
5
- class Client
6
- # API calls around MARCXML-based operations from dor-services-app
7
- class Marcxml < VersionedService
8
- # Gets MARCXML corresponding to a barcode or catkey
9
- # @param barcode [String] string representing a barcode
10
- # @param catkey [String] string representing a catkey
11
- # @param folio_instance_hrid [String] string representing a Folio instance HRID
12
- # @raise [NotFoundResponse] when the response is a 500 with "Record not found in Symphony"
13
- # @raise [UnexpectedResponse] on an unsuccessful response from the server
14
- # @return [String] MARCXML
15
- def marcxml(barcode: nil, catkey: nil, folio_instance_hrid: nil)
16
- check_args(barcode, catkey, folio_instance_hrid)
17
-
18
- resp = connection.get do |req|
19
- req.url "#{api_version}/catalog/marcxml"
20
- req.params['barcode'] = barcode unless barcode.nil?
21
- req.params['catkey'] = catkey unless catkey.nil?
22
- req.params['folio_instance_hrid'] = folio_instance_hrid unless folio_instance_hrid.nil?
23
- end
24
-
25
- # This method needs its own exception handling logic due to how the endpoint service (Symphony) operates
26
-
27
- # DOR Services App does not respond with a 404 when no match in Symphony or Folio.
28
- # Rather, it responds with a 500 containing "Record not found in catalog" in the body.
29
- # raise a NotFoundResponse because the resource being requested was not found in the ILS (via dor-services-app)
30
- raise NotFoundResponse.new(response: resp) if !resp.success? && resp.body.match?(/Record not found in catalog/)
31
-
32
- raise UnexpectedResponse.new(response: resp) unless resp.success?
33
-
34
- resp.body
35
- end
36
-
37
- private
38
-
39
- # rubocop:disable Layout/LineLength
40
- def check_args(barcode, catkey, folio_instance_hrid)
41
- raise ArgumentError, 'Barcode, catkey, or folio_instance_hrid must be provided' if barcode.nil? && catkey.nil? && folio_instance_hrid.nil?
42
- raise ArgumentError, 'Both barcode and a catalog id (catkey or folio_instance_hrid) may not be provided' if !barcode.nil? && (!catkey.nil? || !folio_instance_hrid.nil?)
43
- end
44
- # rubocop:enable Layout/LineLength
45
- end
46
- end
47
- end
48
- end