dor-services 6.8.0 → 7.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.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/config/config_defaults.yml +0 -27
  3. data/config/dev_console_env.rb.example +0 -17
  4. data/lib/dor-services.rb +9 -73
  5. data/lib/dor/config.rb +1 -30
  6. data/lib/dor/datastreams/content_metadata_ds.rb +8 -0
  7. data/lib/dor/datastreams/desc_metadata_ds.rb +19 -0
  8. data/lib/dor/datastreams/identity_metadata_ds.rb +65 -0
  9. data/lib/dor/datastreams/rights_metadata_ds.rb +14 -2
  10. data/lib/dor/datastreams/workflow_definition_ds.rb +1 -1
  11. data/lib/dor/datastreams/workflow_ds.rb +0 -15
  12. data/lib/dor/indexers/identifiable_indexer.rb +8 -4
  13. data/lib/dor/indexers/releasable_indexer.rb +7 -1
  14. data/lib/dor/models/abstract.rb +143 -8
  15. data/lib/dor/models/admin_policy_object.rb +0 -3
  16. data/lib/dor/models/collection.rb +0 -2
  17. data/lib/dor/models/concerns/embargoable.rb +7 -60
  18. data/lib/dor/models/etd.rb +100 -0
  19. data/lib/dor/models/item.rb +12 -28
  20. data/lib/dor/models/part.rb +18 -0
  21. data/lib/dor/models/set.rb +0 -2
  22. data/lib/dor/services/collection_service.rb +36 -0
  23. data/lib/dor/services/embargo_service.rb +93 -0
  24. data/lib/dor/services/ontology.rb +0 -18
  25. data/lib/dor/services/public_desc_metadata_service.rb +7 -11
  26. data/lib/dor/services/search_service.rb +0 -40
  27. data/lib/dor/version.rb +1 -1
  28. data/lib/dor/workflow/document.rb +0 -7
  29. metadata +15 -78
  30. data/lib/dor/models/concerns/assembleable.rb +0 -18
  31. data/lib/dor/models/concerns/contentable.rb +0 -185
  32. data/lib/dor/models/concerns/describable.rb +0 -82
  33. data/lib/dor/models/concerns/eventable.rb +0 -18
  34. data/lib/dor/models/concerns/geoable.rb +0 -14
  35. data/lib/dor/models/concerns/governable.rb +0 -101
  36. data/lib/dor/models/concerns/identifiable.rb +0 -172
  37. data/lib/dor/models/concerns/itemizable.rb +0 -42
  38. data/lib/dor/models/concerns/preservable.rb +0 -46
  39. data/lib/dor/models/concerns/processable.rb +0 -86
  40. data/lib/dor/models/concerns/publishable.rb +0 -76
  41. data/lib/dor/models/concerns/releaseable.rb +0 -118
  42. data/lib/dor/models/concerns/rightsable.rb +0 -25
  43. data/lib/dor/models/concerns/shelvable.rb +0 -15
  44. data/lib/dor/models/concerns/versionable.rb +0 -72
  45. data/lib/dor/services/ability.rb +0 -77
  46. data/lib/dor/services/cleanup_reset_service.rb +0 -103
  47. data/lib/dor/services/datastream_builder.rb +0 -96
  48. data/lib/dor/services/decommission_service.rb +0 -31
  49. data/lib/dor/services/digital_stacks_service.rb +0 -125
  50. data/lib/dor/services/dublin_core_service.rb +0 -45
  51. data/lib/dor/services/file_metadata_merge_service.rb +0 -71
  52. data/lib/dor/services/indexing_service.rb +0 -131
  53. data/lib/dor/services/merge_service.rb +0 -105
  54. data/lib/dor/services/public_xml_service.rb +0 -116
  55. data/lib/dor/services/publish_metadata_service.rb +0 -99
  56. data/lib/dor/services/reset_workspace_service.rb +0 -27
  57. data/lib/dor/services/sdr_ingest_service.rb +0 -172
  58. data/lib/dor/services/secondary_file_name_service.rb +0 -10
  59. data/lib/dor/services/shelving_service.rb +0 -69
  60. data/lib/dor/services/technical_metadata_service.rb +0 -232
  61. data/lib/dor/services/version_service.rb +0 -84
  62. data/lib/dor/utils/sdr_client.rb +0 -94
@@ -1,71 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Dor
4
- # Merges contentMetadata from several objects into one.
5
- class FileMetadataMergeService
6
- extend Deprecation
7
- self.deprecation_horizon = 'dor-services version 7.0.0'
8
-
9
- # @param [Array<String>] secondary_druids ids of the secondary objects that will get their contentMetadata merged into this one
10
- def self.copy_file_resources(primary, secondary_druids)
11
- merge_service = FileMetadataMergeService.new primary, secondary_druids
12
- merge_service.copy_file_resources
13
- end
14
-
15
- def initialize(primary, secondary_druids)
16
- @pid = primary.pid
17
- content_metadata = primary.contentMetadata
18
- content_metadata.ng_xml_will_change!
19
- @primary_cm = content_metadata.ng_xml
20
- @secondary_druids = secondary_druids
21
- end
22
-
23
- # Appends contentMetadata file resources from the source objects to this object
24
- def copy_file_resources
25
- base_id = primary_cm.at_xpath('/contentMetadata/@objectId').value
26
- max_sequence = primary_cm.at_xpath('/contentMetadata/resource[last()]/@sequence').value.to_i
27
-
28
- secondary_druids.each do |src_pid|
29
- source_obj = Dor.find src_pid
30
- source_cm = source_obj.contentMetadata.ng_xml
31
-
32
- # Copy the resources from each source object
33
- source_cm.xpath('/contentMetadata/resource').each do |old_resource|
34
- max_sequence += 1
35
- resource_copy = old_resource.clone
36
- resource_copy['sequence'] = max_sequence.to_s
37
-
38
- # Append sequence number to each secondary filename, then
39
- # look for filename collisions with the primary object
40
- resource_copy.xpath('file').each do |secondary_file|
41
- secondary_file['id'] = SecondaryFileNameService.create(secondary_file['id'], max_sequence)
42
-
43
- if primary_cm.at_xpath("//file[@id = '#{secondary_file['id']}']")
44
- raise Dor::Exception, "File '#{secondary_file['id']}' from secondary object #{src_pid} already exist in primary object: #{pid}"
45
- end
46
- end
47
-
48
- if old_resource['type']
49
- resource_copy['id'] = "#{old_resource['type']}_#{max_sequence}"
50
- else
51
- resource_copy['id'] = "#{base_id}_#{max_sequence}"
52
- end
53
-
54
- lbl = old_resource.at_xpath 'label'
55
- resource_copy.at_xpath('label').content = "#{Regexp.last_match(1)} #{max_sequence}" if lbl && lbl.text =~ /^(.*)\s+\d+$/
56
-
57
- primary_cm.at_xpath('/contentMetadata/resource[last()]').add_next_sibling resource_copy
58
- attr_node = primary_cm.create_element 'attr', src_pid, name: 'mergedFromPid'
59
- resource_copy.first_element_child.add_previous_sibling attr_node
60
- attr_node = primary_cm.create_element 'attr', old_resource['id'], name: 'mergedFromResource'
61
- resource_copy.first_element_child.add_previous_sibling attr_node
62
- end
63
- end
64
- end
65
- deprecation_deprecate copy_file_resources: 'No longer used by any DLSS code'
66
-
67
- private
68
-
69
- attr_reader :secondary_druids, :primary_cm, :pid
70
- end
71
- end
@@ -1,131 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'benchmark'
4
-
5
- module Dor
6
- class IndexingService
7
- extend Deprecation
8
-
9
- class ReindexError < RuntimeError; end
10
-
11
- ##
12
- # Returns a Logger instance for recording info about indexing attempts
13
- # @yield attempt to execute 'entry_id_block' and use the result as an extra identifier for the log
14
- # entry. a placeholder will be used otherwise. 'request.uuid' might be useful in a Rails app.
15
- def self.generate_index_logger(&entry_id_block)
16
- Deprecation.warn(self, 'generate_index_logger is deprecated and will be removed in dor-services version 7')
17
- index_logger = Logger.new(Config.indexing_svc.log, Config.indexing_svc.log_rotation_interval)
18
- index_logger.formatter = proc do |_severity, datetime, _progname, msg|
19
- date_format_str = Config.indexing_svc.log_date_format_str
20
- entry_id = begin begin
21
- entry_id_block.call
22
- rescue StandardError
23
- '---'
24
- end end
25
- "[#{entry_id}] [#{datetime.utc.strftime(date_format_str)}] #{msg}\n"
26
- end
27
- index_logger
28
- end
29
-
30
- # memoize the loggers we create in a hash, init with a nil default logger
31
- @@loggers = { default: nil }
32
-
33
- def self.default_index_logger
34
- Deprecation.warn(self, 'default_index_logger is deprecated and will be removed in dor-services version 7')
35
- @@loggers[:default] ||= generate_index_logger
36
- end
37
-
38
- # takes a Dor object and indexes it to solr. doesn't commit automatically.
39
- def self.reindex_object(obj, options = {})
40
- Deprecation.warn(self, 'reindex_pid is deprecated and will be removed in dor-services 7.')
41
- solr_doc = obj.to_solr
42
- Dor::SearchService.solr.add(solr_doc, options)
43
- solr_doc
44
- end
45
-
46
- # Use the dor-indexing-app service to reindex a pid
47
- # @param [String] pid the druid
48
- # @raise [ReindexError] on failure
49
- def self.reindex_pid_remotely(pid)
50
- Deprecation.warn(self, 'reindex_pid_remotely is deprecated and will be removed in dor-services 7.')
51
-
52
- pid = "druid:#{pid}" unless pid =~ /^druid:/
53
- realtime = Benchmark.realtime do
54
- with_retries(max_tries: 3, rescue: [RestClient::Exception, Errno::ECONNREFUSED]) do
55
- RestClient.post("#{Config.dor_indexing_app.url}/reindex/#{pid}", '')
56
- end
57
- end
58
- default_index_logger.info "successfully updated index for #{pid} in #{'%.3f' % realtime}s"
59
- rescue RestClient::Exception, Errno::ECONNREFUSED => e
60
- msg = "failed to reindex #{pid}: #{e}"
61
- default_index_logger.error msg
62
- raise ReindexError.new(msg)
63
- rescue StandardError => e
64
- default_index_logger.error "failed to reindex #{pid}: #{e}"
65
- raise
66
- end
67
-
68
- # retrieves a single Dor object by pid, indexes the object to solr, does some logging
69
- # (will use a default logger if one is not provided). doesn't commit automatically.
70
- #
71
- # WARNING/TODO: the tests indicate that the "rescue Exception" block at the end will
72
- # get skipped, and the thrown exception (e.g. SystemStackError) will not be logged. since
73
- # that's the only consequence, and the exception bubbles up as we would want anyway, it
74
- # doesn't seem worth blocking refactoring. see https://github.com/sul-dlss/dor-services/issues/156
75
- # extra logging in this case would be nice, but centralized indexing that's otherwise
76
- # fully functional is nicer.
77
- #
78
- # @overload reindex_pid(pid, index_logger, options = {})
79
- # @overload reindex_pid(pid, index_logger, should_raise_errors, options = {})
80
- # @overload reindex_pid(pid, options = {})
81
- def self.reindex_pid(pid, *args)
82
- Deprecation.warn(self, 'reindex_pid is deprecated and will be removed in dor-services 7.')
83
- options = {}
84
- options = args.pop if args.last.is_a? Hash
85
-
86
- if args.length > 0
87
- warn 'Dor::IndexingService.reindex_pid with primitive arguments is deprecated; pass e.g. { logger: logger, raise_errors: bool } instead'
88
- index_logger, should_raise_errors = args
89
- index_logger ||= default_index_logger
90
- should_raise_errors = true if should_raise_errors.nil?
91
- else
92
- index_logger = options.fetch(:logger, default_index_logger)
93
- should_raise_errors = options.fetch(:raise_errors, true)
94
- end
95
-
96
- obj = nil
97
- solr_doc = nil
98
-
99
- # benchmark how long it takes to load the object
100
- load_stats = Benchmark.measure('find') do
101
- obj = Dor.find pid
102
- end.format('%n realtime %rs total CPU %ts').gsub(/[\(\)]/, '')
103
-
104
- # benchmark how long it takes to convert the object to a Solr document
105
- to_solr_stats = Benchmark.measure('to_solr') do
106
- solr_doc = reindex_object obj, options
107
- end.format('%n realtime %rs total CPU %ts').gsub(/[\(\)]/, '')
108
-
109
- index_logger.info "successfully updated index for #{pid} (metrics: #{load_stats}; #{to_solr_stats})"
110
-
111
- solr_doc
112
- rescue StandardError => se
113
- if se.is_a? ActiveFedora::ObjectNotFoundError
114
- index_logger.warn "failed to update index for #{pid}, object not found in Fedora"
115
- else
116
- index_logger.warn "failed to update index for #{pid}, unexpected StandardError, see main app log: #{se.backtrace}"
117
- end
118
- raise se if should_raise_errors
119
- rescue Exception => ex
120
- index_logger.error "failed to update index for #{pid}, unexpected Exception, see main app log: #{ex.backtrace}"
121
- raise ex # don't swallow anything worse than StandardError
122
- end
123
-
124
- # given a list of pids, retrieve those objects from fedora, index each to solr, optionally commit
125
- def self.reindex_pid_list(pid_list, should_commit = false)
126
- Deprecation.warn(self, 'reindex_pid_list is deprecated and will be removed in dor-services 7')
127
- pid_list.each { |pid| reindex_pid pid, raise_errors: false } # use the default logger, don't let individual errors nuke the rest of the batch
128
- ActiveFedora.solr.conn.commit if should_commit
129
- end
130
- end
131
- end
@@ -1,105 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Dor
4
- class MergeService
5
- extend Deprecation
6
- self.deprecation_horizon = 'dor-services version 7.0.0'
7
-
8
- def self.merge_into_primary(primary_druid, secondary_druids, tag, logger = nil)
9
- # TODO: test the secondary_obj to see if we've processed it already
10
- merge_service = Dor::MergeService.new primary_druid, secondary_druids, tag, logger
11
- merge_service.check_objects_editable
12
- merge_service.move_metadata_and_content
13
- merge_service.decommission_secondaries
14
- # kick off commonAccessioning for the primary?
15
- end
16
-
17
- def initialize(primary_druid, secondary_pids, tag, logger = nil)
18
- @primary = Dor.find primary_druid
19
- @secondary_pids = secondary_pids
20
- @secondary_objs = secondary_pids.map { |pid| Dor.find pid }
21
- if logger.nil?
22
- @logger = Logger.new(STDERR)
23
- else
24
- @logger = logger
25
- end
26
- @tag = tag
27
- end
28
-
29
- def check_objects_editable
30
- raise Dor::Exception, "Primary object is not editable: #{@primary.pid}" unless @primary.allows_modification?
31
-
32
- non_editable = @secondary_objs.detect { |obj| !obj.allows_modification? }
33
- raise Dor::Exception, "Secondary object is not editable: #{non_editable.pid}" if non_editable
34
- end
35
- deprecation_deprecate check_objects_editable: 'No longer used by any DLSS code'
36
-
37
- def move_metadata_and_content
38
- FileMetadataMergeService.copy_file_resources @primary, @secondary_pids
39
- @primary.save
40
- copy_workspace_content
41
- end
42
- deprecation_deprecate move_metadata_and_content: 'No longer used by any DLSS code'
43
-
44
- # Copies the content from the secondary object workspace to the primary object's workspace
45
- # Depends on Dor::Config.stacks.local_workspace_root
46
- def copy_workspace_content
47
- pri_file = @primary.contentMetadata.resource(0).file(0).id.first
48
- pri_druid = DruidTools::Druid.new @primary.pid, Dor::Config.stacks.local_workspace_root
49
- dest_path = pri_druid.find_filelist_parent 'content', pri_file
50
- primary_cm = @primary.contentMetadata.ng_xml
51
-
52
- @secondary_objs.each do |secondary|
53
- sec_druid = DruidTools::Druid.new secondary.pid, Dor::Config.stacks.local_workspace_root
54
- secondary.contentMetadata.ng_xml.xpath('//resource').each do |src_resource|
55
- primary_resource = primary_cm.at_xpath "//resource[attr[@name = 'mergedFromPid']/text() = '#{secondary.pid}' and
56
- attr[@name = 'mergedFromResource']/text() = '#{src_resource['id']}' ]"
57
- sequence = primary_resource['sequence']
58
- src_resource.xpath('//file/@id').map(&:value).each do |file_id|
59
- copy_path = sec_druid.find_content file_id
60
- new_name = SecondaryFileNameService.create(file_id, sequence)
61
- # TODO: verify new_name exists in primary_cm?
62
- FileUtils.cp(copy_path, File.join(dest_path, "/#{new_name}"))
63
- end
64
- end
65
- end
66
- end
67
- deprecation_deprecate copy_workspace_content: 'No longer used by any DLSS code'
68
-
69
- def decommission_secondaries
70
- @secondary_objs.each do |secondary_obj|
71
- begin
72
- @current_secondary = secondary_obj
73
- @current_secondary.decommission @tag
74
- @current_secondary.save
75
-
76
- unshelve
77
- unpublish
78
- Dor::CleanupService.cleanup_by_druid @current_secondary.pid
79
- Dor::Config.workflow.client.archive_active_workflow 'dor', @current_secondary.pid
80
- rescue StandardError => e
81
- @logger.error "Unable to decommission #{@current_secondary.pid} with primary object #{@primary.pid}: #{e.inspect}"
82
- @logger.error e.backtrace.join("\n")
83
- end
84
- end
85
- end
86
- deprecation_deprecate decommission_secondaries: 'No longer used by any DLSS code'
87
-
88
- alias decomission_secondaries decommission_secondaries
89
- deprecate decomission_secondaries: 'Use decommission_secondaries instead'
90
-
91
- # Remove content from stacks
92
- # TODO: might set workflow status in future for robot to do
93
- def unshelve
94
- DigitalStacksService.prune_stacks_dir @current_secondary.pid
95
- end
96
- deprecation_deprecate unshelve: 'No longer used by any DLSS code'
97
-
98
- # Withdraw item from Purl
99
- # TODO: might set workflow status in future for robot to do
100
- def unpublish
101
- @current_secondary.publish_metadata
102
- end
103
- deprecation_deprecate unpublish: 'No longer used by any DLSS code'
104
- end
105
- end
@@ -1,116 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Dor
4
- class PublicXmlService
5
- attr_reader :object
6
-
7
- def initialize(object)
8
- @object = object
9
- end
10
-
11
- def to_xml
12
- pub = Nokogiri::XML('<publicObject/>').root
13
- pub['id'] = object.pid
14
- pub['published'] = Time.now.utc.xmlschema
15
- pub['publishVersion'] = 'dor-services/' + Dor::VERSION
16
-
17
- pub.add_child(public_identity_metadata.root) # add in modified identityMetadata datastream
18
- pub.add_child(public_content_metadata.root) if public_content_metadata.xpath('//resource').any?
19
- pub.add_child(public_rights_metadata.root)
20
-
21
- pub.add_child(public_relationships.root) unless public_relationships.nil? # TODO: Should never be nil in practice; working around an ActiveFedora quirk for testing
22
- pub.add_child(DublinCoreService.new(object).ng_xml.root)
23
- pub.add_child(PublicDescMetadataService.new(object).ng_xml.root)
24
- pub.add_child(release_xml.root) unless release_xml.xpath('//release').children.size == 0 # If there are no release_tags, this prevents an empty <releaseData/> from being added
25
- # Note we cannot base this on if an individual object has release tags or not, because the collection may cause one to be generated for an item,
26
- # so we need to calculate it and then look at the final result.
27
-
28
- thumb = ThumbnailService.new(object).thumb
29
- pub.add_child(Nokogiri("<thumb>#{thumb}</thumb>").root) unless thumb.nil?
30
-
31
- new_pub = Nokogiri::XML(pub.to_xml, &:noblanks)
32
- new_pub.encoding = 'UTF-8'
33
- new_pub.to_xml
34
- end
35
-
36
- # Generate XML structure for inclusion to Purl
37
- # @return [String] The XML release node as a string, with ReleaseDigest as the root document
38
- def release_xml
39
- @release_xml ||= begin
40
- builder = Nokogiri::XML::Builder.new do |xml|
41
- xml.releaseData do
42
- object.released_for.each do |project, released_value|
43
- xml.release(released_value['release'], to: project)
44
- end
45
- end
46
- end
47
- Nokogiri::XML(builder.to_xml)
48
- end
49
- end
50
-
51
- def public_relationships
52
- @public_relationships ||= object.public_relationships.clone
53
- end
54
-
55
- def public_rights_metadata
56
- @public_rights_metadata ||= object.datastreams['rightsMetadata'].ng_xml.clone
57
- end
58
-
59
- def public_identity_metadata
60
- @public_identity_metadata ||= begin
61
- im = object.datastreams['identityMetadata'].ng_xml.clone
62
- im.search('//release').each(&:remove) # remove any <release> tags from public xml which have full history
63
- im
64
- end
65
- end
66
-
67
- # @return [Nokogiri::XML::Document] sanitized for public consumption
68
- def public_content_metadata
69
- return Nokogiri::XML::Document.new unless object.datastreams['contentMetadata']
70
-
71
- @public_content_metadata ||= begin
72
- result = object.datastreams['contentMetadata'].ng_xml.clone
73
-
74
- # remove any resources or attributes that are not destined for the public XML
75
- result.xpath('/contentMetadata/resource[not(file[(@deliver="yes" or @publish="yes")]|externalFile)]').each(&:remove)
76
- result.xpath('/contentMetadata/resource/file[not(@deliver="yes" or @publish="yes")]').each(&:remove)
77
- result.xpath('/contentMetadata/resource/file').xpath('@preserve|@shelve|@publish|@deliver').each(&:remove)
78
- result.xpath('/contentMetadata/resource/file/checksum').each(&:remove)
79
-
80
- # support for dereferencing links via externalFile element(s) to the source (child) item - see JUMBO-19
81
- result.xpath('/contentMetadata/resource/externalFile').each do |external_file|
82
- add_data_from_src(external_file)
83
- end
84
-
85
- result
86
- end
87
- end
88
-
89
- def add_data_from_src(external_file)
90
- # enforce pre-conditions that resourceId, objectId, fileId are required
91
- src_resource_id = external_file['resourceId']
92
- src_druid = external_file['objectId']
93
- src_file_id = external_file['fileId']
94
- raise DataError, "Malformed externalFile data: #{external_file.to_xml}" if [src_resource_id, src_file_id, src_druid].map(&:blank?).any?
95
-
96
- # grab source item
97
- src_item = Dor.find(src_druid)
98
-
99
- # locate and extract the resourceId/fileId elements
100
- doc = src_item.contentMetadata.ng_xml
101
- src_resource = doc.at_xpath("//resource[@id=\"#{src_resource_id}\"]")
102
- src_file = src_resource.at_xpath("file[@id=\"#{src_file_id}\"]")
103
- raise DataError, "Unable to find a file node with id=\"#{src_file_id}\" (child of #{object.pid})" unless src_file
104
-
105
- src_image_data = src_file.at_xpath('imageData')
106
-
107
- # always use title regardless of whether a child label is present
108
- src_label = doc.create_element('label')
109
- src_label.content = src_item.full_title
110
-
111
- # add the extracted label and imageData
112
- external_file.add_previous_sibling(src_label)
113
- external_file << src_image_data unless src_image_data.nil?
114
- end
115
- end
116
- end
@@ -1,99 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Dor
4
- # Merges contentMetadata from several objects into one.
5
- class PublishMetadataService
6
- # @param [Dor::Item] item the object to be publshed
7
- def self.publish(item)
8
- new(item).publish
9
- end
10
-
11
- def initialize(item)
12
- @item = item
13
- end
14
-
15
- # Appends contentMetadata file resources from the source objects to this object
16
- def publish
17
- return unpublish unless world_discoverable?
18
-
19
- transfer_metadata
20
- publish_notify_on_success
21
- end
22
-
23
- private
24
-
25
- attr_reader :item
26
-
27
- def transfer_metadata
28
- transfer_to_document_store(DublinCoreService.new(item).ng_xml.to_xml(&:no_declaration), 'dc')
29
- %w(identityMetadata contentMetadata rightsMetadata).each do |stream|
30
- transfer_to_document_store(item.datastreams[stream].content.to_s, stream) if item.datastreams[stream]
31
- end
32
- transfer_to_document_store(PublicXmlService.new(item).to_xml, 'public')
33
- transfer_to_document_store(PublicDescMetadataService.new(item).to_xml, 'mods')
34
- end
35
-
36
- # Clear out the document cache for this item
37
- def unpublish
38
- purl_druid.prune!
39
- publish_delete_on_success
40
- end
41
-
42
- def world_discoverable?
43
- rights = item.rightsMetadata.ng_xml.clone.remove_namespaces!
44
- rights.at_xpath("//rightsMetadata/access[@type='discover']/machine/world")
45
- end
46
-
47
- # Create a file inside the content directory under the stacks.local_document_cache_root
48
- # @param [String] content The contents of the file to be created
49
- # @param [String] filename The name of the file to be created
50
- # @return [void]
51
- def transfer_to_document_store(content, filename)
52
- new_file = File.join(purl_druid.content_dir, filename)
53
- File.open(new_file, 'w') { |f| f.write content }
54
- end
55
-
56
- def purl_druid
57
- @purl_druid ||= DruidTools::PurlDruid.new item.pid, Config.stacks.local_document_cache_root
58
- end
59
-
60
- def prune_purl_dir
61
- purl_druid.prune!
62
- end
63
-
64
- ##
65
- # When publishing a PURL, we notify purl-fetcher of changes.
66
- # If the purl service isn't configured, instead we drop a `aa11bb2222` file into the `local_recent_changes` folder
67
- # to notify other applications watching the filesystem (i.e., purl-fetcher).
68
- # We also remove any .deletes entry that may have left over from a previous removal
69
- def publish_notify_on_success
70
- id = item.pid.gsub(/^druid:/, '')
71
- if Dor::Config.purl_services.url
72
- purl_services = Dor::Config.purl_services.rest_client
73
- purl_services["purls/#{id}"].post ''
74
- else
75
- Deprecation.warn(self, 'You have not configured perl-fetcher (Dor::Config.purl_services.url). This will result in an error in dor-services 7 ')
76
- local_recent_changes = Config.stacks.local_recent_changes
77
- raise ArgumentError, "Missing local_recent_changes directory: #{local_recent_changes}" unless File.directory?(local_recent_changes)
78
-
79
- FileUtils.touch(File.join(local_recent_changes, id))
80
- begin
81
- DruidTools::Druid.new(id, Dor::Config.stacks.local_document_cache_root).deletes_delete_record
82
- rescue Errno::EACCES
83
- Dor.logger.warn "Access denied while trying to remove .deletes file for druid:#{id}"
84
- end
85
- end
86
- end
87
-
88
- ##
89
- # When publishing a PURL, we notify purl-fetcher of changes.
90
- def publish_delete_on_success
91
- return unless Dor::Config.purl_services.url
92
-
93
- id = item.pid.gsub(/^druid:/, '')
94
-
95
- purl_services = Dor::Config.purl_services.rest_client
96
- purl_services["purls/#{id}"].delete
97
- end
98
- end
99
- end