diff --git a/.rubocop.yml b/.rubocop.yml
index 6adcedabc5..3ccb3f3142 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -1,3 +1,4 @@
+
inherit_from: .rubocop_todo.yml
require:
@@ -14,6 +15,9 @@ AllCops:
Rails:
Enabled: true
+Lint/AssignmentInCondition:
+ Enabled: false
+
Lint/UnusedMethodArgument:
AllowUnusedKeywordArguments: true
diff --git a/app/controllers/metadata_controller.rb b/app/controllers/metadata_controller.rb
index 3ebb80e3b3..e3f9ea0f2a 100644
--- a/app/controllers/metadata_controller.rb
+++ b/app/controllers/metadata_controller.rb
@@ -13,4 +13,24 @@ def descriptive
service = PublicDescMetadataService.new(@item)
render xml: service
end
+
+ # This supports the Legacy Fedora 3 data model. This is used by the accessionWF.
+ def update_legacy_metadata
+ datastream_names = { descriptive: 'descMetadata',
+ technical: 'technicalMetadata',
+ content: 'contentMetadata',
+ rights: 'rightsMetadata' }
+
+ datastream_names.each do |section, datastream_name|
+ next unless values = params[section]
+
+ update_datastream_if_newer(datastream: @item.datastreams[datastream_name],
+ updated: Time.zone.parse(values[:updated]),
+ content: values[:content])
+ end
+
+ @item.save!
+ end
+
+ delegate :update_datastream_if_newer, to: LegacyMetadataService
end
diff --git a/app/services/legacy_metadata_service.rb b/app/services/legacy_metadata_service.rb
new file mode 100644
index 0000000000..20e8aebbd2
--- /dev/null
+++ b/app/services/legacy_metadata_service.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+# Operations on the legacy Fedora 3 metadata.
+# This is used by the accessionWF
+class LegacyMetadataService
+ # If the updated value is newer than then createDate of the datastream, then update it.
+ def self.update_datastream_if_newer(datastream:, updated:, content:)
+ datastream.content = content if !datastream.createDate || updated > datastream.createDate
+ return if !datastream.createDate || updated > datastream.createDate
+
+ Honeybadger.notify("Found #{datasteam.pid}/#{datastream.dsid} that had a create " \
+ "date (#{datastream.createDate}) after the file was modified (#{updated}). " \
+ 'Doing an experiment to see if this ever happens.')
+ end
+end
diff --git a/config/routes.rb b/config/routes.rb
index 415e989a7d..2c077f6e6e 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -56,6 +56,7 @@
resources :metadata, only: [] do
collection do
+ patch 'legacy', action: :update_legacy_metadata
get 'dublin_core'
get 'descriptive'
end
diff --git a/openapi.json b/openapi.json
index f4ac42bebc..286d1cb24d 100644
--- a/openapi.json
+++ b/openapi.json
@@ -787,6 +787,41 @@
]
}
},
+ "/objects/{object_id}/metadata/legacy": {
+ "post": {
+ "tags": [
+ "objects"
+ ],
+ "summary": "Update the legacy (datastream) metadata for the object",
+ "description": "",
+ "operationId": "metadata#update_legacy_metadata",
+ "responses": {
+ "200": {
+ "description": "OK"
+ }
+ },
+ "parameters": [
+ {
+ "name": "object_id",
+ "in": "path",
+ "description": "ID of object",
+ "required": true,
+ "schema": {
+ "$ref": "#/components/schemas/Druid"
+ }
+ },
+ ],
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/UpdateLegacyMetadata"
+ }
+ }
+ }
+ }
+ }
+ },
"/objects/{object_id}/metadata/dublin_core": {
"get": {
"tags": [
@@ -1244,6 +1279,37 @@
}
}
}
+ },
+ "UpdateLegacyMetadata": {
+ "properties": {
+ "descriptive": {
+ "$ref": "#/components/schemas/LegacyDatastream"
+ },
+ "rights": {
+ "$ref": "#/components/schemas/LegacyDatastream"
+ },
+ "content": {
+ "$ref": "#/components/schemas/LegacyDatastream"
+ },
+ "technical": {
+ "$ref": "#/components/schemas/LegacyDatastream"
+ },
+ }
+ },
+ "LegacyDatastream": {
+ "properties": {
+ "updated": {
+ "type": "string",
+ "format": "date-time",
+ "description": "The date the xml was produced. This may be used to see if the server wants to accept this or if it already has a more recent version."
+
+ },
+ "content": {
+ "type": "string",
+ "description": "The XML datastream content",
+ "example": "..."
+ }
+ }
}
},
"securitySchemes": {
diff --git a/spec/requests/legacy_metadata_update_spec.rb b/spec/requests/legacy_metadata_update_spec.rb
new file mode 100644
index 0000000000..eef4ae4bfc
--- /dev/null
+++ b/spec/requests/legacy_metadata_update_spec.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe 'Update the legacy (datastream) metadata' do
+ let(:work) { instance_double(Dor::Item, pid: 'druid:bc123df4567', datastreams: datastreams, save!: nil) }
+ let(:create_date) { Time.zone.parse('2019-08-09T19:18:15Z') }
+ let(:descMetadata) { instance_double(Dor::DescMetadataDS, createDate: create_date) }
+ let(:rightsMetadata) { instance_double(Dor::RightsMetadataDS, createDate: create_date) }
+ let(:technicalMetadata) { instance_double(Dor::TechnicalMetadataDS, createDate: create_date) }
+ let(:contentMetadata) { instance_double(Dor::ContentMetadataDS, createDate: create_date) }
+
+ let(:datastreams) do
+ {
+ 'descMetadata' => descMetadata,
+ 'rightsMetadata' => rightsMetadata,
+ 'technicalMetadata' => technicalMetadata,
+ 'contentMetadata' => contentMetadata
+ }
+ end
+
+ context 'when update is successful' do
+ before do
+ allow(Dor).to receive(:find).and_return(work)
+ allow(LegacyMetadataService).to receive(:update_datastream_if_newer)
+ end
+
+ let(:data) do
+ <<~JSON
+ {
+ "descriptive": {
+ "updated": "2019-11-08T15:15:43Z",
+ "content": ""
+ },
+ "rights": {
+ "updated": "2019-11-08T15:15:43Z",
+ "content": ""
+ }
+ }
+ JSON
+ end
+
+ it 'updates the object datastreams' do
+ patch "/v1/objects/#{work.pid}/metadata/legacy",
+ params: data,
+ headers: { 'Authorization' => "Bearer #{jwt}", 'CONTENT_TYPE' => 'application/json' }
+ expect(response).to have_http_status(:no_content)
+
+ expect(LegacyMetadataService).to have_received(:update_datastream_if_newer)
+ .with(datastream: descMetadata,
+ updated: Time.zone.parse('2019-11-08T15:15:43Z'),
+ content: '')
+
+ expect(LegacyMetadataService).to have_received(:update_datastream_if_newer)
+ .with(datastream: rightsMetadata,
+ updated: Time.zone.parse('2019-11-08T15:15:43Z'),
+ content: '')
+
+ expect(work).to have_received(:save!)
+ end
+ end
+end
diff --git a/spec/services/legacy_metadata_service_spec.rb b/spec/services/legacy_metadata_service_spec.rb
new file mode 100644
index 0000000000..10dee27a64
--- /dev/null
+++ b/spec/services/legacy_metadata_service_spec.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe LegacyMetadataService do
+ describe '.update_datastream_if_newer' do
+ subject(:update) { described_class.update_datastream_if_newer(datastream: datastream, updated: updated, content: content) }
+
+ let(:updated) { Time.zone.parse('2019-08-09T19:18:15Z') }
+ let(:content) { '' }
+ let(:datastream) { instance_double(Dor::DescMetadataDS, createDate: create_date, :content= => nil) }
+
+ context 'with a new datastream' do
+ let(:create_date) { nil }
+
+ it 'updates the content' do
+ update
+ expect(datastream).to have_received(:content=).with(content)
+ end
+ end
+
+ context 'with a datastream that is older than the content' do
+ let(:create_date) { Time.zone.parse('2019-07-09T19:18:15Z') }
+
+ it 'updates the content' do
+ update
+ expect(datastream).to have_received(:content=).with(content)
+ end
+ end
+ end
+end