dor-workflow-service 1.8.0 → 2.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 +4 -4
- data/dor-workflow-service.gemspec +1 -1
- data/lib/dor/services/workflow_service.rb +63 -37
- data/lib/dor/workflow_exception.rb +4 -0
- data/lib/dor/workflow_version.rb +1 -1
- data/spec/spec_helper.rb +5 -1
- data/spec/workflow_service_spec.rb +331 -117
- metadata +19 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6cdb8d9e4d0b767532df5ea3f4c8e090b2120353
|
4
|
+
data.tar.gz: 0bbd9f050f133cd1f2c924832bc4f2f390150398
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 31e2c9ccbd940d6e1335797e68fb173a564fb70d8684b23135d58090552ba4a8f617da7e3492fdad44572022f7ac7a78b43ca73b01d80c036c8a3cd5e12ad291
|
7
|
+
data.tar.gz: ce17ca0ce0d966e5076e19d3d92b6ca38d082c6d5891bf4b123e05e39a3bb1b8b2085617a30002b101465f1c180df8017c939f2b26a0b5c3f6682daafdb64259
|
@@ -19,7 +19,6 @@ Gem::Specification.new do |gem|
|
|
19
19
|
|
20
20
|
gem.add_dependency 'activesupport', '>= 3.2.1', '< 5'
|
21
21
|
gem.add_dependency 'nokogiri', '~> 1.6.0'
|
22
|
-
gem.add_dependency 'rest-client', '~> 1.7'
|
23
22
|
gem.add_dependency 'retries'
|
24
23
|
gem.add_dependency 'confstruct', '>= 0.2.7', '< 2'
|
25
24
|
gem.add_dependency 'faraday', '~> 0.9.2'
|
@@ -30,4 +29,5 @@ Gem::Specification.new do |gem|
|
|
30
29
|
gem.add_development_dependency 'yard'
|
31
30
|
gem.add_development_dependency 'redcarpet'
|
32
31
|
gem.add_development_dependency 'equivalent-xml', '~> 0.5.1'
|
32
|
+
gem.add_development_dependency 'simplecov'
|
33
33
|
end
|
@@ -1,10 +1,9 @@
|
|
1
|
-
require 'rest-client'
|
2
1
|
require 'active_support'
|
3
2
|
require 'active_support/core_ext'
|
4
3
|
require 'nokogiri'
|
5
4
|
require 'retries'
|
6
5
|
require 'faraday'
|
7
|
-
require '
|
6
|
+
require 'dor/workflow_exception'
|
8
7
|
|
9
8
|
module Dor
|
10
9
|
|
@@ -13,7 +12,7 @@ module Dor
|
|
13
12
|
# TODO: create normal initalize method, deprecate configure
|
14
13
|
# TODO: hardcoded 'true' returns are dumb, instead return the response object where possible
|
15
14
|
# TODO: VALID_STATUS should be just another attribute w/ default
|
16
|
-
# TODO: allow constructor/initalizer to receive
|
15
|
+
# TODO: allow constructor/initalizer to receive Faraday object(s), not just URLs (solves SSL/proxy config problem)
|
17
16
|
# TODO: allow constructor/initalizer to receive logger
|
18
17
|
|
19
18
|
# Create and update workflows
|
@@ -46,7 +45,7 @@ module Dor
|
|
46
45
|
def create_workflow(repo, druid, workflow_name, wf_xml, opts = {:create_ds => true})
|
47
46
|
lane_id = opts.fetch(:lane_id, 'default')
|
48
47
|
xml = add_lane_id_to_workflow_xml(lane_id, wf_xml)
|
49
|
-
workflow_resource_method "#{repo}/objects/#{druid}/workflows/#{workflow_name}", 'put', xml,
|
48
|
+
status = workflow_resource_method "#{repo}/objects/#{druid}/workflows/#{workflow_name}", 'put', xml,
|
50
49
|
{
|
51
50
|
:content_type => 'application/xml',
|
52
51
|
:params => { 'create-ds' => opts[:create_ds] }
|
@@ -97,7 +96,7 @@ module Dor
|
|
97
96
|
def get_workflow_status(repo, druid, workflow, process)
|
98
97
|
workflow_md = get_workflow_xml(repo, druid, workflow)
|
99
98
|
doc = Nokogiri::XML(workflow_md)
|
100
|
-
raise
|
99
|
+
raise Dor::WorkflowException.new("Unable to parse response:\n#{workflow_md}") if doc.root.nil?
|
101
100
|
status = doc.root.at_xpath("//process[@name='#{process}']/@status")
|
102
101
|
status = status.content if status
|
103
102
|
status
|
@@ -280,7 +279,6 @@ module Dor
|
|
280
279
|
uri_string << "&limit=#{options[:limit].to_i}" if options[:limit] && options[:limit].to_i > 0
|
281
280
|
uri_string << "&lane-id=#{lane_id}"
|
282
281
|
|
283
|
-
workflow_resource.options[:timeout] = 5 * 60 unless workflow_resource.options.include?(:timeout)
|
284
282
|
resp = workflow_resource_method uri_string
|
285
283
|
#
|
286
284
|
# response looks like:
|
@@ -324,7 +322,7 @@ module Dor
|
|
324
322
|
#
|
325
323
|
# @return [Integer] Number of objects with this repository:workflow:step that have a status of 'error'
|
326
324
|
def count_errored_for_workstep(workflow, step, repository = 'dor')
|
327
|
-
count_objects_in_step(workflow, step,
|
325
|
+
count_objects_in_step(workflow, step, 'error', repository)
|
328
326
|
end
|
329
327
|
|
330
328
|
# Returns the number of objects that have a status of 'queued' in a particular workflow and step
|
@@ -335,7 +333,17 @@ module Dor
|
|
335
333
|
#
|
336
334
|
# @return [Integer] Number of objects with this repository:workflow:step that have a status of 'queued'
|
337
335
|
def count_queued_for_workstep(workflow, step, repository = 'dor')
|
338
|
-
count_objects_in_step(workflow, step,
|
336
|
+
count_objects_in_step(workflow, step, 'queued', repository)
|
337
|
+
end
|
338
|
+
|
339
|
+
##
|
340
|
+
# Returns the number of objects that have completed a particular workflow
|
341
|
+
# @param [String] workflow name
|
342
|
+
# @param [String] repository -- optional, default=dor
|
343
|
+
# @return [Integer] Number of objects with this repository:workflow that have been archived
|
344
|
+
def count_archived_for_workflow(workflow, repository = 'dor')
|
345
|
+
resp = workflow_resource_method "workflow_archive?repository=#{repository}&workflow=#{workflow}&count-only=true"
|
346
|
+
extract_object_count(resp)
|
339
347
|
end
|
340
348
|
|
341
349
|
# Gets all of the workflow steps that have a status of 'queued' that have a last-updated timestamp older than the number of hours passed in
|
@@ -395,10 +403,9 @@ module Dor
|
|
395
403
|
# @param [String] druid The id of the object to delete the workflow from
|
396
404
|
def archive_workflow(repo, druid, wf_name, version_num = nil)
|
397
405
|
raise 'Please call Dor::WorkflowService.configure(workflow_service_url, :dor_services_url => DOR_SERVIES_URL) once before archiving workflow' if @@dor_services_url.nil?
|
398
|
-
dor_services = RestClient::Resource.new(@@dor_services_url)
|
399
406
|
url = "/v1/objects/#{druid}/workflows/#{wf_name}/archive"
|
400
407
|
url << "/#{version_num}" if version_num
|
401
|
-
|
408
|
+
workflow_resource_method(url, 'post', '')
|
402
409
|
end
|
403
410
|
|
404
411
|
# Calls the versionClose endpoint of the WorkflowService:
|
@@ -430,10 +437,16 @@ module Dor
|
|
430
437
|
end
|
431
438
|
|
432
439
|
### MIMICKING ATTRIBUTE READER
|
433
|
-
# @return [
|
440
|
+
# @return [Faraday::Connection] the REST client resource created during configure()
|
434
441
|
def workflow_resource
|
435
|
-
raise 'Please call Dor::WorkflowService.configure(url) once before calling any WorkflowService methods' if @@
|
436
|
-
@@
|
442
|
+
raise 'Please call Dor::WorkflowService.configure(url) once before calling any WorkflowService methods' if @@http_conn.nil?
|
443
|
+
@@http_conn
|
444
|
+
end
|
445
|
+
|
446
|
+
##
|
447
|
+
# Get the configured URL for the connection
|
448
|
+
def base_url
|
449
|
+
workflow_resource.url_prefix
|
437
450
|
end
|
438
451
|
|
439
452
|
# Among other things, a distinct method helps tests mock default logger
|
@@ -445,7 +458,7 @@ module Dor
|
|
445
458
|
end
|
446
459
|
|
447
460
|
def workflow_service_exceptions_to_catch
|
448
|
-
[
|
461
|
+
[Faraday::Error]
|
449
462
|
end
|
450
463
|
|
451
464
|
# Configure the workflow service
|
@@ -454,14 +467,12 @@ module Dor
|
|
454
467
|
# @param [Hash] opts optional params
|
455
468
|
# @option opts [Logger] :logger defaults writing to workflow_service.log with weekly rotation
|
456
469
|
# @option opts [String] :dor_services_url uri to the DOR REST service
|
457
|
-
# @option opts [Integer] :timeout number of seconds for
|
470
|
+
# @option opts [Integer] :timeout number of seconds for HTTP timeout
|
458
471
|
# @option opts [String] :client_cert_file path to an SSL client certificate (deprecated)
|
459
472
|
# @option opts [String] :client_key_file path to an SSL key file (deprecated)
|
460
473
|
# @option opts [String] :client_key_pass password for the key file (deprecated)
|
461
|
-
# @return [
|
462
|
-
def configure(
|
463
|
-
params = {}
|
464
|
-
params[:timeout] = opts[:timeout] if opts[:timeout]
|
474
|
+
# @return [Faraday::Connection] the REST client resource
|
475
|
+
def configure(url_or_connection, opts = {})
|
465
476
|
@@logger = opts[:logger] || default_logger
|
466
477
|
@@dor_services_url = opts[:dor_services_url] if opts[:dor_services_url]
|
467
478
|
# params[:ssl_client_cert] = OpenSSL::X509::Certificate.new(File.read(opts[:client_cert_file])) if opts[:client_cert_file]
|
@@ -469,11 +480,20 @@ module Dor
|
|
469
480
|
@@handler = Proc.new do |exception, attempt_number, total_delay|
|
470
481
|
@@logger.warn "[Attempt #{attempt_number}] #{exception.class}: #{exception.message}; #{total_delay} seconds elapsed."
|
471
482
|
end
|
472
|
-
@@
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
483
|
+
@@http_conn = case url_or_connection
|
484
|
+
when String
|
485
|
+
Faraday.new(url: url_or_connection) do |faraday|
|
486
|
+
faraday.response :logger if opts[:debug] # logs to STDOUT
|
487
|
+
faraday.adapter :net_http_persistent # use Keep-Alive connections
|
488
|
+
faraday.use Faraday::Response::RaiseError
|
489
|
+
if opts.key? :timeout
|
490
|
+
faraday.options.timeout = opts[:timeout]
|
491
|
+
faraday.options.open_timeout = opts[:timeout]
|
492
|
+
end
|
493
|
+
end
|
494
|
+
else
|
495
|
+
url_or_connection
|
496
|
+
end
|
477
497
|
end
|
478
498
|
|
479
499
|
|
@@ -511,8 +531,12 @@ module Dor
|
|
511
531
|
|
512
532
|
def count_objects_in_step(workflow, step, type, repo)
|
513
533
|
resp = workflow_resource_method "workflow_queue?repository=#{repo}&workflow=#{workflow}&#{type}=#{step}"
|
534
|
+
extract_object_count(resp)
|
535
|
+
end
|
536
|
+
|
537
|
+
def extract_object_count(resp)
|
514
538
|
node = Nokogiri::XML(resp).at_xpath('/objects')
|
515
|
-
raise 'Unable to determine count from response' if node.nil?
|
539
|
+
raise Dor::WorkflowException.new('Unable to determine count from response') if node.nil?
|
516
540
|
node['count'].to_i
|
517
541
|
end
|
518
542
|
|
@@ -525,21 +549,23 @@ module Dor
|
|
525
549
|
# @return [Object] response from method
|
526
550
|
def workflow_resource_method(uri_string, meth = 'get', payload = '', opts = {})
|
527
551
|
with_retries(:max_tries => 2, :handler => @@handler, :rescue => workflow_service_exceptions_to_catch) do |attempt|
|
528
|
-
@@logger.info "[Attempt #{attempt}] #{meth} #{
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
workflow_resource[uri_string].send(meth, payload)
|
537
|
-
else
|
538
|
-
workflow_resource[uri_string].send(meth, payload, opts)
|
552
|
+
@@logger.info "[Attempt #{attempt}] #{meth} #{base_url}/#{uri_string}"
|
553
|
+
|
554
|
+
response = workflow_resource.send(meth, uri_string) do |req|
|
555
|
+
req.body = payload unless meth == 'delete'
|
556
|
+
|
557
|
+
req.params.update opts[:params] if opts[:params]
|
558
|
+
|
559
|
+
req.headers.update opts.except(:params)
|
539
560
|
end
|
561
|
+
|
562
|
+
response.body
|
540
563
|
end
|
564
|
+
rescue *workflow_service_exceptions_to_catch => e
|
565
|
+
msg = "Failed to retrieve resource: #{meth} #{base_url}/#{uri_string}"
|
566
|
+
msg += " (HTTP status #{e.response[:status]})" if e.respond_to?(:response) && e.response
|
567
|
+
raise Dor::WorkflowException, msg
|
541
568
|
end
|
542
|
-
|
543
569
|
end
|
544
570
|
end
|
545
571
|
end
|
data/lib/dor/workflow_version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1,10 +1,14 @@
|
|
1
1
|
lib = File.expand_path('../lib', __FILE__)
|
2
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
3
|
|
4
|
+
require 'simplecov'
|
5
|
+
SimpleCov.start do
|
6
|
+
add_filter 'spec'
|
7
|
+
end
|
8
|
+
|
4
9
|
require 'dor-workflow-service'
|
5
10
|
require 'equivalent-xml'
|
6
11
|
require 'equivalent-xml/rspec_matchers'
|
7
12
|
|
8
13
|
# RSpec.configure do |conf|
|
9
14
|
# end
|
10
|
-
|
@@ -24,50 +24,65 @@ describe Dor::WorkflowService do
|
|
24
24
|
EOXML
|
25
25
|
}
|
26
26
|
|
27
|
+
let(:stubs) do
|
28
|
+
Faraday::Adapter::Test::Stubs.new
|
29
|
+
end
|
30
|
+
|
31
|
+
let(:mock_http_connection) do
|
32
|
+
Faraday.new(url: 'http://example.com/') do |builder|
|
33
|
+
builder.use Faraday::Response::RaiseError
|
34
|
+
|
35
|
+
builder.adapter :test, stubs
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
27
39
|
before(:each) do
|
28
40
|
@repo = 'dor'
|
29
41
|
@druid = 'druid:123'
|
30
|
-
@mock_resource = double('mock_rest_client_resource')
|
31
|
-
@mock_http_connection = double('mock_http_connection')
|
32
42
|
@mock_logger = double('Logger')
|
33
43
|
|
34
44
|
allow(@mock_logger).to receive(:info) # silence log output
|
35
45
|
allow(@mock_logger).to receive(:debug) # silence log output
|
46
|
+
allow(@mock_logger).to receive(:warn) # silence log output
|
36
47
|
allow(Dor::WorkflowService).to receive(:default_logger).and_return(@mock_logger)
|
37
48
|
|
38
|
-
|
39
|
-
|
40
|
-
allow(@mock_resource).to receive(:url).and_return( 'https://localhost/workflow' )
|
41
|
-
|
42
|
-
allow(Faraday).to receive(:new).and_return(@mock_http_connection)
|
49
|
+
Dor::WorkflowService.configure mock_http_connection
|
50
|
+
end
|
43
51
|
|
44
|
-
|
45
|
-
|
52
|
+
describe '#configure' do
|
53
|
+
it 'should handle a string and timeout' do
|
54
|
+
conn = Dor::WorkflowService.configure 'http://externalhost/', :timeout => 99
|
55
|
+
expect(conn).to be_a(Faraday::Connection)
|
56
|
+
expect(conn.options.timeout).to eq(99)
|
57
|
+
expect(conn.options.open_timeout).to eq(99)
|
58
|
+
end
|
46
59
|
end
|
47
60
|
|
48
61
|
describe '#create_workflow' do
|
62
|
+
let(:stubs) do
|
63
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
64
|
+
stub.put("#{@repo}/objects/#{@druid}/workflows/etdSubmitWF") { |env| [201, {}, ''] }
|
65
|
+
stub.put("#{@repo}/objects/#{@druid}/workflows/noCreateDsWF?create-ds=false") { |env| [201, {}, ''] }
|
66
|
+
stub.put("#{@repo}/objects/#{@druid}/workflows/httpException") { |env| [418, {}, "I'm A Teapot"] }
|
67
|
+
stub.put("#{@repo}/objects/#{@druid}/workflows/raiseException") { |env| raise 'broken' }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
49
71
|
it 'should pass workflow xml to the DOR workflow service and return the URL to the workflow' do
|
50
|
-
expect(@mock_resource).to receive(:put).with(wf_xml_label, anything).and_return('')
|
51
72
|
Dor::WorkflowService.create_workflow(@repo, @druid, 'etdSubmitWF', wf_xml)
|
52
73
|
end
|
53
74
|
|
54
|
-
it 'should log an error and retry upon a targetted
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
raise Exception.new('Something Else Happened') if runs == 2
|
62
|
-
}
|
63
|
-
expect(@mock_logger).to receive(:warn).with(/\[Attempt 1\] RestClient::Exception: #{ex.message}/)
|
64
|
-
expect{ Dor::WorkflowService.create_workflow(@repo, @druid, 'etdSubmitWF', wf_xml) }.to raise_error(Exception, 'Something Else Happened')
|
75
|
+
it 'should log an error and retry upon a targetted Faraday exception' do
|
76
|
+
expect(@mock_logger).to receive(:warn).with(/\[Attempt 1\] Faraday::ClientError: the server responded with status 418/)
|
77
|
+
expect { Dor::WorkflowService.create_workflow(@repo, @druid, 'httpException', wf_xml) }.to raise_error Dor::WorkflowException
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'should raise on an unexpected Exception' do
|
81
|
+
expect{ Dor::WorkflowService.create_workflow(@repo, @druid, 'raiseException', wf_xml) }.to raise_error(Exception, 'broken')
|
65
82
|
end
|
66
83
|
|
67
84
|
it 'sets the create-ds param to the value of the passed in options hash' do
|
68
|
-
|
69
|
-
:params => {'create-ds' => false}).and_return('')
|
70
|
-
Dor::WorkflowService.create_workflow(@repo, @druid, 'etdSubmitWF', wf_xml, :create_ds => false)
|
85
|
+
Dor::WorkflowService.create_workflow(@repo, @druid, 'noCreateDsWF', wf_xml, :create_ds => false)
|
71
86
|
end
|
72
87
|
|
73
88
|
it 'adds lane_id attributes to all steps if passed in as an option' do
|
@@ -91,102 +106,207 @@ describe Dor::WorkflowService do
|
|
91
106
|
end
|
92
107
|
|
93
108
|
describe '#update_workflow_status' do
|
94
|
-
|
95
|
-
|
109
|
+
let(:stubs) do
|
110
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
111
|
+
stub.put("#{@repo}/objects/#{@druid}/workflows/etdSubmitWF/reader-approval?current-status=queued") do |env|
|
112
|
+
[201, {}, '']
|
113
|
+
end
|
114
|
+
|
115
|
+
stub.put("#{@repo}/objects/#{@druid}/workflows/etdSubmitWF/reader-approval") do |env|
|
116
|
+
expect(env.body).to eq "<?xml version=\"1.0\"?>\n<process name=\"reader-approval\" status=\"completed\" elapsed=\"0\" note=\"annotation\" version=\"2\" laneId=\"lane2\"/>\n"
|
117
|
+
[201, {}, '']
|
118
|
+
end
|
119
|
+
|
120
|
+
stub.put("#{@repo}/objects/#{@druid}/workflows/errorWF/reader-approval") do |env|
|
121
|
+
[400, {}, '']
|
122
|
+
end
|
123
|
+
end
|
96
124
|
end
|
97
125
|
|
98
126
|
it 'should update workflow status and return true if successful' do
|
99
|
-
built_xml = "<?xml version=\"1.0\"?>\n<process name=\"reader-approval\" status=\"completed\" elapsed=\"0\" note=\"annotation\" version=\"2\" laneId=\"lane2\"/>\n"
|
100
|
-
expect(@mock_resource).to receive(:put).with(built_xml, { :content_type => 'application/xml' }).and_return('')
|
101
127
|
expect(Dor::WorkflowService.update_workflow_status(@repo, @druid, 'etdSubmitWF', 'reader-approval', 'completed', :version => 2, :note => 'annotation', :lane_id => 'lane2')).to be true
|
102
128
|
end
|
103
129
|
|
104
130
|
it 'should return false if the PUT to the DOR workflow service throws an exception' do
|
105
|
-
|
106
|
-
expect(@mock_resource).to receive(:put).with(@xml_re, { :content_type => 'application/xml' }).and_raise(ex)
|
107
|
-
expect{ Dor::WorkflowService.update_workflow_status(@repo, @druid, 'etdSubmitWF', 'reader-approval', 'completed') }.to raise_error(Exception, 'exception thrown')
|
131
|
+
expect{ Dor::WorkflowService.update_workflow_status(@repo, @druid, 'errorWF', 'reader-approval', 'completed') }.to raise_error(Dor::WorkflowException, /status 400/)
|
108
132
|
end
|
109
133
|
|
110
134
|
it 'performs a conditional update when current-status is passed as a parameter' do
|
111
|
-
expect(
|
112
|
-
|
135
|
+
expect(mock_http_connection).to receive(:put).with("#{@repo}/objects/#{@druid}/workflows/etdSubmitWF/reader-approval?current-status=queued").and_call_original
|
136
|
+
|
113
137
|
expect(Dor::WorkflowService.update_workflow_status(@repo, @druid, 'etdSubmitWF', 'reader-approval', 'completed', :version => 2, :note => 'annotation', :lane_id => 'lane1', :current_status => 'queued')).to be true
|
114
138
|
end
|
139
|
+
|
140
|
+
it 'should throw exception if invalid status provided' do
|
141
|
+
expect { Dor::WorkflowService.update_workflow_status(@repo, @druid, 'accessionWF', 'publish', 'NOT_VALID_STATUS') }.to raise_error(ArgumentError)
|
142
|
+
end
|
115
143
|
end
|
116
144
|
|
117
145
|
describe '#update_workflow_error_status' do
|
146
|
+
let(:stubs) do
|
147
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
148
|
+
stub.put("#{@repo}/objects/#{@druid}/workflows/etdSubmitWF/reader-approval") do |env|
|
149
|
+
expect(env.body).to match /status="error" errorMessage="Some exception" errorText="The optional stacktrace"/
|
150
|
+
[201, {}, '']
|
151
|
+
end
|
152
|
+
|
153
|
+
stub.put("#{@repo}/objects/#{@druid}/workflows/errorWF/reader-approval") do |env|
|
154
|
+
[400, {}, '']
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
118
159
|
it 'should update workflow status to error and return true if successful' do
|
119
|
-
expect(@mock_resource).to receive(:put).with(/status="error" errorMessage="Some exception" errorText="The optional stacktrace"/, { :content_type => 'application/xml' }).and_return('')
|
120
160
|
Dor::WorkflowService.update_workflow_error_status(@repo, @druid, 'etdSubmitWF', 'reader-approval', 'Some exception', :error_text =>'The optional stacktrace')
|
121
161
|
end
|
122
162
|
it 'should return false if the PUT to the DOR workflow service throws an exception' do
|
123
|
-
|
124
|
-
expect(@mock_resource).to receive(:put).with(/status="completed"/, { :content_type => 'application/xml' }).and_raise(ex)
|
125
|
-
expect{ Dor::WorkflowService.update_workflow_status(@repo, @druid, 'etdSubmitWF', 'reader-approval', 'completed') }.to raise_error(Exception, 'exception thrown')
|
163
|
+
expect{ Dor::WorkflowService.update_workflow_status(@repo, @druid, 'errorWF', 'reader-approval', 'completed') }.to raise_error(Dor::WorkflowException, /status 400/)
|
126
164
|
end
|
127
165
|
end
|
128
166
|
|
129
167
|
describe '#get_workflow_status' do
|
168
|
+
let(:stubs) do
|
169
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
170
|
+
stub.get("#{@repo}/objects/#{@druid}/workflows/etdSubmitWF") do |env|
|
171
|
+
[200, {}, '<process name="registrar-approval" status="completed" />']
|
172
|
+
end
|
173
|
+
|
174
|
+
stub.get("#{@repo}/objects/#{@druid}/workflows/missingWF") do |env|
|
175
|
+
[404, {}, '']
|
176
|
+
end
|
177
|
+
|
178
|
+
stub.get("#{@repo}/objects/#{@druid}/workflows/errorWF") do |env|
|
179
|
+
[200, {}, 'something not xml']
|
180
|
+
end
|
181
|
+
|
182
|
+
stub.get("#{@repo}/objects/#{@druid}/workflows/accessionWF") do |env|
|
183
|
+
[200, {}, '<process name="registrar-approval" status="completed" />']
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
130
188
|
it 'parses workflow xml and returns status as a string' do
|
131
|
-
xml = '<process name="registrar-approval" status="completed" />'
|
132
|
-
allow(@mock_http_connection).to receive(:get).and_return(double Faraday::Response, :body => xml)
|
133
189
|
expect(Dor::WorkflowService.get_workflow_status('dor', 'druid:123', 'etdSubmitWF', 'registrar-approval')).to eq('completed')
|
134
190
|
end
|
135
191
|
it 'should throw an exception if it fails for any reason' do
|
136
|
-
|
137
|
-
allow(@mock_http_connection).to receive(:get).and_raise(ex)
|
138
|
-
expect{ Dor::WorkflowService.get_workflow_status('dor', 'druid:123', 'etdSubmitWF', 'registrar-approval') }.to raise_error(Exception, 'exception thrown')
|
192
|
+
expect{ Dor::WorkflowService.get_workflow_status('dor', 'druid:123', 'missingWF', 'registrar-approval') }.to raise_error Dor::WorkflowException
|
139
193
|
end
|
140
194
|
it 'should throw an exception if it cannot parse the response' do
|
141
|
-
|
142
|
-
expect{ Dor::WorkflowService.get_workflow_status('dor', 'druid:123', 'etdSubmitWF', 'registrar-approval') }.to raise_error(Exception, "Unable to parse response:\nsomething not xml")
|
195
|
+
expect{ Dor::WorkflowService.get_workflow_status('dor', 'druid:123', 'errorWF', 'registrar-approval') }.to raise_error(Dor::WorkflowException, "Unable to parse response:\nsomething not xml")
|
143
196
|
end
|
144
197
|
it 'should return nil if the workflow/process combination doesnt exist' do
|
145
|
-
allow(@mock_http_connection).to receive(:get).and_return(double Faraday::Response, :body => '<process name="registrar-approval" status="completed" />')
|
146
198
|
expect(Dor::WorkflowService.get_workflow_status('dor', 'druid:123', 'accessionWF', 'publish')).to be_nil
|
147
199
|
end
|
148
200
|
end
|
149
201
|
|
150
202
|
describe '#get_workflow_xml' do
|
203
|
+
let(:xml) { '<workflow id="etdSubmitWF"><process name="registrar-approval" status="completed" /></workflow>' }
|
204
|
+
let(:stubs) do
|
205
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
206
|
+
stub.get("dor/objects/druid:123/workflows/etdSubmitWF") do |env|
|
207
|
+
[200, {}, xml]
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
151
212
|
it 'returns the xml for a given repository, druid, and workflow' do
|
152
|
-
xml = '<workflow id="etdSubmitWF"><process name="registrar-approval" status="completed" /></workflow>'
|
153
|
-
allow(@mock_http_connection).to receive(:get).and_return(double Faraday::Response, :body => xml)
|
154
213
|
expect(Dor::WorkflowService.get_workflow_xml('dor', 'druid:123', 'etdSubmitWF')).to eq(xml)
|
155
214
|
end
|
156
215
|
end
|
157
216
|
|
217
|
+
describe '#get_workflows' do
|
218
|
+
let(:xml) { '<workflow id="accessionWF"><process name="publish" status="completed" /></workflow>' }
|
219
|
+
let(:stubs) do
|
220
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
221
|
+
stub.get("dor/objects/#{@druid}/workflows/") do |env|
|
222
|
+
[200, {}, xml]
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
it 'returns the workflows associated with druid' do
|
228
|
+
expect(Dor::WorkflowService.get_workflows(@druid)).to eq(['accessionWF'])
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
158
232
|
describe '#get_lifecycle' do
|
233
|
+
let(:stubs) do
|
234
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
235
|
+
stub.get('dor/objects/druid:123/lifecycle') do |env|
|
236
|
+
[200, {}, <<-EOXML]
|
237
|
+
<lifecycle objectId="druid:ct011cv6501">
|
238
|
+
<milestone date="2010-04-27T11:34:17-0700">registered</milestone>
|
239
|
+
<milestone date="2010-04-29T10:12:51-0700">inprocess</milestone>
|
240
|
+
<milestone date="2010-06-15T16:08:58-0700">released</milestone>
|
241
|
+
</lifecycle>
|
242
|
+
EOXML
|
243
|
+
end
|
244
|
+
|
245
|
+
stub.get('dor/objects/druid:abc/lifecycle') do |env|
|
246
|
+
[200, {}, <<-EOXML]
|
247
|
+
<lifecycle />
|
248
|
+
EOXML
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
159
253
|
it 'returns a Time object reprenting when the milestone was reached' do
|
160
|
-
xml = <<-EOXML
|
161
|
-
<lifecycle objectId="druid:ct011cv6501">
|
162
|
-
<milestone date="2010-04-27T11:34:17-0700">registered</milestone>
|
163
|
-
<milestone date="2010-04-29T10:12:51-0700">inprocess</milestone>
|
164
|
-
<milestone date="2010-06-15T16:08:58-0700">released</milestone>
|
165
|
-
</lifecycle>
|
166
|
-
EOXML
|
167
|
-
allow(@mock_http_connection).to receive(:get).and_return(double Faraday::Response, :body => xml)
|
168
254
|
expect(Dor::WorkflowService.get_lifecycle('dor', 'druid:123', 'released').beginning_of_day).to eq(Time.parse('2010-06-15T16:08:58-0700').beginning_of_day)
|
169
255
|
end
|
170
256
|
|
171
257
|
it "returns nil if the milestone hasn't been reached yet" do
|
172
|
-
xml = '<lifecycle/>'
|
173
|
-
allow(@mock_http_connection).to receive(:get).and_return(double Faraday::Response, :body => xml)
|
174
258
|
expect(Dor::WorkflowService.get_lifecycle('dor', 'druid:abc', 'inprocess')).to be_nil
|
175
259
|
end
|
176
260
|
end
|
177
261
|
|
262
|
+
describe '#get_active_lifecycle' do
|
263
|
+
let(:stubs) do
|
264
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
265
|
+
stub.get("dor/objects/#{@druid}/lifecycle") do |env|
|
266
|
+
[200, {}, <<-EOXML]
|
267
|
+
<lifecycle objectId="#{@druid}">
|
268
|
+
<milestone date="2010-04-27T11:34:17-0700">registered</milestone>
|
269
|
+
<milestone date="2010-04-29T10:12:51-0700">inprocess</milestone>
|
270
|
+
<milestone date="2010-06-15T16:08:58-0700">released</milestone>
|
271
|
+
</lifecycle>
|
272
|
+
EOXML
|
273
|
+
end
|
274
|
+
|
275
|
+
stub.get("dor/objects/#{@druid}/lifecycle") do |env|
|
276
|
+
[200, {}, <<-EOXML]
|
277
|
+
<lifecycle />
|
278
|
+
EOXML
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
it 'parses out the active lifecycle' do
|
284
|
+
expect(Dor::WorkflowService.get_active_lifecycle('dor', @druid, 'released').beginning_of_day).to eq(Time.parse('2010-06-15T16:08:58-0700').beginning_of_day)
|
285
|
+
end
|
286
|
+
|
287
|
+
it 'handles missing lifecycle' do
|
288
|
+
expect(Dor::WorkflowService.get_active_lifecycle('dor', @druid, 'NOT_FOUND')).to be_nil
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
178
292
|
context '#get_objects_for_workstep' do
|
179
|
-
before :
|
293
|
+
before :all do
|
180
294
|
@repository = 'dor'
|
181
295
|
@workflow = 'googleScannedBookWF'
|
182
296
|
@completed = 'google-download'
|
183
297
|
@waiting = 'process-content'
|
184
298
|
end
|
185
299
|
|
300
|
+
let(:stubs) do
|
301
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
302
|
+
stub.get("workflow_queue?waiting=#{@repository}:#{@workflow}:#{@waiting}&completed=#{@repository}:#{@workflow}:#{@completed}&lane-id=default") do |env|
|
303
|
+
[200, {}, '<objects count="1"><object id="druid:ab123de4567"/><object id="druid:ab123de9012"/></objects>']
|
304
|
+
end
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
186
308
|
describe 'a query with one step completed and one waiting' do
|
187
309
|
it 'creates the URI string with only the one completed step' do
|
188
|
-
xml = %{<objects count="1"><object id="druid:ab123de4567"/><object id="druid:ab123de9012"/></objects>}
|
189
|
-
allow(@mock_http_connection).to receive(:get).with("workflow_queue?waiting=#{@repository}:#{@workflow}:#{@waiting}&completed=#{@repository}:#{@workflow}:#{@completed}&lane-id=default").and_return(double Faraday::Response, :body => xml)
|
190
310
|
expect(Dor::WorkflowService.get_objects_for_workstep(@completed, @waiting, 'default', :default_repository => @repository, :default_workflow => @workflow)).to eq(['druid:ab123de4567', 'druid:ab123de9012'])
|
191
311
|
end
|
192
312
|
end
|
@@ -195,7 +315,7 @@ describe Dor::WorkflowService do
|
|
195
315
|
it 'creates the URI string with the two completed steps correctly' do
|
196
316
|
second_completed = 'google-convert'
|
197
317
|
xml = %{<objects count="1"><object id="druid:ab123de4567"/><object id="druid:ab123de9012"/></objects>}
|
198
|
-
allow(
|
318
|
+
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)
|
199
319
|
expect(Dor::WorkflowService.get_objects_for_workstep([@completed, second_completed], @waiting, 'default', :default_repository => @repository, :default_workflow => @workflow)).to eq(['druid:ab123de4567', 'druid:ab123de9012'])
|
200
320
|
end
|
201
321
|
end
|
@@ -211,7 +331,7 @@ describe Dor::WorkflowService do
|
|
211
331
|
qualified_completed2 = "sdr:sdrIngestWF:complete-deposit"
|
212
332
|
qualified_completed3 = "sdr:sdrIngestWF:ingest-transfer"
|
213
333
|
xml = %{<objects count="2"><object id="druid:ab123de4567"/><object id="druid:ab123de9012"/></objects>}
|
214
|
-
allow(
|
334
|
+
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)
|
215
335
|
args = [[@qualified_completed, qualified_completed2, qualified_completed3], @qualified_waiting]
|
216
336
|
args << laneid if laneid != 'default'
|
217
337
|
expect(Dor::WorkflowService.get_objects_for_workstep(*args)).to eq(['druid:ab123de4567', 'druid:ab123de9012'])
|
@@ -234,15 +354,15 @@ describe Dor::WorkflowService do
|
|
234
354
|
@xml = %{<objects count="1"><object id="druid:ab123de4567"/></objects>}
|
235
355
|
end
|
236
356
|
it 'with only one completed step passed in as a String' do
|
237
|
-
allow(
|
357
|
+
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)
|
238
358
|
expect(Dor::WorkflowService.get_objects_for_workstep(@qualified_completed, @qualified_waiting)).to eq(['druid:ab123de4567'])
|
239
359
|
end
|
240
360
|
it 'without any completed steps, only waiting' do
|
241
|
-
allow(
|
361
|
+
allow(mock_http_connection).to receive(:get).with("workflow_queue?waiting=#{@qualified_waiting}&lane-id=default").and_return(double Faraday::Response, :body => @xml)
|
242
362
|
expect(Dor::WorkflowService.get_objects_for_workstep(nil, @qualified_waiting)).to eq(['druid:ab123de4567'])
|
243
363
|
end
|
244
364
|
it 'same but with lane_id' do
|
245
|
-
allow(
|
365
|
+
allow(mock_http_connection).to receive(:get).with("workflow_queue?waiting=#{@qualified_waiting}&lane-id=lane1").and_return(double Faraday::Response, :body => @xml)
|
246
366
|
expect(Dor::WorkflowService.get_objects_for_workstep(nil, @qualified_waiting, 'lane1')).to eq([ 'druid:ab123de4567' ])
|
247
367
|
end
|
248
368
|
end
|
@@ -250,21 +370,110 @@ describe Dor::WorkflowService do
|
|
250
370
|
end
|
251
371
|
|
252
372
|
context 'get empty workflow queue' do
|
373
|
+
before(:all) do
|
374
|
+
@repository = 'dor'
|
375
|
+
@workflow = 'googleScannedBookWF'
|
376
|
+
@completed = 'google-download'
|
377
|
+
@waiting = 'process-content'
|
378
|
+
end
|
379
|
+
|
380
|
+
let(:stubs) do
|
381
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
382
|
+
stub.get("workflow_queue?waiting=#{@repository}:#{@workflow}:#{@waiting}&completed=#{@repository}:#{@workflow}:#{@completed}&lane-id=default") do |env|
|
383
|
+
[200, {}, '<objects count="0"/>']
|
384
|
+
end
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
253
388
|
it 'returns an empty list if it encounters an empty workflow queue' do
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
389
|
+
expect(Dor::WorkflowService.get_objects_for_workstep(@completed, @waiting, 'default', :default_repository => @repository, :default_workflow => @workflow)).to eq([])
|
390
|
+
end
|
391
|
+
end
|
392
|
+
|
393
|
+
context 'get errored workflow steps' do
|
394
|
+
before(:all) do
|
395
|
+
@repository = 'dor'
|
396
|
+
@workflow = 'accessionWF'
|
397
|
+
@step = 'publish'
|
398
|
+
end
|
399
|
+
|
400
|
+
let(:stubs) do
|
401
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
402
|
+
stub.get("/workflow_queue?error=#{@step}&repository=#{@repository}&workflow=#{@workflow}") do |env|
|
403
|
+
[200, {}, <<-EOXML ]
|
404
|
+
<objects count="1">
|
405
|
+
<object id="druid:ab123cd4567" errorMessage="This is an error message"/>
|
406
|
+
</objects>
|
407
|
+
EOXML
|
408
|
+
end
|
409
|
+
end
|
410
|
+
end
|
411
|
+
|
412
|
+
it 'returns error messages for errored objects' do
|
413
|
+
expect(Dor::WorkflowService.get_errored_objects_for_workstep(@workflow, @step, @repository)).to eq({'druid:ab123cd4567'=>'This is an error message'})
|
414
|
+
end
|
415
|
+
|
416
|
+
it 'counts how many steps are errored out' do
|
417
|
+
expect(Dor::WorkflowService.count_errored_for_workstep(@workflow, @step, @repository)).to eq(1)
|
418
|
+
end
|
419
|
+
end
|
420
|
+
|
421
|
+
describe '#count_queued_for_workstep' do
|
422
|
+
before(:all) do
|
423
|
+
@repository = 'dor'
|
424
|
+
@workflow = 'accessionWF'
|
425
|
+
@step = 'publish'
|
426
|
+
end
|
427
|
+
|
428
|
+
let(:stubs) do
|
429
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
430
|
+
stub.get("/workflow_queue?queued=#{@step}&repository=#{@repository}&workflow=#{@workflow}") do |env|
|
431
|
+
[200, {}, <<-EOXML ]
|
432
|
+
<objects count="1">
|
433
|
+
<object id="druid:ab123cd4567"/>
|
434
|
+
</objects>
|
435
|
+
EOXML
|
436
|
+
end
|
437
|
+
end
|
438
|
+
end
|
439
|
+
|
440
|
+
it 'counts how many steps are errored out' do
|
441
|
+
expect(Dor::WorkflowService.count_queued_for_workstep(@workflow, @step, @repository)).to eq(1)
|
442
|
+
end
|
443
|
+
end
|
444
|
+
|
445
|
+
describe '#count_archived_for_workflow' do
|
446
|
+
before(:all) do
|
447
|
+
@repository = 'dor'
|
448
|
+
@workflow = 'accessionWF'
|
449
|
+
end
|
450
|
+
|
451
|
+
let(:stubs) do
|
452
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
453
|
+
stub.get("/workflow_archive?repository=#{@repository}&workflow=#{@workflow}&count-only=true") do |env|
|
454
|
+
[200, {}, <<-EOXML ]
|
455
|
+
<objects count="20" />
|
456
|
+
EOXML
|
457
|
+
end
|
458
|
+
end
|
459
|
+
end
|
460
|
+
|
461
|
+
it 'counts how many workflows are archived' do
|
462
|
+
expect(Dor::WorkflowService.count_archived_for_workflow(@workflow, @repository)).to eq(20)
|
261
463
|
end
|
262
464
|
end
|
263
465
|
|
264
466
|
describe '#delete_workflow' do
|
467
|
+
let(:url) { "#{@repo}/objects/#{@druid}/workflows/accessionWF" }
|
468
|
+
|
469
|
+
let(:stubs) do
|
470
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
471
|
+
stub.delete(url) { |env| [202, {}, ''] }
|
472
|
+
end
|
473
|
+
end
|
474
|
+
|
265
475
|
it 'sends a delete request to the workflow service' do
|
266
|
-
expect(
|
267
|
-
expect(@mock_resource).to receive(:delete)
|
476
|
+
expect(mock_http_connection).to receive(:delete).with(url).and_call_original
|
268
477
|
Dor::WorkflowService.delete_workflow(@repo, @druid, 'accessionWF')
|
269
478
|
end
|
270
479
|
end
|
@@ -298,28 +507,44 @@ describe Dor::WorkflowService do
|
|
298
507
|
end
|
299
508
|
|
300
509
|
describe '#close_version' do
|
510
|
+
let(:stubs) do
|
511
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
512
|
+
stub.post('dor/objects/druid:123/versionClose?create-accession=false') do |env|
|
513
|
+
[202, {}, '']
|
514
|
+
end
|
515
|
+
|
516
|
+
stub.post('dor/objects/druid:123/versionClose') do |env|
|
517
|
+
[202, {}, '']
|
518
|
+
end
|
519
|
+
end
|
520
|
+
end
|
521
|
+
|
522
|
+
let(:url) { 'dor/objects/druid:123/versionClose' }
|
301
523
|
it 'calls the versionClose endpoint with druid' do
|
302
|
-
expect(@mock_resource).to receive(:[]).with('dor/objects/druid:123/versionClose').and_return(@mock_resource)
|
303
|
-
expect(@mock_resource).to receive(:post).with('').and_return('')
|
304
524
|
Dor::WorkflowService.close_version(@repo, @druid)
|
305
525
|
end
|
306
526
|
|
307
527
|
it 'optionally prevents creation of accessionWF' do
|
308
|
-
expect(
|
309
|
-
expect(@mock_resource).to receive(:post).with('').and_return('')
|
528
|
+
expect(mock_http_connection).to receive(:post).with('dor/objects/druid:123/versionClose?create-accession=false').and_call_original
|
310
529
|
Dor::WorkflowService.close_version(@repo, @druid, false)
|
311
530
|
end
|
312
531
|
end
|
313
532
|
|
314
533
|
describe '.get_stale_queued_workflows' do
|
534
|
+
let(:stubs) do
|
535
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
536
|
+
stub.get('workflow_queue/all_queued?repository=dor&hours-ago=24&limit=100') do |env|
|
537
|
+
[200, {}, <<-XML]
|
538
|
+
<workflows>
|
539
|
+
<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"/>
|
540
|
+
<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"/>
|
541
|
+
</workflows>
|
542
|
+
XML
|
543
|
+
end
|
544
|
+
end
|
545
|
+
end
|
546
|
+
|
315
547
|
it 'returns an Array of Hashes containing each workflow step' do
|
316
|
-
xml = <<-XML
|
317
|
-
<workflows>
|
318
|
-
<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"/>
|
319
|
-
<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"/>
|
320
|
-
</workflows>
|
321
|
-
XML
|
322
|
-
allow(@mock_http_connection).to receive(:get).with('workflow_queue/all_queued?repository=dor&hours-ago=24&limit=100').and_return(double Faraday::Response, :body => xml)
|
323
548
|
ah = Dor::WorkflowService.get_stale_queued_workflows 'dor', :hours_ago => 24, :limit => 100
|
324
549
|
expected = [
|
325
550
|
{ :workflow => 'accessionWF', :step => 'content-metadata', :druid => 'dr:123', :lane_id => 'lane1' },
|
@@ -330,46 +555,35 @@ describe Dor::WorkflowService do
|
|
330
555
|
end
|
331
556
|
|
332
557
|
describe '.count_stale_queued_workflows' do
|
558
|
+
let(:stubs) do
|
559
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
560
|
+
stub.get('workflow_queue/all_queued?repository=dor&hours-ago=48&count-only=true') do |env|
|
561
|
+
[200, {}, '<objects count="10"/>']
|
562
|
+
end
|
563
|
+
end
|
564
|
+
end
|
565
|
+
|
333
566
|
it 'returns the number of queued workflow steps' do
|
334
|
-
xml = %{<objects count="10"/>}
|
335
|
-
allow(@mock_http_connection).to receive(:get).with('workflow_queue/all_queued?repository=dor&hours-ago=48&count-only=true').and_return(double Faraday::Response, :body => xml)
|
336
567
|
expect(Dor::WorkflowService.count_stale_queued_workflows('dor', :hours_ago => 48)).to eq(10)
|
337
568
|
end
|
338
569
|
end
|
339
570
|
|
340
571
|
describe '.get_lane_ids' do
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
end
|
352
|
-
|
353
|
-
describe 'protected method' do
|
354
|
-
describe '#build_queued_uri' do
|
355
|
-
it 'does something' do
|
356
|
-
skip 'test unimplemented'
|
357
|
-
end
|
358
|
-
end
|
359
|
-
describe '#parse_queued_workflows_response' do
|
360
|
-
it 'does something' do
|
361
|
-
skip 'test unimplemented'
|
362
|
-
end
|
363
|
-
end
|
364
|
-
describe '#add_lane_id_to_workflow_xml' do
|
365
|
-
it 'does something' do
|
366
|
-
skip 'test unimplemented'
|
572
|
+
let(:stubs) do
|
573
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
574
|
+
stub.get('workflow_queue/lane_ids?lane_ids?step=dor:accessionWF:shelve') do |env|
|
575
|
+
[200, {}, <<-XML]
|
576
|
+
<lanes>
|
577
|
+
<lane id="lane1"/>
|
578
|
+
<lane id="lane2"/>
|
579
|
+
</lanes>
|
580
|
+
XML
|
581
|
+
end
|
367
582
|
end
|
368
583
|
end
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
end
|
584
|
+
|
585
|
+
it 'returns the lane ids for a given workflow step' do
|
586
|
+
expect(Dor::WorkflowService.get_lane_ids('dor', 'accessionWF', 'shelve')).to eq(%w(lane1 lane2))
|
373
587
|
end
|
374
588
|
end
|
375
589
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dor-workflow-service
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
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:
|
12
|
+
date: 2016-02-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -45,20 +45,6 @@ dependencies:
|
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: 1.6.0
|
48
|
-
- !ruby/object:Gem::Dependency
|
49
|
-
name: rest-client
|
50
|
-
requirement: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '1.7'
|
55
|
-
type: :runtime
|
56
|
-
prerelease: false
|
57
|
-
version_requirements: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - "~>"
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '1.7'
|
62
48
|
- !ruby/object:Gem::Dependency
|
63
49
|
name: retries
|
64
50
|
requirement: !ruby/object:Gem::Requirement
|
@@ -191,6 +177,20 @@ dependencies:
|
|
191
177
|
- - "~>"
|
192
178
|
- !ruby/object:Gem::Version
|
193
179
|
version: 0.5.1
|
180
|
+
- !ruby/object:Gem::Dependency
|
181
|
+
name: simplecov
|
182
|
+
requirement: !ruby/object:Gem::Requirement
|
183
|
+
requirements:
|
184
|
+
- - ">="
|
185
|
+
- !ruby/object:Gem::Version
|
186
|
+
version: '0'
|
187
|
+
type: :development
|
188
|
+
prerelease: false
|
189
|
+
version_requirements: !ruby/object:Gem::Requirement
|
190
|
+
requirements:
|
191
|
+
- - ">="
|
192
|
+
- !ruby/object:Gem::Version
|
193
|
+
version: '0'
|
194
194
|
description: Enables Ruby manipulation of the DOR Workflow Service via its REST API
|
195
195
|
email:
|
196
196
|
- wmene@stanford.edu
|
@@ -215,6 +215,7 @@ files:
|
|
215
215
|
- gemfiles/rails4.gemfile
|
216
216
|
- lib/dor-workflow-service.rb
|
217
217
|
- lib/dor/services/workflow_service.rb
|
218
|
+
- lib/dor/workflow_exception.rb
|
218
219
|
- lib/dor/workflow_version.rb
|
219
220
|
- spec/plumbing_spec.rb
|
220
221
|
- spec/spec_helper.rb
|
@@ -238,7 +239,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
238
239
|
version: '0'
|
239
240
|
requirements: []
|
240
241
|
rubyforge_project:
|
241
|
-
rubygems_version: 2.4.
|
242
|
+
rubygems_version: 2.4.5.1
|
242
243
|
signing_key:
|
243
244
|
specification_version: 4
|
244
245
|
summary: Provides convenience methods to work with the DOR Workflow Service
|
@@ -246,3 +247,4 @@ test_files:
|
|
246
247
|
- spec/plumbing_spec.rb
|
247
248
|
- spec/spec_helper.rb
|
248
249
|
- spec/workflow_service_spec.rb
|
250
|
+
has_rdoc:
|