dor-workflow-client 7.3.0 → 7.4.1

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: f68410646d6db8f4544022b03aa0c1f4ed062c94482663d6076a2e08deefc0aa
4
- data.tar.gz: 2fceb32ccab79dc19cf8449268965f3450d26fb1ab57d23ebff17b316f95c758
3
+ metadata.gz: 5b29586cf5f0f5d2fd768d99ae4533af1d29e1879daa96b1e5611e09ef8195ff
4
+ data.tar.gz: 74c7641b0e942528005d65318116702a5cba4171b6f833f2ec46aa3065619ac7
5
5
  SHA512:
6
- metadata.gz: bec89343f7f847098e221235e4f8f76fe862e57a4af9f05f6da16bc7739e9db28777ae2df11860eba4630c88d5fe179571b6a18bf556477fcae838793e579960
7
- data.tar.gz: b1a5e69406924bd48383e18cabd9416d95a77b90c8cbbdfaf2e395de50b2e95926f9a2b30958036f94fa77be2a05f9a0556f5de0c080e3b1881ed7c2351e956a
6
+ metadata.gz: 46e27f180e3df6018706a9f01051ff09e757795bdc76e013ff8e493a01ba45a639f054a0fefa55f340e3aa054c7458eb4fc82acc8233f2c28208a8476e17c5b3
7
+ data.tar.gz: 9597f00cc9074bac61867dd441b2d96150ce814763c2d5e25b84e3741b905a0233f5a96e1061f61ba0f43aef13a5aebb57f18f9911d12026c7e51acc78ffc832
data/.circleci/config.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  version: 2.1
2
2
  orbs:
3
- ruby-rails: sul-dlss/ruby-rails@4.1.0
3
+ ruby-rails: sul-dlss/ruby-rails@4.2.0
4
4
  workflows:
5
5
  build:
6
6
  jobs:
data/.gitignore CHANGED
@@ -15,5 +15,6 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ workflow_service.log*
18
19
  .ruby-version
19
20
  .ruby-gemset
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- dor-workflow-client (7.3.0)
4
+ dor-workflow-client (7.4.1)
5
5
  activesupport (>= 3.2.1, < 8)
6
6
  deprecation (>= 0.99.0)
7
7
  faraday (~> 2.0)
@@ -12,7 +12,7 @@ PATH
12
12
  GEM
13
13
  remote: https://rubygems.org/
14
14
  specs:
15
- activesupport (7.1.3.2)
15
+ activesupport (7.1.3.3)
16
16
  base64
17
17
  bigdecimal
18
18
  concurrent-ruby (~> 1.0, >= 1.0.2)
@@ -26,7 +26,7 @@ GEM
26
26
  public_suffix (>= 2.0.2, < 6.0)
27
27
  ast (2.4.2)
28
28
  base64 (0.2.0)
29
- bigdecimal (3.1.7)
29
+ bigdecimal (3.1.8)
30
30
  byebug (11.1.3)
31
31
  concurrent-ruby (1.2.3)
32
32
  connection_pool (2.4.1)
@@ -42,31 +42,32 @@ GEM
42
42
  faraday-net_http (>= 2.0, < 3.2)
43
43
  faraday-net_http (3.1.0)
44
44
  net-http
45
- faraday-retry (2.2.0)
45
+ faraday-retry (2.2.1)
46
46
  faraday (~> 2.0)
47
47
  hashdiff (1.1.0)
48
- i18n (1.14.4)
48
+ i18n (1.14.5)
49
49
  concurrent-ruby (~> 1.0)
50
50
  json (2.7.2)
51
51
  language_server-protocol (3.17.0.3)
52
- mini_portile2 (2.8.5)
53
- minitest (5.22.3)
52
+ mini_portile2 (2.8.6)
53
+ minitest (5.23.0)
54
54
  mutex_m (0.2.0)
55
55
  net-http (0.4.1)
56
56
  uri
57
- nokogiri (1.16.3)
57
+ nokogiri (1.16.5)
58
58
  mini_portile2 (~> 2.8.2)
59
59
  racc (~> 1.4)
60
60
  parallel (1.24.0)
61
- parser (3.3.0.5)
61
+ parser (3.3.1.0)
62
62
  ast (~> 2.4.1)
63
63
  racc
64
64
  public_suffix (5.0.5)
65
- racc (1.7.3)
65
+ racc (1.8.0)
66
66
  rainbow (3.1.1)
67
67
  rake (13.2.1)
68
- regexp_parser (2.9.0)
69
- rexml (3.2.6)
68
+ regexp_parser (2.9.2)
69
+ rexml (3.2.8)
70
+ strscan (>= 3.0.9)
70
71
  rspec (3.13.0)
71
72
  rspec-core (~> 3.13.0)
72
73
  rspec-expectations (~> 3.13.0)
@@ -76,13 +77,13 @@ GEM
76
77
  rspec-expectations (3.13.0)
77
78
  diff-lcs (>= 1.2.0, < 2.0)
78
79
  rspec-support (~> 3.13.0)
79
- rspec-mocks (3.13.0)
80
+ rspec-mocks (3.13.1)
80
81
  diff-lcs (>= 1.2.0, < 2.0)
81
82
  rspec-support (~> 3.13.0)
82
83
  rspec-support (3.13.1)
83
84
  rspec_junit_formatter (0.6.0)
84
85
  rspec-core (>= 2, < 4, != 2.12.0)
85
- rubocop (1.63.0)
86
+ rubocop (1.63.5)
86
87
  json (~> 2.3)
87
88
  language_server-protocol (>= 3.17.0)
88
89
  parallel (~> 1.10)
@@ -93,20 +94,20 @@ GEM
93
94
  rubocop-ast (>= 1.31.1, < 2.0)
94
95
  ruby-progressbar (~> 1.7)
95
96
  unicode-display_width (>= 2.4.0, < 3.0)
96
- rubocop-ast (1.31.2)
97
- parser (>= 3.3.0.4)
97
+ rubocop-ast (1.31.3)
98
+ parser (>= 3.3.1.0)
98
99
  rubocop-capybara (2.20.0)
99
100
  rubocop (~> 1.41)
100
101
  rubocop-factory_bot (2.25.1)
101
102
  rubocop (~> 1.41)
102
103
  rubocop-rake (0.6.0)
103
104
  rubocop (~> 1.0)
104
- rubocop-rspec (2.29.1)
105
+ rubocop-rspec (2.29.2)
105
106
  rubocop (~> 1.40)
106
107
  rubocop-capybara (~> 2.17)
107
108
  rubocop-factory_bot (~> 2.22)
108
109
  rubocop-rspec_rails (~> 2.28)
109
- rubocop-rspec_rails (2.28.2)
110
+ rubocop-rspec_rails (2.28.3)
110
111
  rubocop (~> 1.40)
111
112
  ruby-progressbar (1.13.0)
112
113
  simplecov (0.22.0)
@@ -115,6 +116,7 @@ GEM
115
116
  simplecov_json_formatter (~> 0.1)
116
117
  simplecov-html (0.12.3)
117
118
  simplecov_json_formatter (0.1.4)
119
+ strscan (3.1.0)
118
120
  tzinfo (2.0.6)
119
121
  concurrent-ruby (~> 1.0)
120
122
  unicode-display_width (2.5.0)
@@ -124,7 +126,7 @@ GEM
124
126
  crack (>= 0.3.2)
125
127
  hashdiff (>= 0.4.0, < 2.0.0)
126
128
  yard (0.9.36)
127
- zeitwerk (2.6.13)
129
+ zeitwerk (2.6.14)
128
130
 
129
131
  PLATFORMS
130
132
  ruby
data/README.md CHANGED
@@ -19,15 +19,47 @@ client = Dor::Workflow::Client.new(url: 'https://test-server.edu/workflow/')
19
19
 
20
20
  Consumers of recent versions of the [dor-services](https://github.com/sul-dlss/dor-services) gem can access the configured `Dor::Workflow::Client` object via `Dor::Config`.
21
21
 
22
+ ## Console
23
+
24
+ During development, you can test the gem locally on your laptop, hitting a local instance of workflow-server-rails via the console:
25
+
26
+ ```ruby
27
+ bin/console
28
+
29
+ client = Dor::Workflow::Client.new(url: 'http://localhost:3000')
30
+ client.create_workflow_by_name('druid:bc123df4567', 'accessionWF', version: '1', context: { 'requireOCR' => true})
31
+
32
+ client.workflows('druid:bc123df4567')
33
+ => ["accessionWF"]
34
+
35
+ client.workflow(pid: 'druid:bc123df4567', workflow_name: 'accessionWF')
36
+ => #<Dor::Workflow::Response::Workflow:0x0000000105c8b440
37
+
38
+ client.process(pid: 'druid:bc123df4567', workflow_name: 'accessionWF', process: 'start-accession').context
39
+ => {"requireOCR"=>true}
40
+
41
+ client.all_workflows(pid: 'druid:bc123df4567')
42
+ => #<Dor::Workflow::Response::Workflows:0x00000001055d29a0>.....
43
+ ```
44
+
22
45
  ## API
23
46
  [Rubydoc](https://www.rubydoc.info/github/sul-dlss/dor-workflow-client/main)
24
47
 
48
+ ### Workflow Variables
49
+
50
+ If a workflow or workflows for a particular object require data to be persisted and available between steps, workflow variables can be set. These are per object/version pair and thus available to any step in any workflow for a given version of an object once set. Pass in a context variable as a Hash as shown in the example below. The context will be returned as a hash when fetching workflows data for an object.
51
+
25
52
  ### Example usage
26
53
  Create a workflow
27
54
  ```
28
55
  client.create_workflow_by_name('druid:bc123df4567', 'etdSubmitWF', version: '1')
29
56
  ```
30
57
 
58
+ Create a workflow and send in context
59
+ ```
60
+ client.create_workflow_by_name('druid:bc123df4567', 'etdSubmitWF', version: '1', context: { foo: 'bar'} )
61
+ ```
62
+
31
63
  Update a workflow step's status
32
64
  ```ruby
33
65
  client.update_status(druid: 'druid:bc123df4567',
@@ -36,6 +68,24 @@ client.update_status(druid: 'druid:bc123df4567',
36
68
  status: 'completed')
37
69
  ```
38
70
 
71
+ Fetch information about a workflow:
72
+ ```ruby
73
+ client.workflow(pid: 'druid:bc123df4567', workflow_name: 'etdSubmitWF')
74
+ => #<Dor::Workflow::Response::Workflow:0x000000010cb28588
75
+ ```
76
+
77
+ Fetch information about a workflow step:
78
+ ```ruby
79
+ client.process(pid: 'druid:bc123df4567', workflow_name: 'etdSubmitWF', process: 'registrar-approval')
80
+ => #<Dor::Workflow::Response::Process:0x000000010c505098
81
+ ```
82
+
83
+ Fetch version context about a workflow step:
84
+ ```ruby
85
+ client.process(pid: 'druid:bc123df4567', workflow_name: 'etdSubmitWF', process: 'registrar-approval').context
86
+ => {"foo"=>"bar"}
87
+ ```
88
+
39
89
  Show "milestones" for an object
40
90
  ```ruby
41
91
  client.milestones(druid: 'druid:gv054hp4128')
data/bin/console ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'dor/workflow/client'
6
+
7
+ require 'irb'
8
+ IRB.start(__FILE__)
@@ -11,7 +11,6 @@ module Dor
11
11
 
12
12
  # Returns the Date for a requested milestone from workflow lifecycle
13
13
  #
14
- # @param [String] repo The repository the object resides in. This parameter is deprecated
15
14
  # @param [String] druid object id
16
15
  # @param [String] milestone_name the name of the milestone being queried for
17
16
  # @param [Number] version (nil) the version to query for
@@ -3,7 +3,7 @@
3
3
  module Dor
4
4
  module Workflow
5
5
  class Client
6
- VERSION = '7.3.0'
6
+ VERSION = '7.4.1'
7
7
  end
8
8
  end
9
9
  end
@@ -14,7 +14,6 @@ module Dor
14
14
  # - completes the versioningWF:submit-version and versioningWF:start-accession steps
15
15
  # - initiates accesssionWF
16
16
  #
17
- # @param [String] repo The repository the object resides in. This parameter is deprecated
18
17
  # @param [String] druid The id of the object to delete the workflow from
19
18
  # @param [Boolean] create_accession_wf Option to create accessionWF when closing a version. Defaults to true
20
19
  def close_version(druid:, version:, create_accession_wf: true)
@@ -17,13 +17,15 @@ module Dor
17
17
  # @param [String] workflow_name The name of the workflow you want to create. This must correspond with a workflow
18
18
  # name that is known by the workflow service.
19
19
  # @param [String] lane_id adds laneId attribute to all process elements in the wf_xml workflow xml. Defaults to a value of 'default'
20
+ # @param [Hash] context optional context to be included in the workflow (same for all processes for a given druid/version pair)
20
21
  # @param [Integer] version specifies the version so that workflow service doesn't need to query dor-services.
21
22
  # @return [Boolean] always true
22
23
  #
23
- def create_workflow_by_name(druid, workflow_name, version:, lane_id: 'default')
24
+ def create_workflow_by_name(druid, workflow_name, version:, lane_id: 'default', context: nil)
24
25
  params = { 'lane-id' => lane_id, 'version' => version }
25
- requestor.request "objects/#{druid}/workflows/#{workflow_name}", 'post', '',
26
- content_type: 'application/xml',
26
+ body = context ? { 'context' => context }.to_json : ''
27
+ requestor.request "objects/#{druid}/workflows/#{workflow_name}", 'post', body,
28
+ content_type: 'application/json',
27
29
  params: params
28
30
  true
29
31
  end
@@ -31,7 +33,6 @@ module Dor
31
33
  # Updates the status of one step in a workflow.
32
34
  # Returns true on success. Caller must handle any exceptions
33
35
  #
34
- # @param [String] repo The repository the object resides in. The service recoginzes "dor" and "sdr" at the moment
35
36
  # @param [String] druid The id of the object
36
37
  # @param [String] workflow The name of the workflow
37
38
  # @param [String] process The name of the process step
@@ -50,6 +51,7 @@ module Dor
50
51
  def update_status(druid:, workflow:, process:, status:, elapsed: 0, lifecycle: nil, note: nil, current_status: nil)
51
52
  raise ArgumentError, "Unknown status value #{status}" unless VALID_STATUS.include?(status)
52
53
  raise ArgumentError, "Unknown current_status value #{current_status}" if current_status && !VALID_STATUS.include?(current_status)
54
+ raise ArgumentError, "Do not set status to 'error', use update_error_status method" if status == 'error'
53
55
 
54
56
  xml = create_process_xml(name: process, status: status, elapsed: elapsed, lifecycle: lifecycle, note: note)
55
57
  uri = "objects/#{druid}/workflows/#{workflow}/#{process}"
@@ -61,7 +63,6 @@ module Dor
61
63
 
62
64
  #
63
65
  # Retrieves the process status of the given workflow for the given object identifier
64
- # @param [String] repo The repository the object resides in. Currently recoginzes "dor" and "sdr".
65
66
  # @param [String] druid The id of the object
66
67
  # @param [String] workflow The name of the workflow
67
68
  # @param [String] process The name of the process step
@@ -24,7 +24,7 @@ module Dor
24
24
  #
25
25
  # Create and update workflows
26
26
  class Client
27
- # From Workflow Service's admin/Process.java
27
+ # From workflow-server-rails' app/models/workflow_step.rb
28
28
  VALID_STATUS = %w[waiting completed error queued skipped started].freeze
29
29
 
30
30
  attr_accessor :requestor
@@ -40,7 +40,7 @@ module Dor
40
40
  @requestor = Requestor.new(connection: connection || ConnectionFactory.build_connection(url, timeout: timeout, logger: logger))
41
41
  end
42
42
 
43
- delegate :create_workflow_by_name, :workflow_status, :workflows,
43
+ delegate :create_workflow_by_name, :workflow_status, :workflows, :all_workflows,
44
44
  :workflow, :process, :delete_workflow, :delete_all_workflows, :update_status, :update_error_status,
45
45
  to: :workflow_routes
46
46
 
@@ -51,6 +51,13 @@ module Dor
51
51
  @attributes[:laneId].presence
52
52
  end
53
53
 
54
+ # @return [Hash] the context for the process (or empty hash if none present)
55
+ def context
56
+ return {} unless @attributes[:context].present?
57
+
58
+ JSON.parse(@attributes[:context])
59
+ end
60
+
54
61
  delegate :pid, :workflow_name, to: :parent
55
62
 
56
63
  private
@@ -108,6 +108,12 @@ RSpec.describe Dor::Workflow::Client::WorkflowRoutes do
108
108
  expect { routes.update_status(druid: druid, workflow: 'accessionWF', process: 'publish', status: 'NOT_VALID_STATUS') }.to raise_error(ArgumentError)
109
109
  end
110
110
  end
111
+
112
+ context 'when an error status is provided' do
113
+ it 'throws an exception' do
114
+ expect { routes.update_status(druid: druid, workflow: 'accessionWF', process: 'publish', status: 'error') }.to raise_error(ArgumentError)
115
+ end
116
+ end
111
117
  end
112
118
 
113
119
  describe '#update_error_status' do
@@ -169,8 +175,48 @@ RSpec.describe Dor::Workflow::Client::WorkflowRoutes do
169
175
  end
170
176
 
171
177
  describe '#create_workflow_by_name' do
172
- it 'need to write these specs', skip: 'need to write specs' do
173
- # something
178
+ let(:mock_requestor) { instance_double(Dor::Workflow::Client::Requestor, request: nil) }
179
+
180
+ context 'with default lane_id and no context' do
181
+ subject(:create_workflow_by_name) do
182
+ routes.create_workflow_by_name('druid:mw971zk1113', 'accessionWF', version: '1')
183
+ end
184
+
185
+ it 'sends a create request with default lane_id and without any context param' do
186
+ create_workflow_by_name
187
+ expect(mock_requestor).to have_received(:request)
188
+ .with('objects/druid:mw971zk1113/workflows/accessionWF', 'post', '',
189
+ { content_type: 'application/json',
190
+ params: { 'lane-id' => 'default', 'version' => '1' } })
191
+ end
192
+ end
193
+
194
+ context 'with a custom lane_id' do
195
+ subject(:create_workflow_by_name) do
196
+ routes.create_workflow_by_name('druid:mw971zk1113', 'accessionWF', version: '1', lane_id: 'hamburgers')
197
+ end
198
+
199
+ it 'sends a create request without any context param' do
200
+ create_workflow_by_name
201
+ expect(mock_requestor).to have_received(:request)
202
+ .with('objects/druid:mw971zk1113/workflows/accessionWF', 'post', '',
203
+ { content_type: 'application/json',
204
+ params: { 'lane-id' => 'hamburgers', 'version' => '1' } })
205
+ end
206
+ end
207
+
208
+ context 'when context is sent' do
209
+ subject(:create_workflow_by_name) do
210
+ routes.create_workflow_by_name('druid:mw971zk1113', 'accessionWF', version: '1', lane_id: 'default', context: { foo: 'bar' })
211
+ end
212
+
213
+ it 'sends a create request with the context in the body' do
214
+ create_workflow_by_name
215
+ expect(mock_requestor).to have_received(:request)
216
+ .with('objects/druid:mw971zk1113/workflows/accessionWF', 'post', '{"context":{"foo":"bar"}}',
217
+ { content_type: 'application/json',
218
+ params: { 'lane-id' => 'default', 'version' => '1' } })
219
+ end
174
220
  end
175
221
  end
176
222
  end
@@ -225,6 +225,29 @@ RSpec.describe Dor::Workflow::Client do
225
225
  end
226
226
  end
227
227
 
228
+ describe '#all_workflows' do
229
+ let(:xml) do
230
+ <<~XML
231
+ <workflows objectId="druid:123">
232
+ <workflow repository="dor" objectId="druid:123" id="accessionWF">
233
+ <process laneId="default" lifecycle="submitted" elapsed="0.0" attempts="1" datetime="2013-02-18T15:08:10-0800" status="completed" name="start-accession"/>
234
+ </workflow>
235
+ </workflows>
236
+ XML
237
+ end
238
+ let(:stubs) do
239
+ Faraday::Adapter::Test::Stubs.new do |stub|
240
+ stub.get("/objects/#{@druid}/workflows") do |_env|
241
+ [200, {}, xml]
242
+ end
243
+ end
244
+ end
245
+
246
+ it 'returns the workflow details associated with druid' do
247
+ expect(client.all_workflows(pid: @druid).xml).to eq(xml)
248
+ end
249
+ end
250
+
228
251
  describe '#lifecycle' do
229
252
  let(:stubs) do
230
253
  Faraday::Adapter::Test::Stubs.new do |stub|
@@ -62,4 +62,32 @@ RSpec.describe Dor::Workflow::Response::Process do
62
62
 
63
63
  it { is_expected.to eq 'default' }
64
64
  end
65
+
66
+ describe '#context' do
67
+ subject { instance.context }
68
+
69
+ context 'when context exists' do
70
+ let(:xml) do
71
+ <<~XML
72
+ <workflow repository="dor" objectId="druid:mw971zk1113" id="assemblyWF">
73
+ <process name="start-assembly" laneId="default" context="{&quot;requireOCR&quot;:true}">
74
+ </workflow>
75
+ XML
76
+ end
77
+
78
+ it { is_expected.to eq({ 'requireOCR' => true }) }
79
+ end
80
+
81
+ context 'when no context exists' do
82
+ let(:xml) do
83
+ <<~XML
84
+ <workflow repository="dor" objectId="druid:mw971zk1113" id="assemblyWF">
85
+ <process name="start-assembly" laneId="default" context="">
86
+ </workflow>
87
+ XML
88
+ end
89
+
90
+ it { is_expected.to eq({}) }
91
+ end
92
+ end
65
93
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dor-workflow-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.3.0
4
+ version: 7.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Willy Mene
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-04-11 00:00:00.000000000 Z
12
+ date: 2024-05-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -120,6 +120,7 @@ files:
120
120
  - LICENSE.txt
121
121
  - README.md
122
122
  - Rakefile
123
+ - bin/console
123
124
  - dor-workflow-client.gemspec
124
125
  - lib/dor/missing_workflow_exception.rb
125
126
  - lib/dor/workflow/client.rb
@@ -168,7 +169,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
168
169
  - !ruby/object:Gem::Version
169
170
  version: '0'
170
171
  requirements: []
171
- rubygems_version: 3.5.7
172
+ rubygems_version: 3.5.9
172
173
  signing_key:
173
174
  specification_version: 4
174
175
  summary: Provides convenience methods to work with the DOR Workflow Service