dor-services 6.6.2 → 6.7.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/config/dev_console_env.rb.example +1 -1
- data/lib/dor-services.rb +3 -0
- data/lib/dor/datastreams/workflow_ds.rb +6 -4
- data/lib/dor/exceptions.rb +3 -0
- data/lib/dor/indexers/workflow_indexer.rb +67 -10
- data/lib/dor/indexers/workflows_indexer.rb +28 -0
- data/lib/dor/models/admin_policy_object.rb +1 -1
- data/lib/dor/models/collection.rb +1 -1
- data/lib/dor/models/concerns/contentable.rb +3 -14
- data/lib/dor/models/concerns/versionable.rb +2 -2
- data/lib/dor/models/item.rb +1 -1
- data/lib/dor/models/set.rb +1 -1
- data/lib/dor/models/workflow_object.rb +1 -1
- data/lib/dor/models/workflow_solr_document.rb +93 -0
- data/lib/dor/services/cleanup_reset_service.rb +1 -1
- data/lib/dor/services/cleanup_service.rb +1 -1
- data/lib/dor/services/decommission_service.rb +31 -0
- data/lib/dor/services/metadata_handlers/catalog_handler.rb +5 -4
- data/lib/dor/services/metadata_service.rb +12 -29
- data/lib/dor/services/status_service.rb +1 -1
- data/lib/dor/services/version_service.rb +4 -4
- data/lib/dor/version.rb +1 -1
- data/lib/dor/workflow/document.rb +0 -73
- metadata +7 -25
- data/lib/dor/services/registration_service.rb +0 -202
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 49efa35d39eee0748121dad21f44e871d6ea38eff28dc1719f7d13061eaab269
|
4
|
+
data.tar.gz: d1e0418a853a958966e7247e9c2ca0ceaf0739784ee3da2e3a0ab1a4f8a2f67d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 37ac6a9d98625fb2272a5e541d6cf99d4b3f6d7e615c000b22aa6c51b49ed917b912a30f77c293da356107f2418fa60d5c70a5a3b84f31bb52fa149b13f3601d
|
7
|
+
data.tar.gz: 2401c8bfef4aa070e5672227e67c53a29dee353dbe58fa73922f4a3409d1b23f0ad8baf9d5e30fa4c4e0d87062e0c38d37fbc0ac74cf31fd740d6d33fba84fea
|
data/lib/dor-services.rb
CHANGED
@@ -91,6 +91,7 @@ module Dor
|
|
91
91
|
autoload :ProcessableIndexer
|
92
92
|
autoload :ReleasableIndexer
|
93
93
|
autoload :WorkflowIndexer
|
94
|
+
autoload :WorkflowsIndexer
|
94
95
|
end
|
95
96
|
|
96
97
|
# datastreams
|
@@ -144,6 +145,7 @@ module Dor
|
|
144
145
|
autoload :Collection
|
145
146
|
autoload :AdminPolicyObject
|
146
147
|
autoload :WorkflowObject
|
148
|
+
autoload :WorkflowSolrDocument
|
147
149
|
end
|
148
150
|
end
|
149
151
|
|
@@ -155,6 +157,7 @@ module Dor
|
|
155
157
|
autoload :CreateWorkflowService
|
156
158
|
autoload :CreativeCommonsLicenseService
|
157
159
|
autoload :DatastreamBuilder
|
160
|
+
autoload :DecommissionService
|
158
161
|
autoload :DigitalStacksService
|
159
162
|
autoload :DublinCoreService
|
160
163
|
autoload :FileMetadataMergeService
|
@@ -35,7 +35,7 @@ module Dor
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def get_workflow(wf, repo = 'dor')
|
38
|
-
xml = Dor::Config.workflow.client.
|
38
|
+
xml = Dor::Config.workflow.client.workflow_xml(repo, pid, wf)
|
39
39
|
xml = Nokogiri::XML(xml)
|
40
40
|
return nil if xml.xpath('workflow').length == 0
|
41
41
|
|
@@ -55,14 +55,16 @@ module Dor
|
|
55
55
|
# service directly
|
56
56
|
def content(refresh = false)
|
57
57
|
@content = nil if refresh
|
58
|
-
@content ||= Dor::Config.workflow.client.
|
58
|
+
@content ||= Dor::Config.workflow.client.all_workflows_xml pid
|
59
59
|
rescue Dor::WorkflowException => e
|
60
|
+
# TODO: I don't understand when this would be useful as this block ends up calling the workflow service too.
|
61
|
+
# Why not just raise an exception here?
|
60
62
|
Dor.logger.warn "Unable to connect to the workflow service #{e}. Falling back to placeholder XML"
|
61
63
|
xml = Nokogiri::XML(%(<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<workflows objectId="#{pid}"/>))
|
62
64
|
digital_object.datastreams.keys.each do |dsid|
|
63
65
|
next unless dsid =~ /WF$/
|
64
66
|
|
65
|
-
ds_content = Nokogiri::XML(Dor::Config.workflow.client.
|
67
|
+
ds_content = Nokogiri::XML(Dor::Config.workflow.client.workflow_xml('dor', pid, dsid))
|
66
68
|
xml.root.add_child(ds_content.root)
|
67
69
|
end
|
68
70
|
@content ||= xml.to_xml
|
@@ -83,7 +85,7 @@ module Dor
|
|
83
85
|
end
|
84
86
|
|
85
87
|
def to_solr(solr_doc = {}, *_args)
|
86
|
-
# noop - indexing is done by the
|
88
|
+
# noop - indexing is done by the WorkflowsIndexer
|
87
89
|
solr_doc
|
88
90
|
end
|
89
91
|
|
data/lib/dor/exceptions.rb
CHANGED
@@ -11,6 +11,9 @@ module Dor
|
|
11
11
|
# rubocop:disable Lint/InheritException
|
12
12
|
# See https://github.com/rubocop-hq/rubocop/issues/6770
|
13
13
|
class VersionAlreadyOpenError < Exception; end
|
14
|
+
|
15
|
+
# Raised when we can't get a response from the catalog
|
16
|
+
class BadResponseFromCatalog < Exception; end
|
14
17
|
# rubocop:enable Lint/InheritException
|
15
18
|
|
16
19
|
class DuplicateIdError < RuntimeError
|
@@ -3,25 +3,82 @@
|
|
3
3
|
module Dor
|
4
4
|
# Indexes the objects position in workflows
|
5
5
|
class WorkflowIndexer
|
6
|
-
|
6
|
+
ERROR_OMISSION = '... (continued)'
|
7
|
+
private_constant :ERROR_OMISSION
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
# see https://lucene.apache.org/core/7_3_1/core/org/apache/lucene/util/BytesRefHash.MaxBytesLengthExceededException.html
|
10
|
+
MAX_ERROR_LENGTH = 32_768 - 2 - ERROR_OMISSION.length
|
11
|
+
private_constant :MAX_ERROR_LENGTH
|
12
|
+
|
13
|
+
# @param [Dor::WorkflowDocument] document the workflow document to index
|
14
|
+
def initialize(document:)
|
15
|
+
@document = document
|
11
16
|
end
|
12
17
|
|
13
|
-
# @return [Hash] the partial solr document for workflow
|
18
|
+
# @return [Hash] the partial solr document for the workflow document
|
14
19
|
def to_solr
|
15
|
-
|
16
|
-
|
20
|
+
WorkflowSolrDocument.new do |solr_doc|
|
21
|
+
wf_name = document.workflowId.first
|
22
|
+
solr_doc.name = wf_name
|
23
|
+
errors = processes.count(&:error?)
|
24
|
+
|
25
|
+
repo = document.repository.first
|
26
|
+
solr_doc.status = [wf_name, workflow_status, errors, repo].join('|')
|
27
|
+
|
28
|
+
processes.each do |process|
|
29
|
+
index_process(solr_doc, wf_name, process)
|
30
|
+
end
|
17
31
|
end
|
18
32
|
end
|
19
33
|
|
20
34
|
private
|
21
35
|
|
22
|
-
|
23
|
-
|
24
|
-
|
36
|
+
attr_reader :document
|
37
|
+
delegate :processes, to: :document
|
38
|
+
|
39
|
+
def index_process(solr_doc, wf_name, process)
|
40
|
+
return unless process.status.present?
|
41
|
+
|
42
|
+
# add a record of the robot having operated on this item, so we can track robot activity
|
43
|
+
solr_doc.add_process_time(wf_name, process.name, Time.parse(process.date_time)) if process_has_time?(process)
|
44
|
+
|
45
|
+
index_error_message(solr_doc, wf_name, process)
|
46
|
+
|
47
|
+
# workflow name, process status then process name
|
48
|
+
solr_doc.add_wps("#{wf_name}:#{process.status}", "#{wf_name}:#{process.status}:#{process.name}")
|
49
|
+
|
50
|
+
# workflow name, process name then process status
|
51
|
+
solr_doc.add_wps("#{wf_name}:#{process.name}", "#{wf_name}:#{process.name}:#{process.status}")
|
52
|
+
|
53
|
+
# process status, workflowname then process name
|
54
|
+
solr_doc.add_swp(process.status.to_s, "#{process.status}:#{wf_name}", "#{process.status}:#{wf_name}:#{process.name}")
|
55
|
+
return if process.state == process.status
|
56
|
+
|
57
|
+
solr_doc.add_wsp("#{wf_name}:#{process.state}:#{process.name}")
|
58
|
+
solr_doc.add_wps("#{wf_name}:#{process.name}:#{process.state}")
|
59
|
+
solr_doc.add_swp(process.state.to_s, "#{process.state}:#{wf_name}", "#{process.state}:#{wf_name}:#{process.name}")
|
60
|
+
end
|
61
|
+
|
62
|
+
def process_has_time?(process)
|
63
|
+
!process.date_time.blank? && process.status && (process.status == 'completed' || process.status == 'error')
|
64
|
+
end
|
65
|
+
|
66
|
+
def workflow_status
|
67
|
+
return 'empty' if processes.empty?
|
68
|
+
|
69
|
+
workflow_should_show_completed?(processes) ? 'completed' : 'active'
|
70
|
+
end
|
71
|
+
|
72
|
+
def workflow_should_show_completed?(processes)
|
73
|
+
processes.all? { |p| ['skipped', 'completed', '', nil].include?(p.status) }
|
74
|
+
end
|
75
|
+
|
76
|
+
# index the error message without the druid so we hopefully get some overlap
|
77
|
+
# truncate to avoid org.apache.lucene.util.BytesRefHash$MaxBytesLengthExceededException
|
78
|
+
def index_error_message(solr_doc, wf_name, process)
|
79
|
+
return unless process.error_message
|
80
|
+
|
81
|
+
solr_doc.error = "#{wf_name}:#{process.name}:#{process.error_message}".truncate(MAX_ERROR_LENGTH, omission: ERROR_OMISSION)
|
25
82
|
end
|
26
83
|
end
|
27
84
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dor
|
4
|
+
# Indexes the objects position in workflows
|
5
|
+
class WorkflowsIndexer
|
6
|
+
attr_reader :resource
|
7
|
+
def initialize(resource:)
|
8
|
+
@resource = resource
|
9
|
+
end
|
10
|
+
|
11
|
+
# @return [Hash] the partial solr document for workflow concerns
|
12
|
+
def to_solr
|
13
|
+
WorkflowSolrDocument.new do |combined_doc|
|
14
|
+
workflows.each do |wf|
|
15
|
+
doc = WorkflowIndexer.new(document: wf).to_solr
|
16
|
+
combined_doc.merge!(doc)
|
17
|
+
end
|
18
|
+
end.to_h
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
# @return [Array<Dor::WorkflowDocument>]
|
24
|
+
def workflows
|
25
|
+
resource.workflows.workflows
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -15,7 +15,7 @@ module Dor
|
|
15
15
|
EditableIndexer,
|
16
16
|
IdentifiableIndexer,
|
17
17
|
ProcessableIndexer,
|
18
|
-
|
18
|
+
WorkflowsIndexer
|
19
19
|
)
|
20
20
|
|
21
21
|
CREATIVE_COMMONS_USE_LICENSES = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('CREATIVE_COMMONS_USE_LICENSES', 'Dor::CreativeCommonsLicenseService')
|
@@ -170,27 +170,16 @@ module Dor
|
|
170
170
|
# Clears RELS-EXT relationships, sets the isGovernedBy relationship to the SDR Graveyard APO
|
171
171
|
# @param [String] tag optional String of text that is concatenated to the identityMetadata/tag "Decommissioned : "
|
172
172
|
def decommission(tag)
|
173
|
-
|
174
|
-
clear_relationship :is_member_of
|
175
|
-
clear_relationship :is_member_of_collection
|
176
|
-
# remove isGovernedBy relationship
|
177
|
-
clear_relationship :is_governed_by
|
178
|
-
# add isGovernedBy to graveyard APO druid:sw909tc7852
|
179
|
-
# SEARCH BY dc title for 'SDR Graveyard'
|
180
|
-
add_relationship :is_governed_by, ActiveFedora::Base.find(Dor::SearchService.sdr_graveyard_apo_druid)
|
181
|
-
# eliminate contentMetadata. set it to <contentMetadata/> ?
|
182
|
-
contentMetadata.content = '<contentMetadata/>'
|
183
|
-
# eliminate rightsMetadata. set it to <rightsMetadata/> ?
|
184
|
-
rightsMetadata.content = '<rightsMetadata/>'
|
185
|
-
TagService.add self, "Decommissioned : #{tag}"
|
173
|
+
DecommissionService.new(self).decommission(tag)
|
186
174
|
end
|
175
|
+
deprecation_deprecate decommission: 'Use DecommissionService#decommission instead'
|
187
176
|
|
188
|
-
# TODO: Move to Dor-Utils.
|
189
177
|
# Adds a RELS-EXT constituent relationship to the given druid
|
190
178
|
# @param [String] druid the parent druid of the constituent relationship
|
191
179
|
# e.g.: <fedora:isConstituentOf rdf:resource="info:fedora/druid:hj097bm8879" />
|
192
180
|
def add_constituent(druid)
|
193
181
|
add_relationship :is_constituent_of, ActiveFedora::Base.find(druid)
|
194
182
|
end
|
183
|
+
deprecation_deprecate add_constituent: 'Use add_relationship :is_constituent_of instead'
|
195
184
|
end
|
196
185
|
end
|
@@ -49,9 +49,9 @@ module Dor
|
|
49
49
|
# @return [Boolean] true if the object is in a state that allows it to be modified.
|
50
50
|
# States that will allow modification are: has not been submitted for accessioning, has an open version or has sdr-ingest set to hold
|
51
51
|
def allows_modification?
|
52
|
-
if Dor::Config.workflow.client.
|
52
|
+
if Dor::Config.workflow.client.lifecycle('dor', pid, 'submitted') &&
|
53
53
|
!VersionService.new(self).open? &&
|
54
|
-
Dor::Config.workflow.client.
|
54
|
+
Dor::Config.workflow.client.workflow_status('dor', pid, 'accessionWF', 'sdr-ingest-transfer') != 'hold'
|
55
55
|
false
|
56
56
|
else
|
57
57
|
true
|
data/lib/dor/models/item.rb
CHANGED
data/lib/dor/models/set.rb
CHANGED
@@ -0,0 +1,93 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dor
|
4
|
+
# Represents that part of the solr document that holds workflow data
|
5
|
+
class WorkflowSolrDocument
|
6
|
+
WORKFLOW_SOLR = 'wf_ssim'
|
7
|
+
# field that indexes workflow name, process status then process name
|
8
|
+
WORKFLOW_WPS_SOLR = 'wf_wps_ssim'
|
9
|
+
# field that indexes workflow name, process name then process status
|
10
|
+
WORKFLOW_WSP_SOLR = 'wf_wsp_ssim'
|
11
|
+
# field that indexes process status, workflowname then process name
|
12
|
+
WORKFLOW_SWP_SOLR = 'wf_swp_ssim'
|
13
|
+
WORKFLOW_ERROR_SOLR = 'wf_error_ssim'
|
14
|
+
WORKFLOW_STATUS_SOLR = 'workflow_status_ssim'
|
15
|
+
|
16
|
+
KEYS_TO_MERGE = [
|
17
|
+
WORKFLOW_SOLR,
|
18
|
+
WORKFLOW_WPS_SOLR,
|
19
|
+
WORKFLOW_WSP_SOLR,
|
20
|
+
WORKFLOW_SWP_SOLR,
|
21
|
+
WORKFLOW_STATUS_SOLR,
|
22
|
+
WORKFLOW_ERROR_SOLR
|
23
|
+
].freeze
|
24
|
+
|
25
|
+
def initialize
|
26
|
+
@data = empty_document
|
27
|
+
yield self if block_given?
|
28
|
+
end
|
29
|
+
|
30
|
+
def name=(wf_name)
|
31
|
+
data[WORKFLOW_SOLR] += [wf_name]
|
32
|
+
data[WORKFLOW_WPS_SOLR] += [wf_name]
|
33
|
+
data[WORKFLOW_WSP_SOLR] += [wf_name]
|
34
|
+
end
|
35
|
+
|
36
|
+
def status=(status)
|
37
|
+
data[WORKFLOW_STATUS_SOLR] += [status]
|
38
|
+
end
|
39
|
+
|
40
|
+
def error=(message)
|
41
|
+
data[WORKFLOW_ERROR_SOLR] += [message]
|
42
|
+
end
|
43
|
+
|
44
|
+
# Add to the field that indexes workflow name, process status then process name
|
45
|
+
def add_wps(*messages)
|
46
|
+
data[WORKFLOW_WPS_SOLR] += messages
|
47
|
+
end
|
48
|
+
|
49
|
+
# Add to the field that indexes workflow name, process name then process status
|
50
|
+
def add_wsp(*messages)
|
51
|
+
data[WORKFLOW_WSP_SOLR] += messages
|
52
|
+
end
|
53
|
+
|
54
|
+
# Add to the field that indexes process status, workflow name then process name
|
55
|
+
def add_swp(*messages)
|
56
|
+
data[WORKFLOW_SWP_SOLR] += messages
|
57
|
+
end
|
58
|
+
|
59
|
+
# Add the processes data_time attribute to the solr document
|
60
|
+
# @param [String] wf_name
|
61
|
+
# @param [String] process_name
|
62
|
+
# @param [Time] time
|
63
|
+
def add_process_time(wf_name, process_name, time)
|
64
|
+
data["wf_#{wf_name}_#{process_name}_dttsi"] = time.utc.iso8601
|
65
|
+
end
|
66
|
+
|
67
|
+
def to_h
|
68
|
+
KEYS_TO_MERGE.each { |k| data[k].uniq! }
|
69
|
+
data
|
70
|
+
end
|
71
|
+
|
72
|
+
delegate :except, :[], to: :data
|
73
|
+
|
74
|
+
# @param [WorkflowSolrDocument] doc
|
75
|
+
def merge!(doc)
|
76
|
+
# This is going to get the date fields, e.g. `wf_assemblyWF_jp2-create_dttsi'
|
77
|
+
@data.merge!(doc.except(*KEYS_TO_MERGE))
|
78
|
+
|
79
|
+
# Combine the non-unique fields together
|
80
|
+
KEYS_TO_MERGE.each do |k|
|
81
|
+
data[k] += doc[k]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
attr_reader :data
|
88
|
+
|
89
|
+
def empty_document
|
90
|
+
KEYS_TO_MERGE.each_with_object({}) { |k, obj| obj[k] = [] }
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -19,7 +19,7 @@ module Dor
|
|
19
19
|
last_version = druid_obj.current_version.to_i
|
20
20
|
|
21
21
|
# if the current version is still open, avoid this versioned directory
|
22
|
-
last_version -= 1 if Dor::Config.workflow.client.
|
22
|
+
last_version -= 1 if Dor::Config.workflow.client.lifecycle('dor', druid, 'accessioned').nil?
|
23
23
|
last_version
|
24
24
|
end
|
25
25
|
|
@@ -70,7 +70,7 @@ module Dor
|
|
70
70
|
|
71
71
|
def self.remove_active_workflows(druid)
|
72
72
|
%w(dor sdr).each do |repo|
|
73
|
-
dor_wfs = Dor::Config.workflow.client.
|
73
|
+
dor_wfs = Dor::Config.workflow.client.workflows(druid, repo)
|
74
74
|
dor_wfs.each { |wf| Dor::Config.workflow.client.delete_workflow(repo, druid, wf) }
|
75
75
|
end
|
76
76
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dor
|
4
|
+
# Responsible for decommissioning objects
|
5
|
+
class DecommissionService
|
6
|
+
# @param [Dor::Item] object
|
7
|
+
def initialize(object)
|
8
|
+
@object = object
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :object
|
12
|
+
|
13
|
+
# Clears RELS-EXT relationships, sets the isGovernedBy relationship to the SDR Graveyard APO
|
14
|
+
# @param [String] tag optional String of text that is concatenated to the identityMetadata/tag "Decommissioned : "
|
15
|
+
def decommission(tag)
|
16
|
+
# remove isMemberOf and isMemberOfCollection relationships
|
17
|
+
object.clear_relationship :is_member_of
|
18
|
+
object.clear_relationship :is_member_of_collection
|
19
|
+
# remove isGovernedBy relationship
|
20
|
+
object.clear_relationship :is_governed_by
|
21
|
+
# add isGovernedBy to graveyard APO druid:sw909tc7852
|
22
|
+
# SEARCH BY dc title for 'SDR Graveyard'
|
23
|
+
object.add_relationship :is_governed_by, ActiveFedora::Base.find(Dor::SearchService.sdr_graveyard_apo_druid)
|
24
|
+
# eliminate contentMetadata. set it to <contentMetadata/> ?
|
25
|
+
object.contentMetadata.content = '<contentMetadata/>'
|
26
|
+
# eliminate rightsMetadata. set it to <rightsMetadata/> ?
|
27
|
+
object.rightsMetadata.content = '<rightsMetadata/>'
|
28
|
+
TagService.add object, "Decommissioned : #{tag}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -2,12 +2,15 @@
|
|
2
2
|
|
3
3
|
require 'rest-client'
|
4
4
|
|
5
|
-
|
5
|
+
class CatalogHandler
|
6
6
|
def fetch(prefix, identifier)
|
7
7
|
client = RestClient::Resource.new(Dor::Config.metadata.catalog.url,
|
8
8
|
Dor::Config.metadata.catalog.user,
|
9
9
|
Dor::Config.metadata.catalog.pass)
|
10
|
-
|
10
|
+
params = "?#{prefix.chomp}=#{identifier.chomp}"
|
11
|
+
client[params].get
|
12
|
+
rescue RestClient::Exception => e
|
13
|
+
raise BadResponseFromCatalog, "#{e.class} - when contacting (with BasicAuth hidden): #{Dor::Config.metadata.catalog.url}#{params}"
|
11
14
|
end
|
12
15
|
|
13
16
|
def label(metadata)
|
@@ -20,5 +23,3 @@ handler = Class.new do
|
|
20
23
|
%w(catkey barcode)
|
21
24
|
end
|
22
25
|
end
|
23
|
-
|
24
|
-
Dor::MetadataService.register(handler)
|
@@ -1,37 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'cache'
|
4
|
+
require 'dor/services/metadata_handlers/catalog_handler'
|
4
5
|
|
5
6
|
module Dor
|
6
7
|
class MetadataError < RuntimeError; end
|
7
8
|
|
8
|
-
# class MetadataHandler
|
9
|
-
#
|
10
|
-
# def fetch(prefix, identifier)
|
11
|
-
# ### Return metadata for prefix/identifier combo
|
12
|
-
# end
|
13
|
-
#
|
14
|
-
# def label(metadata)
|
15
|
-
# ### Return a Fedora-compatible label from the metadata format returned by #fetch
|
16
|
-
# end
|
17
|
-
#
|
18
|
-
# end
|
19
|
-
|
20
9
|
class MetadataService
|
21
10
|
class << self
|
22
11
|
@@cache = Cache.new(nil, nil, 250, 300)
|
23
12
|
|
24
|
-
def register(handler_class)
|
25
|
-
%w(fetch label prefixes).each do |method|
|
26
|
-
raise TypeError, "Metadata handlers must define ##{method}" unless handler_class.instance_methods.include?(method) || handler_class.instance_methods.include?(method.to_sym)
|
27
|
-
end
|
28
|
-
handler = handler_class.new
|
29
|
-
handler.prefixes.each do |prefix|
|
30
|
-
handlers[prefix.to_sym] = handler
|
31
|
-
end
|
32
|
-
handler
|
33
|
-
end
|
34
|
-
|
35
13
|
def known_prefixes
|
36
14
|
handlers.keys
|
37
15
|
end
|
@@ -62,7 +40,7 @@ module Dor
|
|
62
40
|
|
63
41
|
def handler_for(prefix)
|
64
42
|
handler = handlers[prefix.to_sym]
|
65
|
-
raise MetadataError, "
|
43
|
+
raise MetadataError, "Unknown metadata prefix: #{prefix}" if handler.nil?
|
66
44
|
|
67
45
|
handler
|
68
46
|
end
|
@@ -70,12 +48,17 @@ module Dor
|
|
70
48
|
private
|
71
49
|
|
72
50
|
def handlers
|
73
|
-
@handlers ||= {}
|
51
|
+
@handlers ||= {}.tap do |md_handlers|
|
52
|
+
# There's only one. If additional handlers are added, will need to be registered here.
|
53
|
+
register(CatalogHandler.new, md_handlers)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def register(handler, md_handlers)
|
58
|
+
handler.prefixes.each do |prefix|
|
59
|
+
md_handlers[prefix.to_sym] = handler
|
60
|
+
end
|
74
61
|
end
|
75
62
|
end
|
76
63
|
end
|
77
64
|
end
|
78
|
-
|
79
|
-
Dir[File.join(File.dirname(__FILE__), 'metadata_handlers', '*.rb')].each do |handler_file|
|
80
|
-
load handler_file
|
81
|
-
end
|
@@ -24,9 +24,9 @@ module Dor
|
|
24
24
|
def open(opts = {})
|
25
25
|
# During local development, we need a way to open a new version even if the object has not been accessioned.
|
26
26
|
raise(Dor::Exception, 'Object net yet accessioned') unless
|
27
|
-
opts[:assume_accessioned] || Dor::Config.workflow.client.
|
27
|
+
opts[:assume_accessioned] || Dor::Config.workflow.client.lifecycle('dor', work.pid, 'accessioned')
|
28
28
|
raise Dor::VersionAlreadyOpenError, 'Object already opened for versioning' if open?
|
29
|
-
raise Dor::Exception, 'Object currently being accessioned' if Dor::Config.workflow.client.
|
29
|
+
raise Dor::Exception, 'Object currently being accessioned' if Dor::Config.workflow.client.active_lifecycle('dor', work.pid, 'submitted')
|
30
30
|
|
31
31
|
sdr_version = Sdr::Client.current_version work.pid
|
32
32
|
|
@@ -67,14 +67,14 @@ module Dor
|
|
67
67
|
|
68
68
|
raise Dor::Exception, 'latest version in versionMetadata requires tag and description before it can be closed' unless work.versionMetadata.current_version_closeable?
|
69
69
|
raise Dor::Exception, 'Trying to close version on an object not opened for versioning' unless open?
|
70
|
-
raise Dor::Exception, 'accessionWF already created for versioned object' if Dor::Config.workflow.client.
|
70
|
+
raise Dor::Exception, 'accessionWF already created for versioned object' if Dor::Config.workflow.client.active_lifecycle('dor', work.pid, 'submitted')
|
71
71
|
|
72
72
|
Dor::Config.workflow.client.close_version 'dor', work.pid, opts.fetch(:start_accession, true) # Default to creating accessionWF when calling close_version
|
73
73
|
end
|
74
74
|
|
75
75
|
# @return [Boolean] true if 'opened' lifecycle is active, false otherwise
|
76
76
|
def open?
|
77
|
-
return true if Dor::Config.workflow.client.
|
77
|
+
return true if Dor::Config.workflow.client.active_lifecycle('dor', work.pid, 'opened')
|
78
78
|
|
79
79
|
false
|
80
80
|
end
|
data/lib/dor/version.rb
CHANGED
@@ -4,21 +4,8 @@ module Dor
|
|
4
4
|
module Workflow
|
5
5
|
class Document
|
6
6
|
extend Deprecation
|
7
|
-
include SolrDocHelper
|
8
7
|
include ::OM::XML::Document
|
9
8
|
|
10
|
-
ERROR_OMISSION = '... (continued)'
|
11
|
-
private_constant :ERROR_OMISSION
|
12
|
-
|
13
|
-
# see https://lucene.apache.org/core/7_3_1/core/org/apache/lucene/util/BytesRefHash.MaxBytesLengthExceededException.html
|
14
|
-
MAX_ERROR_LENGTH = 32_768 - 2 - ERROR_OMISSION.length
|
15
|
-
private_constant :MAX_ERROR_LENGTH
|
16
|
-
|
17
|
-
WF_SOLR_TYPE = :string
|
18
|
-
private_constant :WF_SOLR_TYPE
|
19
|
-
WF_SOLR_ATTRS = [:symbol].freeze
|
20
|
-
private_constant :WF_SOLR_ATTRS
|
21
|
-
|
22
9
|
set_terminology do |t|
|
23
10
|
t.root(path: 'workflow')
|
24
11
|
t.repository(path: { attribute: 'repository' })
|
@@ -93,69 +80,9 @@ module Dor
|
|
93
80
|
end
|
94
81
|
end
|
95
82
|
|
96
|
-
def workflow_should_show_completed?(processes)
|
97
|
-
processes.all? { |p| ['skipped', 'completed', '', nil].include?(p.status) }
|
98
|
-
end
|
99
|
-
|
100
|
-
def to_solr(solr_doc = {}, *_args)
|
101
|
-
wf_name = workflowId.first
|
102
|
-
repo = repository.first
|
103
|
-
|
104
|
-
add_solr_value(solr_doc, 'wf', wf_name, WF_SOLR_TYPE, WF_SOLR_ATTRS)
|
105
|
-
add_solr_value(solr_doc, 'wf_wps', wf_name, WF_SOLR_TYPE, WF_SOLR_ATTRS)
|
106
|
-
add_solr_value(solr_doc, 'wf_wsp', wf_name, WF_SOLR_TYPE, WF_SOLR_ATTRS)
|
107
|
-
status = processes.empty? ? 'empty' : (workflow_should_show_completed?(processes) ? 'completed' : 'active')
|
108
|
-
errors = processes.count(&:error?)
|
109
|
-
add_solr_value(solr_doc, 'workflow_status', [wf_name, status, errors, repo].join('|'), WF_SOLR_TYPE, WF_SOLR_ATTRS)
|
110
|
-
|
111
|
-
processes.each do |process|
|
112
|
-
next unless process.status.present?
|
113
|
-
|
114
|
-
# add a record of the robot having operated on this item, so we can track robot activity
|
115
|
-
if !process.date_time.blank? && process.status && (process.status == 'completed' || process.status == 'error')
|
116
|
-
solr_doc["wf_#{wf_name}_#{process.name}_dttsi"] = Time.parse(process.date_time).utc.iso8601
|
117
|
-
end
|
118
|
-
|
119
|
-
index_error_message(solr_doc, wf_name, process)
|
120
|
-
|
121
|
-
add_solr_value(solr_doc, 'wf_wsp', "#{wf_name}:#{process.status}", WF_SOLR_TYPE, WF_SOLR_ATTRS)
|
122
|
-
add_solr_value(solr_doc, 'wf_wsp', "#{wf_name}:#{process.status}:#{process.name}", WF_SOLR_TYPE, WF_SOLR_ATTRS)
|
123
|
-
add_solr_value(solr_doc, 'wf_wps', "#{wf_name}:#{process.name}", WF_SOLR_TYPE, WF_SOLR_ATTRS)
|
124
|
-
add_solr_value(solr_doc, 'wf_wps', "#{wf_name}:#{process.name}:#{process.status}", WF_SOLR_TYPE, WF_SOLR_ATTRS)
|
125
|
-
add_solr_value(solr_doc, 'wf_swp', process.status.to_s, WF_SOLR_TYPE, WF_SOLR_ATTRS)
|
126
|
-
add_solr_value(solr_doc, 'wf_swp', "#{process.status}:#{wf_name}", WF_SOLR_TYPE, WF_SOLR_ATTRS)
|
127
|
-
add_solr_value(solr_doc, 'wf_swp', "#{process.status}:#{wf_name}:#{process.name}", WF_SOLR_TYPE, WF_SOLR_ATTRS)
|
128
|
-
next unless process.state != process.status
|
129
|
-
|
130
|
-
add_solr_value(solr_doc, 'wf_wsp', "#{wf_name}:#{process.state}:#{process.name}", WF_SOLR_TYPE, WF_SOLR_ATTRS)
|
131
|
-
add_solr_value(solr_doc, 'wf_wps', "#{wf_name}:#{process.name}:#{process.state}", WF_SOLR_TYPE, WF_SOLR_ATTRS)
|
132
|
-
add_solr_value(solr_doc, 'wf_swp', process.state.to_s, WF_SOLR_TYPE, WF_SOLR_ATTRS)
|
133
|
-
add_solr_value(solr_doc, 'wf_swp', "#{process.state}:#{wf_name}", WF_SOLR_TYPE, WF_SOLR_ATTRS)
|
134
|
-
add_solr_value(solr_doc, 'wf_swp', "#{process.state}:#{wf_name}:#{process.name}", WF_SOLR_TYPE, WF_SOLR_ATTRS)
|
135
|
-
end
|
136
|
-
|
137
|
-
solr_doc[Solrizer.solr_name('wf_wps', :symbol)]&.uniq!
|
138
|
-
solr_doc[Solrizer.solr_name('wf_wsp', :symbol)]&.uniq!
|
139
|
-
solr_doc[Solrizer.solr_name('wf_swp', :symbol)]&.uniq!
|
140
|
-
solr_doc['workflow_status']&.uniq!
|
141
|
-
|
142
|
-
solr_doc
|
143
|
-
end
|
144
|
-
|
145
83
|
def inspect
|
146
84
|
"#<#{self.class.name}:#{object_id}>"
|
147
85
|
end
|
148
|
-
|
149
|
-
private
|
150
|
-
|
151
|
-
# index the error message without the druid so we hopefully get some overlap
|
152
|
-
# truncate to avoid org.apache.lucene.util.BytesRefHash$MaxBytesLengthExceededException
|
153
|
-
def index_error_message(solr_doc, wf_name, process)
|
154
|
-
return unless process.error_message
|
155
|
-
|
156
|
-
error_message = "#{wf_name}:#{process.name}:#{process.error_message}".truncate(MAX_ERROR_LENGTH, omission: ERROR_OMISSION)
|
157
|
-
add_solr_value(solr_doc, 'wf_error', error_message, WF_SOLR_TYPE, WF_SOLR_ATTRS)
|
158
|
-
end
|
159
86
|
end
|
160
87
|
end
|
161
88
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dor-services
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.
|
4
|
+
version: 6.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Klein
|
@@ -14,7 +14,7 @@ authors:
|
|
14
14
|
autorequire:
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
|
-
date: 2019-03
|
17
|
+
date: 2019-04-03 00:00:00.000000000 Z
|
18
18
|
dependencies:
|
19
19
|
- !ruby/object:Gem::Dependency
|
20
20
|
name: active-fedora
|
@@ -290,20 +290,6 @@ dependencies:
|
|
290
290
|
- - "~>"
|
291
291
|
- !ruby/object:Gem::Version
|
292
292
|
version: '2.6'
|
293
|
-
- !ruby/object:Gem::Dependency
|
294
|
-
name: uuidtools
|
295
|
-
requirement: !ruby/object:Gem::Requirement
|
296
|
-
requirements:
|
297
|
-
- - "~>"
|
298
|
-
- !ruby/object:Gem::Version
|
299
|
-
version: 2.1.4
|
300
|
-
type: :runtime
|
301
|
-
prerelease: false
|
302
|
-
version_requirements: !ruby/object:Gem::Requirement
|
303
|
-
requirements:
|
304
|
-
- - "~>"
|
305
|
-
- !ruby/object:Gem::Version
|
306
|
-
version: 2.1.4
|
307
293
|
- !ruby/object:Gem::Dependency
|
308
294
|
name: retries
|
309
295
|
requirement: !ruby/object:Gem::Requirement
|
@@ -344,20 +330,14 @@ dependencies:
|
|
344
330
|
requirements:
|
345
331
|
- - "~>"
|
346
332
|
- !ruby/object:Gem::Version
|
347
|
-
version: '2.
|
348
|
-
- - ">="
|
349
|
-
- !ruby/object:Gem::Version
|
350
|
-
version: 2.0.1
|
333
|
+
version: '2.11'
|
351
334
|
type: :runtime
|
352
335
|
prerelease: false
|
353
336
|
version_requirements: !ruby/object:Gem::Requirement
|
354
337
|
requirements:
|
355
338
|
- - "~>"
|
356
339
|
- !ruby/object:Gem::Version
|
357
|
-
version: '2.
|
358
|
-
- - ">="
|
359
|
-
- !ruby/object:Gem::Version
|
360
|
-
version: 2.0.1
|
340
|
+
version: '2.11'
|
361
341
|
- !ruby/object:Gem::Dependency
|
362
342
|
name: druid-tools
|
363
343
|
requirement: !ruby/object:Gem::Requirement
|
@@ -624,6 +604,7 @@ files:
|
|
624
604
|
- lib/dor/indexers/processable_indexer.rb
|
625
605
|
- lib/dor/indexers/releasable_indexer.rb
|
626
606
|
- lib/dor/indexers/workflow_indexer.rb
|
607
|
+
- lib/dor/indexers/workflows_indexer.rb
|
627
608
|
- lib/dor/models/abstract.rb
|
628
609
|
- lib/dor/models/admin_policy_object.rb
|
629
610
|
- lib/dor/models/agreement.rb
|
@@ -647,6 +628,7 @@ files:
|
|
647
628
|
- lib/dor/models/item.rb
|
648
629
|
- lib/dor/models/set.rb
|
649
630
|
- lib/dor/models/workflow_object.rb
|
631
|
+
- lib/dor/models/workflow_solr_document.rb
|
650
632
|
- lib/dor/rest_resource_factory.rb
|
651
633
|
- lib/dor/services/ability.rb
|
652
634
|
- lib/dor/services/cleanup_reset_service.rb
|
@@ -654,6 +636,7 @@ files:
|
|
654
636
|
- lib/dor/services/create_workflow_service.rb
|
655
637
|
- lib/dor/services/creative_commons_license_service.rb
|
656
638
|
- lib/dor/services/datastream_builder.rb
|
639
|
+
- lib/dor/services/decommission_service.rb
|
657
640
|
- lib/dor/services/digital_stacks_service.rb
|
658
641
|
- lib/dor/services/dublin_core_service.rb
|
659
642
|
- lib/dor/services/file_metadata_merge_service.rb
|
@@ -667,7 +650,6 @@ files:
|
|
667
650
|
- lib/dor/services/public_desc_metadata_service.rb
|
668
651
|
- lib/dor/services/public_xml_service.rb
|
669
652
|
- lib/dor/services/publish_metadata_service.rb
|
670
|
-
- lib/dor/services/registration_service.rb
|
671
653
|
- lib/dor/services/release_tag_service.rb
|
672
654
|
- lib/dor/services/reset_workspace_service.rb
|
673
655
|
- lib/dor/services/sdr_ingest_service.rb
|
@@ -1,202 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'uuidtools'
|
4
|
-
|
5
|
-
module Dor
|
6
|
-
class RegistrationService
|
7
|
-
class << self
|
8
|
-
# @TODO: Why isn't all this logic in, for example, Dor::Item.create? or Dor::Base.create? or Dor::Creatable.create?
|
9
|
-
# @TODO: these duplicate checks could be combined into 1 query
|
10
|
-
|
11
|
-
# @param [String] pid an ID to check, if desired. If not passed (or nil), a new ID is minted
|
12
|
-
# @return [String] a pid you can use immidately, either freshly minted or your checked value
|
13
|
-
# @raise [Dor::DuplicateIdError]
|
14
|
-
def unduplicated_pid(pid = nil)
|
15
|
-
return Dor::SuriService.mint_id unless pid
|
16
|
-
|
17
|
-
existing_pid = SearchService.query_by_id(pid).first
|
18
|
-
raise Dor::DuplicateIdError.new(existing_pid), "An object with the PID #{pid} has already been registered." unless existing_pid.nil?
|
19
|
-
|
20
|
-
pid
|
21
|
-
end
|
22
|
-
|
23
|
-
# @param [String] source_id_string a fully qualified source:val or empty string
|
24
|
-
# @return [String] the same qualified source:id for immediate use
|
25
|
-
# @raise [Dor::DuplicateIdError]
|
26
|
-
def check_source_id(source_id_string)
|
27
|
-
return '' if source_id_string == ''
|
28
|
-
unless SearchService.query_by_id(source_id_string.to_s).first.nil?
|
29
|
-
raise Dor::DuplicateIdError.new(source_id_string), "An object with the source ID '#{source_id_string}' has already been registered."
|
30
|
-
end
|
31
|
-
|
32
|
-
source_id_string
|
33
|
-
end
|
34
|
-
|
35
|
-
# @param [Hash{Symbol => various}] params
|
36
|
-
# @option params [String] :object_type required
|
37
|
-
# @option params [String] :label required
|
38
|
-
# @option params [String] :admin_policy required
|
39
|
-
# @option params [String] :metadata_source
|
40
|
-
# @option params [String] :rights
|
41
|
-
# @option params [String] :collection
|
42
|
-
# @option params [Hash{String => String}] :source_id Primary ID from another system, max one key/value pair!
|
43
|
-
# @option params [Hash] :other_ids including :uuid if known
|
44
|
-
# @option params [String] :pid Fully qualified PID if you don't want one generated for you
|
45
|
-
# @option params [Integer] :workflow_priority]
|
46
|
-
# @option params [Array<String>] :seed_datastream datastream_names
|
47
|
-
# @option params [Array<String>] :initiate_workflow workflow_ids
|
48
|
-
# @option params [Array] :tags
|
49
|
-
def register_object(params = {})
|
50
|
-
%i[object_type label].each do |required_param|
|
51
|
-
raise Dor::ParameterError, "#{required_param.inspect} must be specified in call to #{name}.register_object" unless params[required_param]
|
52
|
-
end
|
53
|
-
metadata_source = params[:metadata_source]
|
54
|
-
raise Dor::ParameterError, "label cannot be empty to call #{name}.register_object" if params[:label].length < 1 && %w[label none].include?(metadata_source)
|
55
|
-
|
56
|
-
object_type = params[:object_type]
|
57
|
-
item_class = Dor.registered_classes[object_type]
|
58
|
-
raise Dor::ParameterError, "Unknown item type: '#{object_type}'" if item_class.nil?
|
59
|
-
|
60
|
-
# content_model = params[:content_model]
|
61
|
-
# parent = params[:parent]
|
62
|
-
label = params[:label]
|
63
|
-
source_id = params[:source_id] || {}
|
64
|
-
other_ids = params[:other_ids] || {}
|
65
|
-
tags = params[:tags] || []
|
66
|
-
collection = params[:collection]
|
67
|
-
|
68
|
-
# Check for sourceId conflict *before* potentially minting PID
|
69
|
-
source_id_string = check_source_id [source_id.keys.first, source_id[source_id.keys.first]].compact.join(':')
|
70
|
-
pid = unduplicated_pid(params[:pid])
|
71
|
-
|
72
|
-
raise ArgumentError, ":source_id Hash can contain at most 1 pair: recieved #{source_id.size}" if source_id.size > 1
|
73
|
-
|
74
|
-
rights = nil
|
75
|
-
if params[:rights]
|
76
|
-
rights = params[:rights]
|
77
|
-
raise Dor::ParameterError, "Unknown rights setting '#{rights}' when calling #{name}.register_object" unless rights == 'default' || RightsMetadataDS.valid_rights_type?(rights)
|
78
|
-
end
|
79
|
-
|
80
|
-
other_ids[:uuid] = UUIDTools::UUID.timestamp_create.to_s if (other_ids.key?(:uuid) || other_ids.key?('uuid')) == false
|
81
|
-
apo_object = Dor.find(params[:admin_policy])
|
82
|
-
new_item = item_class.new(pid: pid)
|
83
|
-
new_item.label = label.length > 254 ? label[0, 254] : label
|
84
|
-
idmd = new_item.identityMetadata
|
85
|
-
idmd.sourceId = source_id_string
|
86
|
-
idmd.add_value(:objectId, pid)
|
87
|
-
idmd.add_value(:objectCreator, 'DOR')
|
88
|
-
idmd.add_value(:objectLabel, label)
|
89
|
-
idmd.add_value(:objectType, object_type)
|
90
|
-
other_ids.each_pair { |name, value| idmd.add_otherId("#{name}:#{value}") }
|
91
|
-
tags.each { |tag| idmd.add_value(:tag, tag) }
|
92
|
-
new_item.admin_policy_object = apo_object
|
93
|
-
|
94
|
-
apo_object.administrativeMetadata.ng_xml.xpath('/administrativeMetadata/relationships/*').each do |rel|
|
95
|
-
short_predicate = ActiveFedora::RelsExtDatastream.short_predicate rel.namespace.href + rel.name
|
96
|
-
if short_predicate.nil?
|
97
|
-
ix = 0
|
98
|
-
ix += 1 while ActiveFedora::Predicates.predicate_mappings[rel.namespace.href].key?(short_predicate = :"extra_predicate_#{ix}")
|
99
|
-
ActiveFedora::Predicates.predicate_mappings[rel.namespace.href][short_predicate] = rel.name
|
100
|
-
end
|
101
|
-
new_item.add_relationship short_predicate, rel['rdf:resource']
|
102
|
-
end
|
103
|
-
new_item.add_collection(collection) if collection
|
104
|
-
if rights && %w(item collection).include?(object_type)
|
105
|
-
rights_xml = apo_object.defaultObjectRights.ng_xml
|
106
|
-
new_item.datastreams['rightsMetadata'].content = rights_xml.to_s
|
107
|
-
new_item.set_read_rights(rights) unless rights == 'default' # already defaulted to default!
|
108
|
-
end
|
109
|
-
# create basic mods from the label
|
110
|
-
build_desc_metadata_from_label(new_item, label) if metadata_source == 'label'
|
111
|
-
|
112
|
-
workflow_priority = params[:workflow_priority] ? params[:workflow_priority].to_i : 0
|
113
|
-
|
114
|
-
seed_datastreams(Array(params[:seed_datastream]), new_item)
|
115
|
-
initiate_workflow(workflows: Array(params[:initiate_workflow]), item: new_item, priority: workflow_priority)
|
116
|
-
|
117
|
-
new_item.class.ancestors.select { |x| x.respond_to?(:to_class_uri) && x != ActiveFedora::Base }.each do |parent_class|
|
118
|
-
new_item.add_relationship(:has_model, parent_class.to_class_uri)
|
119
|
-
end
|
120
|
-
|
121
|
-
new_item.save
|
122
|
-
new_item
|
123
|
-
end
|
124
|
-
|
125
|
-
# @param [Hash] params
|
126
|
-
# @see register_object similar but different
|
127
|
-
def create_from_request(params)
|
128
|
-
other_ids = Array(params[:other_id]).map do |id|
|
129
|
-
if id =~ /^symphony:(.+)$/
|
130
|
-
"#{$1.length < 14 ? 'catkey' : 'barcode'}:#{$1}"
|
131
|
-
else
|
132
|
-
id
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
if params[:label] == ':auto'
|
137
|
-
params.delete(:label)
|
138
|
-
params.delete('label')
|
139
|
-
metadata_id = Dor::MetadataService.resolvable(other_ids).first
|
140
|
-
params[:label] = Dor::MetadataService.label_for(metadata_id)
|
141
|
-
end
|
142
|
-
|
143
|
-
dor_params = {
|
144
|
-
pid: params[:pid],
|
145
|
-
admin_policy: params[:admin_policy],
|
146
|
-
content_model: params[:model],
|
147
|
-
label: params[:label],
|
148
|
-
object_type: params[:object_type],
|
149
|
-
other_ids: ids_to_hash(other_ids),
|
150
|
-
parent: params[:parent],
|
151
|
-
source_id: ids_to_hash(params[:source_id]),
|
152
|
-
tags: params[:tag] || [],
|
153
|
-
seed_datastream: params[:seed_datastream],
|
154
|
-
initiate_workflow: Array(params[:initiate_workflow]) + Array(params[:workflow_id]),
|
155
|
-
rights: params[:rights],
|
156
|
-
metadata_source: params[:metadata_source],
|
157
|
-
collection: params[:collection],
|
158
|
-
workflow_priority: params[:workflow_priority]
|
159
|
-
}
|
160
|
-
dor_params.delete_if { |_k, v| v.nil? }
|
161
|
-
|
162
|
-
dor_obj = register_object(dor_params)
|
163
|
-
pid = dor_obj.pid
|
164
|
-
location = URI.parse(Dor::Config.fedora.safeurl.sub(/\/*$/, '/')).merge("objects/#{pid}").to_s
|
165
|
-
dor_params.dup.merge(location: location, pid: pid)
|
166
|
-
end
|
167
|
-
|
168
|
-
private
|
169
|
-
|
170
|
-
def ids_to_hash(ids)
|
171
|
-
return nil if ids.nil?
|
172
|
-
|
173
|
-
Hash[Array(ids).map { |id| id.split(':', 2) }]
|
174
|
-
end
|
175
|
-
|
176
|
-
def seed_datastreams(names, item)
|
177
|
-
names.each do |datastream_name|
|
178
|
-
item.build_datastream(datastream_name)
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
def initiate_workflow(workflows:, item:, priority:)
|
183
|
-
workflows.each do |workflow_id|
|
184
|
-
Dor::CreateWorkflowService.create_workflow(item, name: workflow_id,
|
185
|
-
create_ds: !item.new_record?,
|
186
|
-
priority: priority)
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
|
-
def build_desc_metadata_from_label(new_item, label)
|
191
|
-
builder = Nokogiri::XML::Builder.new do |xml|
|
192
|
-
xml.mods(Dor::DescMetadataDS::MODS_HEADER_CONFIG) do
|
193
|
-
xml.titleInfo do
|
194
|
-
xml.title label
|
195
|
-
end
|
196
|
-
end
|
197
|
-
end
|
198
|
-
new_item.descMetadata.content = builder.to_xml
|
199
|
-
end
|
200
|
-
end
|
201
|
-
end
|
202
|
-
end
|