dor-workflow-client 3.0.0.rc1
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 +7 -0
- data/.gitignore +21 -0
- data/.rspec +1 -0
- data/.rubocop.yml +11 -0
- data/.rubocop_todo.yml +21 -0
- data/.travis.yml +10 -0
- data/.yardopts +1 -0
- data/Gemfile +13 -0
- data/LICENSE.txt +22 -0
- data/README.md +35 -0
- data/Rakefile +16 -0
- data/bin/console +14 -0
- data/dor-workflow-client.gemspec +36 -0
- data/lib/dor/models/response/process.rb +55 -0
- data/lib/dor/models/response/update.rb +20 -0
- data/lib/dor/models/response/workflow.rb +54 -0
- data/lib/dor/workflow/client/connection_factory.rb +75 -0
- data/lib/dor/workflow/client/lifecycle_routes.rb +71 -0
- data/lib/dor/workflow/client/queues.rb +208 -0
- data/lib/dor/workflow/client/requestor.rb +48 -0
- data/lib/dor/workflow/client/version.rb +9 -0
- data/lib/dor/workflow/client/version_routes.rb +33 -0
- data/lib/dor/workflow/client/workflow_routes.rb +192 -0
- data/lib/dor/workflow/client.rb +77 -0
- data/lib/dor/workflow_exception.rb +6 -0
- data/spec/models/response/workflow_spec.rb +142 -0
- data/spec/spec_helper.rb +18 -0
- data/spec/workflow/client/connection_factory_spec.rb +25 -0
- data/spec/workflow/client/lifecycle_routes_spec.rb +27 -0
- data/spec/workflow/client/requestor_spec.rb +33 -0
- data/spec/workflow/client/workflow_routes_spec.rb +53 -0
- data/spec/workflow/client_spec.rb +633 -0
- metadata +309 -0
@@ -0,0 +1,633 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe Dor::Workflow::Client do
|
6
|
+
let(:wf_xml) do
|
7
|
+
<<-EOXML
|
8
|
+
<workflow id="etdSubmitWF">
|
9
|
+
<process name="register-object" status="completed" attempts="1" />
|
10
|
+
<process name="submit" status="waiting" />
|
11
|
+
<process name="reader-approval" status="waiting" />
|
12
|
+
<process name="registrar-approval" status="waiting" />
|
13
|
+
<process name="start-accession" status="waiting" />
|
14
|
+
</workflow>
|
15
|
+
EOXML
|
16
|
+
end
|
17
|
+
|
18
|
+
let(:wf_xml_label) do
|
19
|
+
<<~EOXML
|
20
|
+
<?xml version="1.0"?>
|
21
|
+
<workflow id="etdSubmitWF">
|
22
|
+
<process name="register-object" status="completed" attempts="1" laneId="default"/>
|
23
|
+
<process name="submit" status="waiting" laneId="default"/>
|
24
|
+
<process name="reader-approval" status="waiting" laneId="default"/>
|
25
|
+
<process name="registrar-approval" status="waiting" laneId="default"/>
|
26
|
+
<process name="start-accession" status="waiting" laneId="default"/>
|
27
|
+
</workflow>
|
28
|
+
EOXML
|
29
|
+
end
|
30
|
+
|
31
|
+
let(:stubs) do
|
32
|
+
Faraday::Adapter::Test::Stubs.new
|
33
|
+
end
|
34
|
+
|
35
|
+
let(:mock_http_connection) do
|
36
|
+
Faraday.new(url: 'http://example.com/') do |builder|
|
37
|
+
builder.use Faraday::Response::RaiseError
|
38
|
+
builder.options.params_encoder = Faraday::FlatParamsEncoder
|
39
|
+
|
40
|
+
builder.adapter :test, stubs
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
let(:mock_logger) { double('Logger', info: true, debug: true, warn: true) }
|
45
|
+
|
46
|
+
before do
|
47
|
+
@repo = 'dor'
|
48
|
+
@druid = 'druid:123'
|
49
|
+
end
|
50
|
+
|
51
|
+
let(:client) { described_class.new connection: mock_http_connection, logger: mock_logger }
|
52
|
+
|
53
|
+
describe '#connection' do
|
54
|
+
subject(:conn) { client.requestor.connection }
|
55
|
+
let(:client) { described_class.new url: 'http://example.com', timeout: 99, logger: mock_logger }
|
56
|
+
|
57
|
+
it 'has a timeout' do
|
58
|
+
expect(conn).to be_a(Faraday::Connection)
|
59
|
+
expect(conn.options.timeout).to eq(99)
|
60
|
+
expect(conn.options.open_timeout).to eq(99)
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'has a user_agent' do
|
64
|
+
expect(conn.headers).to include('User-Agent' => /dor-workflow-service \d+\.\d+\.\d+/)
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'defaults to using the flat params encoder' do
|
68
|
+
expect(conn.options.params_encoder).to eq Faraday::FlatParamsEncoder
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe '#create_workflow' do
|
73
|
+
let(:stubs) do
|
74
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
75
|
+
stub.put("#{@repo}/objects/#{@druid}/workflows/etdSubmitWF") { |_env| [201, {}, ''] }
|
76
|
+
stub.put("#{@repo}/objects/#{@druid}/workflows/noCreateDsWF?create-ds=false") { |_env| [201, {}, ''] }
|
77
|
+
stub.put("#{@repo}/objects/#{@druid}/workflows/raiseException") { |_env| raise 'broken' }
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'should pass workflow xml to the DOR workflow service and return the URL to the workflow' do
|
82
|
+
client.create_workflow(@repo, @druid, 'etdSubmitWF', wf_xml)
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'should raise on an unexpected Exception' do
|
86
|
+
expect { client.create_workflow(@repo, @druid, 'raiseException', wf_xml) }.to raise_error(Exception, 'broken')
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'sets the create-ds param to the value of the passed in options hash' do
|
90
|
+
client.create_workflow(@repo, @druid, 'noCreateDsWF', wf_xml, create_ds: false)
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'adds lane_id attributes to all steps if passed in as an option' do
|
94
|
+
skip 'test not implemented'
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe '#update_workflow_status' do
|
99
|
+
let(:stubs) do
|
100
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
101
|
+
stub.put("#{@repo}/objects/#{@druid}/workflows/etdSubmitWF/registrar-approval?current-status=queued") do |_env|
|
102
|
+
[201, {}, '{"next_steps":["submit-marc"]}']
|
103
|
+
end
|
104
|
+
|
105
|
+
stub.put("#{@repo}/objects/#{@druid}/workflows/etdSubmitWF/registrar-approval") do |env|
|
106
|
+
expect(env.body).to eq "<?xml version=\"1.0\"?>\n<process name=\"registrar-approval\" status=\"completed\" elapsed=\"0\" note=\"annotation\" version=\"2\" laneId=\"lane2\"/>\n"
|
107
|
+
[201, {}, '{"next_steps":["submit-marc"]}']
|
108
|
+
end
|
109
|
+
|
110
|
+
stub.put("#{@repo}/objects/#{@druid}/workflows/errorWF/registrar-approval") do |_env|
|
111
|
+
[400, {}, '']
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'should update workflow status and return true if successful' do
|
117
|
+
expect(client.update_workflow_status(@repo, @druid, 'etdSubmitWF', 'registrar-approval', 'completed', version: 2, note: 'annotation', lane_id: 'lane2')).to be_kind_of Dor::Workflow::Response::Update
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'should return false if the PUT to the DOR workflow service throws an exception' do
|
121
|
+
expect { client.update_workflow_status(@repo, @druid, 'errorWF', 'registrar-approval', 'completed') }.to raise_error(Dor::WorkflowException, /status 400/)
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'performs a conditional update when current-status is passed as a parameter' do
|
125
|
+
expect(mock_http_connection).to receive(:put).with("#{@repo}/objects/#{@druid}/workflows/etdSubmitWF/registrar-approval?current-status=queued").and_call_original
|
126
|
+
|
127
|
+
expect(client.update_workflow_status(@repo, @druid, 'etdSubmitWF', 'registrar-approval', 'completed', version: 2, note: 'annotation', lane_id: 'lane1', current_status: 'queued')).to be_kind_of Dor::Workflow::Response::Update
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'should throw exception if invalid status provided' do
|
131
|
+
expect { client.update_workflow_status(@repo, @druid, 'accessionWF', 'publish', 'NOT_VALID_STATUS') }.to raise_error(ArgumentError)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
describe '#update_workflow_error_status' do
|
136
|
+
let(:stubs) do
|
137
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
138
|
+
stub.put("#{@repo}/objects/#{@druid}/workflows/etdSubmitWF/reader-approval") do |env|
|
139
|
+
expect(env.body).to match(/status="error" errorMessage="Some exception" errorText="The optional stacktrace"/)
|
140
|
+
[201, {}, '']
|
141
|
+
end
|
142
|
+
|
143
|
+
stub.put("#{@repo}/objects/#{@druid}/workflows/errorWF/reader-approval") do |_env|
|
144
|
+
[400, {}, '']
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'should update workflow status to error and return true if successful' do
|
150
|
+
client.update_workflow_error_status(@repo, @druid, 'etdSubmitWF', 'reader-approval', 'Some exception', error_text: 'The optional stacktrace')
|
151
|
+
end
|
152
|
+
it 'should return false if the PUT to the DOR workflow service throws an exception' do
|
153
|
+
expect { client.update_workflow_status(@repo, @druid, 'errorWF', 'reader-approval', 'completed') }.to raise_error(Dor::WorkflowException, /status 400/)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
describe '#workflow_status' do
|
158
|
+
let(:repo) { @repo }
|
159
|
+
let(:druid) { @druid }
|
160
|
+
let(:stubs) do
|
161
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
162
|
+
stub.get("#{repo}/objects/#{druid}/workflows/#{workflow_name}") do |_env|
|
163
|
+
response
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
subject { client.workflow_status(repo, druid, workflow_name, step_name) }
|
169
|
+
let(:step_name) { 'registrar-approval' }
|
170
|
+
let(:workflow_name) { 'etdSubmitWF' }
|
171
|
+
let(:status) { 200 }
|
172
|
+
let(:response) do
|
173
|
+
[status, {}, xml]
|
174
|
+
end
|
175
|
+
let(:xml) { '' }
|
176
|
+
|
177
|
+
context 'when a single result is returned' do
|
178
|
+
let(:xml) do
|
179
|
+
'<workflow><process name="registrar-approval" status="completed" /></workflow>'
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'returns status as a string' do
|
183
|
+
expect(subject).to eq('completed')
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
context 'when a multiple versions are returned' do
|
188
|
+
let(:xml) do
|
189
|
+
'<workflow><process name="registrar-approval" version="1" status="completed" />
|
190
|
+
<process name="registrar-approval" version="2" status="waiting" /></workflow>'
|
191
|
+
end
|
192
|
+
|
193
|
+
it 'returns the status for the highest version' do
|
194
|
+
expect(subject).to eq('waiting')
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
context 'when it fails for any reason' do
|
199
|
+
let(:status) { 404 }
|
200
|
+
|
201
|
+
it 'throws an exception' do
|
202
|
+
expect { subject }.to raise_error Dor::WorkflowException
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
context 'when it cannot parse the response' do
|
207
|
+
let(:xml) do
|
208
|
+
'something not xml'
|
209
|
+
end
|
210
|
+
|
211
|
+
it 'throws an exception' do
|
212
|
+
expect { subject }.to raise_error Dor::WorkflowException, "Unable to parse response:\nsomething not xml"
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
context 'when the workflow/process combination doesnt exist' do
|
217
|
+
let(:xml) do
|
218
|
+
'<workflow><process name="registrar-approval" status="completed" /></workflow>'
|
219
|
+
end
|
220
|
+
let(:step_name) { 'publish' }
|
221
|
+
|
222
|
+
it 'returns nil' do
|
223
|
+
expect(subject).to be_nil
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
describe '#workflow_xml' do
|
229
|
+
subject(:workflow_xml) { client.workflow_xml('dor', 'druid:123', workflow) }
|
230
|
+
|
231
|
+
context 'when a workflow name is provided' do
|
232
|
+
let(:workflow) { 'etdSubmitWF' }
|
233
|
+
let(:xml) { '<workflow id="etdSubmitWF"><process name="registrar-approval" status="completed" /></workflow>' }
|
234
|
+
let(:stubs) do
|
235
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
236
|
+
stub.get('dor/objects/druid:123/workflows/etdSubmitWF') do |_env|
|
237
|
+
[200, {}, xml]
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
it 'returns the xml for a given repository, druid, and workflow' do
|
243
|
+
expect(workflow_xml).to eq(xml)
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
context 'when no workflow name is provided' do
|
248
|
+
let(:workflow) { nil }
|
249
|
+
|
250
|
+
it 'raises an error' do
|
251
|
+
expect { workflow_xml }.to raise_error ArgumentError
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
describe '#all_workflows_xml' do
|
257
|
+
subject(:all_workflows_xml) { client.all_workflows_xml('druid:123') }
|
258
|
+
|
259
|
+
let(:workflow) { 'etdSubmitWF' }
|
260
|
+
let(:xml) do
|
261
|
+
<<~XML
|
262
|
+
<workflows>
|
263
|
+
<workflow id="etdSubmitWF"><process name="registrar-approval" status="completed" /></workflow>
|
264
|
+
<workflow id="etdSubmitWF"><process name="registrar-approval" status="completed" /></workflow>
|
265
|
+
</workflows>
|
266
|
+
XML
|
267
|
+
end
|
268
|
+
let(:stubs) do
|
269
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
270
|
+
stub.get('objects/druid:123/workflows') do |_env|
|
271
|
+
[200, {}, xml]
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
it 'returns the xml for a given druid' do
|
277
|
+
expect(all_workflows_xml).to eq(xml)
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
describe '#workflows' do
|
282
|
+
let(:xml) { '<workflow id="accessionWF"><process name="publish" status="completed" /></workflow>' }
|
283
|
+
let(:stubs) do
|
284
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
285
|
+
stub.get("dor/objects/#{@druid}/workflows/") do |_env|
|
286
|
+
[200, {}, xml]
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
it 'returns the workflows associated with druid' do
|
292
|
+
expect(client.workflows(@druid)).to eq(['accessionWF'])
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
describe '#lifecycle' do
|
297
|
+
let(:stubs) do
|
298
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
299
|
+
stub.get('dor/objects/druid:123/lifecycle') do |_env|
|
300
|
+
[200, {}, <<-EOXML]
|
301
|
+
<lifecycle objectId="druid:ct011cv6501">
|
302
|
+
<milestone date="2010-04-27T11:34:17-0700">registered</milestone>
|
303
|
+
<milestone date="2010-04-29T10:12:51-0700">inprocess</milestone>
|
304
|
+
<milestone date="2010-06-15T16:08:58-0700">released</milestone>
|
305
|
+
</lifecycle>
|
306
|
+
EOXML
|
307
|
+
end
|
308
|
+
|
309
|
+
stub.get('dor/objects/druid:abc/lifecycle') do |_env|
|
310
|
+
[200, {}, <<-EOXML]
|
311
|
+
<lifecycle />
|
312
|
+
EOXML
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
it 'returns a Time object reprenting when the milestone was reached' do
|
318
|
+
expect(client.lifecycle('dor', 'druid:123', 'released').beginning_of_day).to eq(Time.parse('2010-06-15T16:08:58-0700').beginning_of_day)
|
319
|
+
end
|
320
|
+
|
321
|
+
it "returns nil if the milestone hasn't been reached yet" do
|
322
|
+
expect(client.lifecycle('dor', 'druid:abc', 'inprocess')).to be_nil
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
describe '#active_lifecycle' do
|
327
|
+
let(:stubs) do
|
328
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
329
|
+
stub.get("dor/objects/#{@druid}/lifecycle") do |_env|
|
330
|
+
[200, {}, <<-EOXML]
|
331
|
+
<lifecycle objectId="#{@druid}">
|
332
|
+
<milestone date="2010-04-27T11:34:17-0700">registered</milestone>
|
333
|
+
<milestone date="2010-04-29T10:12:51-0700">inprocess</milestone>
|
334
|
+
<milestone date="2010-06-15T16:08:58-0700">released</milestone>
|
335
|
+
</lifecycle>
|
336
|
+
EOXML
|
337
|
+
end
|
338
|
+
|
339
|
+
stub.get("dor/objects/#{@druid}/lifecycle") do |_env|
|
340
|
+
[200, {}, <<-EOXML]
|
341
|
+
<lifecycle />
|
342
|
+
EOXML
|
343
|
+
end
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
it 'parses out the active lifecycle' do
|
348
|
+
expect(client.active_lifecycle('dor', @druid, 'released').beginning_of_day).to eq(Time.parse('2010-06-15T16:08:58-0700').beginning_of_day)
|
349
|
+
end
|
350
|
+
|
351
|
+
it 'handles missing lifecycle' do
|
352
|
+
expect(client.active_lifecycle('dor', @druid, 'NOT_FOUND')).to be_nil
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
context '#objects_for_workstep' do
|
357
|
+
before(:all) do
|
358
|
+
@repository = 'dor'
|
359
|
+
@workflow = 'googleScannedBookWF'
|
360
|
+
@completed = 'google-download'
|
361
|
+
@waiting = 'process-content'
|
362
|
+
end
|
363
|
+
|
364
|
+
let(:stubs) do
|
365
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
366
|
+
stub.get("workflow_queue?waiting=#{@repository}:#{@workflow}:#{@waiting}&completed=#{@repository}:#{@workflow}:#{@completed}&lane-id=default") do |_env|
|
367
|
+
[200, {}, '<objects count="1"><object id="druid:ab123de4567"/><object id="druid:ab123de9012"/></objects>']
|
368
|
+
end
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
372
|
+
describe 'a query with one step completed and one waiting' do
|
373
|
+
it 'creates the URI string with only the one completed step' do
|
374
|
+
expect(client.objects_for_workstep(@completed, @waiting, 'default', default_repository: @repository, default_workflow: @workflow)).to eq(['druid:ab123de4567', 'druid:ab123de9012'])
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
378
|
+
describe 'a query with TWO steps completed and one waiting' do
|
379
|
+
it 'creates the URI string with the two completed steps correctly' do
|
380
|
+
second_completed = 'google-convert'
|
381
|
+
xml = %(<objects count="1"><object id="druid:ab123de4567"/><object id="druid:ab123de9012"/></objects>)
|
382
|
+
allow(mock_http_connection).to receive(:get).with("workflow_queue?waiting=#{@repository}:#{@workflow}:#{@waiting}&completed=#{@repository}:#{@workflow}:#{@completed}&completed=#{@repository}:#{@workflow}:#{second_completed}&lane-id=default").and_return(double(Faraday::Response, body: xml))
|
383
|
+
expect(client.objects_for_workstep([@completed, second_completed], @waiting, 'default', default_repository: @repository, default_workflow: @workflow)).to eq(['druid:ab123de4567', 'druid:ab123de9012'])
|
384
|
+
end
|
385
|
+
end
|
386
|
+
|
387
|
+
context 'a query using qualified workflow names for completed and waiting' do
|
388
|
+
before :each do
|
389
|
+
@qualified_waiting = "#{@repository}:#{@workflow}:#{@waiting}"
|
390
|
+
@qualified_completed = "#{@repository}:#{@workflow}:#{@completed}"
|
391
|
+
end
|
392
|
+
|
393
|
+
RSpec.shared_examples 'lane-aware' do
|
394
|
+
it 'creates the URI string with the two completed steps across repositories correctly' do
|
395
|
+
qualified_completed2 = 'sdr:sdrIngestWF:complete-deposit'
|
396
|
+
qualified_completed3 = 'sdr:sdrIngestWF:ingest-transfer'
|
397
|
+
xml = %(<objects count="2"><object id="druid:ab123de4567"/><object id="druid:ab123de9012"/></objects>)
|
398
|
+
allow(mock_http_connection).to receive(:get).with("workflow_queue?waiting=#{@qualified_waiting}&completed=#{@qualified_completed}&completed=#{qualified_completed2}&completed=#{qualified_completed3}&lane-id=#{laneid}").and_return(double(Faraday::Response, body: xml))
|
399
|
+
args = [[@qualified_completed, qualified_completed2, qualified_completed3], @qualified_waiting]
|
400
|
+
args << laneid if laneid != 'default'
|
401
|
+
expect(client.objects_for_workstep(*args)).to eq(['druid:ab123de4567', 'druid:ab123de9012'])
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|
405
|
+
describe 'default lane_id' do
|
406
|
+
it_behaves_like 'lane-aware' do
|
407
|
+
let(:laneid) { 'default' }
|
408
|
+
end
|
409
|
+
end
|
410
|
+
describe 'explicit lane_id' do
|
411
|
+
it_behaves_like 'lane-aware' do
|
412
|
+
let(:laneid) { 'lane1' }
|
413
|
+
end
|
414
|
+
end
|
415
|
+
|
416
|
+
context 'URI string creation' do
|
417
|
+
before :each do
|
418
|
+
@xml = %(<objects count="1"><object id="druid:ab123de4567"/></objects>)
|
419
|
+
end
|
420
|
+
it 'with only one completed step passed in as a String' do
|
421
|
+
allow(mock_http_connection).to receive(:get).with("workflow_queue?waiting=#{@qualified_waiting}&completed=#{@qualified_completed}&lane-id=default").and_return(double(Faraday::Response, body: @xml))
|
422
|
+
expect(client.objects_for_workstep(@qualified_completed, @qualified_waiting)).to eq(['druid:ab123de4567'])
|
423
|
+
end
|
424
|
+
it 'without any completed steps, only waiting' do
|
425
|
+
allow(mock_http_connection).to receive(:get).with("workflow_queue?waiting=#{@qualified_waiting}&lane-id=default").and_return(double(Faraday::Response, body: @xml))
|
426
|
+
expect(client.objects_for_workstep(nil, @qualified_waiting)).to eq(['druid:ab123de4567'])
|
427
|
+
end
|
428
|
+
it 'same but with lane_id' do
|
429
|
+
allow(mock_http_connection).to receive(:get).with("workflow_queue?waiting=#{@qualified_waiting}&lane-id=lane1").and_return(double(Faraday::Response, body: @xml))
|
430
|
+
expect(client.objects_for_workstep(nil, @qualified_waiting, 'lane1')).to eq(['druid:ab123de4567'])
|
431
|
+
end
|
432
|
+
end
|
433
|
+
end
|
434
|
+
end
|
435
|
+
|
436
|
+
context 'get empty workflow queue' do
|
437
|
+
before(:all) do
|
438
|
+
@repository = 'dor'
|
439
|
+
@workflow = 'googleScannedBookWF'
|
440
|
+
@completed = 'google-download'
|
441
|
+
@waiting = 'process-content'
|
442
|
+
end
|
443
|
+
|
444
|
+
let(:stubs) do
|
445
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
446
|
+
stub.get("workflow_queue?waiting=#{@repository}:#{@workflow}:#{@waiting}&completed=#{@repository}:#{@workflow}:#{@completed}&lane-id=default") do |_env|
|
447
|
+
[200, {}, '<objects count="0"/>']
|
448
|
+
end
|
449
|
+
end
|
450
|
+
end
|
451
|
+
|
452
|
+
it 'returns an empty list if it encounters an empty workflow queue' do
|
453
|
+
expect(client.objects_for_workstep(@completed, @waiting, 'default', default_repository: @repository, default_workflow: @workflow)).to eq([])
|
454
|
+
end
|
455
|
+
end
|
456
|
+
|
457
|
+
context 'get errored workflow steps' do
|
458
|
+
before(:all) do
|
459
|
+
@repository = 'dor'
|
460
|
+
@workflow = 'accessionWF'
|
461
|
+
@step = 'publish'
|
462
|
+
end
|
463
|
+
|
464
|
+
let(:stubs) do
|
465
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
466
|
+
stub.get("/workflow_queue?error=#{@step}&repository=#{@repository}&workflow=#{@workflow}") do |_env|
|
467
|
+
[200, {}, <<-EOXML]
|
468
|
+
<objects count="1">
|
469
|
+
<object id="druid:ab123cd4567" errorMessage="This is an error message"/>
|
470
|
+
</objects>
|
471
|
+
EOXML
|
472
|
+
end
|
473
|
+
end
|
474
|
+
end
|
475
|
+
|
476
|
+
describe 'errored_objects_for_workstep' do
|
477
|
+
it 'returns error messages for errored objects' do
|
478
|
+
expect(client.errored_objects_for_workstep(@workflow, @step, @repository)).to eq('druid:ab123cd4567' => 'This is an error message')
|
479
|
+
end
|
480
|
+
end
|
481
|
+
|
482
|
+
describe 'count_errored_for_workstep' do
|
483
|
+
it 'counts how many steps are errored out' do
|
484
|
+
expect(client.count_errored_for_workstep(@workflow, @step, @repository)).to eq(1)
|
485
|
+
end
|
486
|
+
end
|
487
|
+
end
|
488
|
+
|
489
|
+
describe '#count_queued_for_workstep' do
|
490
|
+
before(:all) do
|
491
|
+
@repository = 'dor'
|
492
|
+
@workflow = 'accessionWF'
|
493
|
+
@step = 'publish'
|
494
|
+
end
|
495
|
+
|
496
|
+
let(:stubs) do
|
497
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
498
|
+
stub.get("/workflow_queue?queued=#{@step}&repository=#{@repository}&workflow=#{@workflow}") do |_env|
|
499
|
+
[200, {}, <<-EOXML]
|
500
|
+
<objects count="1">
|
501
|
+
<object id="druid:ab123cd4567"/>
|
502
|
+
</objects>
|
503
|
+
EOXML
|
504
|
+
end
|
505
|
+
end
|
506
|
+
end
|
507
|
+
|
508
|
+
it 'counts how many steps are errored out' do
|
509
|
+
expect(client.count_queued_for_workstep(@workflow, @step, @repository)).to eq(1)
|
510
|
+
end
|
511
|
+
end
|
512
|
+
|
513
|
+
describe '#count_objects_in_step' do
|
514
|
+
before(:all) do
|
515
|
+
@workflow = 'sdrIngestWF'
|
516
|
+
@step = 'start-ingest'
|
517
|
+
@type = 'waiting'
|
518
|
+
@repository = 'sdr'
|
519
|
+
end
|
520
|
+
|
521
|
+
let(:stubs) do
|
522
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
523
|
+
stub.get("/workflow_queue?repository=#{@repository}&workflow=#{@workflow}&#{@type}=#{@step}") do |_env|
|
524
|
+
[200, {}, <<-EOXML]
|
525
|
+
<objects count="1">
|
526
|
+
<object id="druid:oo000ra0001" url="null/fedora/objects/druid:oo000ra0001"/>
|
527
|
+
</objects>
|
528
|
+
EOXML
|
529
|
+
end
|
530
|
+
end
|
531
|
+
end
|
532
|
+
|
533
|
+
it 'counts how many objects are at the type of step' do
|
534
|
+
expect(client.count_objects_in_step(@workflow, @step, @type, @repository)).to eq(1)
|
535
|
+
end
|
536
|
+
end
|
537
|
+
|
538
|
+
describe '#delete_workflow' do
|
539
|
+
let(:url) { "#{@repo}/objects/#{@druid}/workflows/accessionWF" }
|
540
|
+
|
541
|
+
let(:stubs) do
|
542
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
543
|
+
stub.delete(url) { |_env| [202, {}, ''] }
|
544
|
+
end
|
545
|
+
end
|
546
|
+
|
547
|
+
it 'sends a delete request to the workflow service' do
|
548
|
+
expect(mock_http_connection).to receive(:delete).with(url).and_call_original
|
549
|
+
client.delete_workflow(@repo, @druid, 'accessionWF')
|
550
|
+
end
|
551
|
+
end
|
552
|
+
|
553
|
+
describe '#close_version' do
|
554
|
+
let(:stubs) do
|
555
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
556
|
+
stub.post('dor/objects/druid:123/versionClose?create-accession=false') do |_env|
|
557
|
+
[202, {}, '']
|
558
|
+
end
|
559
|
+
|
560
|
+
stub.post('dor/objects/druid:123/versionClose') do |_env|
|
561
|
+
[202, {}, '']
|
562
|
+
end
|
563
|
+
end
|
564
|
+
end
|
565
|
+
|
566
|
+
let(:url) { 'dor/objects/druid:123/versionClose' }
|
567
|
+
it 'calls the versionClose endpoint with druid' do
|
568
|
+
client.close_version(@repo, @druid)
|
569
|
+
end
|
570
|
+
|
571
|
+
it 'optionally prevents creation of accessionWF' do
|
572
|
+
expect(mock_http_connection).to receive(:post).with('dor/objects/druid:123/versionClose?create-accession=false').and_call_original
|
573
|
+
client.close_version(@repo, @druid, false)
|
574
|
+
end
|
575
|
+
end
|
576
|
+
|
577
|
+
describe '.stale_queued_workflows' do
|
578
|
+
let(:stubs) do
|
579
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
580
|
+
stub.get('workflow_queue/all_queued?repository=dor&hours-ago=24&limit=100') do |_env|
|
581
|
+
[200, {}, <<-XML]
|
582
|
+
<workflows>
|
583
|
+
<workflow laneId="lane1" note="annotation" lifecycle="in-process" errorText="stacktrace" errorMessage="NullPointerException" elapsed="1.173" repository="dor" attempts="0" datetime="2008-11-15T13:30:00-0800" status="waiting" process="content-metadata" name="accessionWF" druid="dr:123"/>
|
584
|
+
<workflow laneId="lane2" note="annotation" lifecycle="in-process" errorText="stacktrace" errorMessage="NullPointerException" elapsed="1.173" repository="dor" attempts="0" datetime="2008-11-15T13:30:00-0800" status="waiting" process="jp2-create" name="assemblyWF" druid="dr:456"/>
|
585
|
+
</workflows>
|
586
|
+
XML
|
587
|
+
end
|
588
|
+
end
|
589
|
+
end
|
590
|
+
|
591
|
+
it 'returns an Array of Hashes containing each workflow step' do
|
592
|
+
ah = client.stale_queued_workflows 'dor', hours_ago: 24, limit: 100
|
593
|
+
expected = [
|
594
|
+
{ workflow: 'accessionWF', step: 'content-metadata', druid: 'dr:123', lane_id: 'lane1' },
|
595
|
+
{ workflow: 'assemblyWF', step: 'jp2-create', druid: 'dr:456', lane_id: 'lane2' }
|
596
|
+
]
|
597
|
+
expect(ah).to eql(expected)
|
598
|
+
end
|
599
|
+
end
|
600
|
+
|
601
|
+
describe '.count_stale_queued_workflows' do
|
602
|
+
let(:stubs) do
|
603
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
604
|
+
stub.get('workflow_queue/all_queued?repository=dor&hours-ago=48&count-only=true') do |_env|
|
605
|
+
[200, {}, '<objects count="10"/>']
|
606
|
+
end
|
607
|
+
end
|
608
|
+
end
|
609
|
+
|
610
|
+
it 'returns the number of queued workflow steps' do
|
611
|
+
expect(client.count_stale_queued_workflows('dor', hours_ago: 48)).to eq(10)
|
612
|
+
end
|
613
|
+
end
|
614
|
+
|
615
|
+
describe '.lane_ids' do
|
616
|
+
let(:stubs) do
|
617
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
618
|
+
stub.get('workflow_queue/lane_ids?lane_ids?step=dor:accessionWF:shelve') do |_env|
|
619
|
+
[200, {}, <<-XML]
|
620
|
+
<lanes>
|
621
|
+
<lane id="lane1"/>
|
622
|
+
<lane id="lane2"/>
|
623
|
+
</lanes>
|
624
|
+
XML
|
625
|
+
end
|
626
|
+
end
|
627
|
+
end
|
628
|
+
|
629
|
+
it 'returns the lane ids for a given workflow step' do
|
630
|
+
expect(client.lane_ids('dor', 'accessionWF', 'shelve')).to eq(%w[lane1 lane2])
|
631
|
+
end
|
632
|
+
end
|
633
|
+
end
|