uc3-dmp-id 0.0.140 → 0.1.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/lib/uc3-dmp-id/asserter.rb +162 -78
- data/lib/uc3-dmp-id/creator.rb +20 -16
- data/lib/uc3-dmp-id/deleter.rb +17 -18
- data/lib/uc3-dmp-id/finder.rb +49 -31
- data/lib/uc3-dmp-id/helper.rb +37 -21
- data/lib/uc3-dmp-id/schemas/amend.rb +269 -267
- data/lib/uc3-dmp-id/schemas/author.rb +1363 -1361
- data/lib/uc3-dmp-id/updater.rb +74 -39
- data/lib/uc3-dmp-id/validator.rb +10 -4
- data/lib/uc3-dmp-id/version.rb +1 -1
- data/lib/uc3-dmp-id/versioner.rb +16 -7
- data/lib/uc3-dmp-id.rb +1 -11
- metadata +2 -58
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1bdcb2754d5168bdeedf8583b91054cf62fc019d4479686da168d4ca70d83729
|
4
|
+
data.tar.gz: b2af99461aa7614212aae435db0db174eeb50125006d0dacc87698ecaf41b7b8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 43cdce10f8bccc41fc979c67a4758fd5726206c9066acefcbc8abe65b9d36f79fc69eedb461a9ce584cf61f85ddd0dca13617d99a39e9c831eb56ea725a00eb0
|
7
|
+
data.tar.gz: 393d0e083ca8cfbf2039ba11861576a2eff489d48d8c541279ae30a3f9e7215d39175c49d1203456f56bb00a6a7e3da6c0211d4c3fc7e4f64f32f88e3d96accf
|
data/lib/uc3-dmp-id/asserter.rb
CHANGED
@@ -5,64 +5,163 @@ require 'time'
|
|
5
5
|
module Uc3DmpId
|
6
6
|
class AsserterError < StandardError; end
|
7
7
|
|
8
|
+
# Class that handles changes to a DMP ID's :dmphub_modifications section
|
8
9
|
class Asserter
|
10
|
+
DEFAULT_DESCRIPTOR = 'references'
|
11
|
+
DEFAULT_WORK_TYPE = 'other'
|
12
|
+
|
9
13
|
class << self
|
10
14
|
# Add assertions to a DMP ID - this is performed by non-provenance systems
|
11
|
-
|
12
|
-
|
13
|
-
|
15
|
+
# rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
16
|
+
def add(updater:, latest_version:, modified_version:, note: nil, logger: nil)
|
17
|
+
return latest_version unless latest_version.is_a?(Hash)
|
14
18
|
|
19
|
+
owner = latest_version['dmphub_provenance_id']&.gsub('PROVENANCE#', '')
|
15
20
|
# If the updater and provenance are the same just return the :dmp as-is
|
16
|
-
return
|
17
|
-
|
18
|
-
|
19
|
-
contact =
|
20
|
-
contributor =
|
21
|
-
project =
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
21
|
+
return latest_version if updater.nil? || !latest_version.is_a?(Hash) || !modified_version.is_a?(Hash) ||
|
22
|
+
updater&.gsub('PROVENANCE#', '') == owner
|
23
|
+
|
24
|
+
# contact = modified_version['contact']
|
25
|
+
# contributor = modified_version.fetch('contributor', [])
|
26
|
+
# project = modified_version.fetch('project', [])
|
27
|
+
funding = modified_version.fetch('project', []).first&.fetch('funding', [])
|
28
|
+
related_works = modified_version.fetch('dmproadmap_related_identifiers', [])
|
29
|
+
|
30
|
+
if related_works.any?
|
31
|
+
latest_version = _add_related_identifier(updater: updater, latest_version: latest_version,
|
32
|
+
identifiers: related_works, note: note, logger: logger)
|
33
|
+
end
|
34
|
+
return latest_version unless !funding.nil? && funding.any?
|
35
|
+
|
36
|
+
_add_funding_mod(updater: updater, latest_version: latest_version, funding: funding,
|
37
|
+
note: note, logger: logger)
|
33
38
|
end
|
39
|
+
# rubocop:enable Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
34
40
|
|
35
|
-
# Splice together assertions made
|
41
|
+
# Splice together assertions made by the owner of the DMP ID so that any :dmphub_modifications made to
|
42
|
+
# the record while it was being updated are not lost
|
43
|
+
# rubocop:disable Metrics/AbcSize
|
36
44
|
def splice(latest_version:, modified_version:, logger: nil)
|
37
|
-
|
38
|
-
puts "LATEST_VERSION ASSERTIONS: #{latest_version['dmphub_modifications']}"
|
39
|
-
puts "MODIFIED_VERSION ASSERTIONS: #{modified_version['dmphub_modifications']}"
|
40
|
-
|
41
|
-
# Return the modified_version if the timestamps are the same (meaning no new assertions were made while the
|
42
|
-
# user was working on the DMP ID) OR neither version has assertions
|
45
|
+
# Return the modified_version if the timestamps are the same OR neither version has :dmphub_modifications
|
43
46
|
return modified_version if latest_version['modified'] == modified_version['modified'] ||
|
44
47
|
(latest_version.fetch('dmphub_modifications', []).empty? &&
|
45
48
|
modified_version.fetch('dmphub_modifications', []).empty?)
|
46
49
|
|
47
|
-
# Clone any existing
|
50
|
+
# Clone any existing :dmphub_modifications on the current DMP ID so we can retain them
|
48
51
|
existing_assertions = Helper.deep_copy_dmp(obj: latest_version.fetch('dmphub_modifications', []))
|
49
52
|
incoming_assertions = Helper.deep_copy_dmp(obj: modified_version.fetch('dmphub_modifications', []))
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
# Keep any assetions that were made after the modified on the incoming changes
|
54
|
-
modified_version['dmphub_modifications'] = existing_assertions.select do |entry|
|
55
|
-
!entry['timestamp'].nil? && Time.parse(entry['timestamp']) > Time.parse(modified_version['modified'])
|
53
|
+
if logger.respond_to?(:debug)
|
54
|
+
logger.debug(message: 'Existing dmphub_modifications',
|
55
|
+
details: existing_assertions)
|
56
56
|
end
|
57
|
+
if logger.respond_to?(:debug)
|
58
|
+
logger.debug(message: 'Incoming dmphub_modifications',
|
59
|
+
details: incoming_assertions)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Keep any :dmphub_modifications and then add the incoming to the Array
|
63
|
+
modified_version['dmphub_modifications'] = existing_assertions
|
57
64
|
return modified_version unless incoming_assertions.any?
|
58
65
|
|
59
66
|
# Add any of the assertions still on the incoming record back to the latest record
|
60
67
|
incoming_assertions.each { |entry| modified_version['dmphub_modifications'] << entry }
|
61
68
|
modified_version
|
62
69
|
end
|
70
|
+
# rubocop:enable Metrics/AbcSize
|
63
71
|
|
64
72
|
private
|
65
73
|
|
74
|
+
# Verify that the DMP ID record does not already have the specified identifiers and then add them
|
75
|
+
# to the :latest_version in the :dmphub_modifications Array
|
76
|
+
#
|
77
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
78
|
+
# rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
79
|
+
def _add_related_identifier(updater:, latest_version:, identifiers:, note: '', logger: nil)
|
80
|
+
return latest_version unless updater.is_a?(String) && latest_version.is_a?(Hash) && identifiers.is_a?(Array)
|
81
|
+
|
82
|
+
latest_version['dmphub_modifications'] = [] if latest_version['dmphub_modifications'].nil?
|
83
|
+
known_mods = latest_version['dmphub_modifications'].map do |mod|
|
84
|
+
mod.fetch('dmproadmap_related_identifiers', [])
|
85
|
+
end
|
86
|
+
known_mods = known_mods.flatten.compact.map { |mod| mod['identifier'].downcase.strip }.compact.uniq
|
87
|
+
|
88
|
+
asserted = latest_version.fetch('dmproadmap_related_identifiers', [])
|
89
|
+
asserted = asserted.flatten.compact.map { |mod| mod['identifier'].downcase.strip }.compact.uniq
|
90
|
+
|
91
|
+
additions = []
|
92
|
+
identifiers.each do |related_identifier|
|
93
|
+
# Skip if there is no :type or :identifier value
|
94
|
+
if !related_identifier.is_a?(Hash) || related_identifier['type'].nil? || related_identifier['identifier'].nil?
|
95
|
+
next
|
96
|
+
end
|
97
|
+
|
98
|
+
id = related_identifier['identifier'].downcase.strip
|
99
|
+
# Skip if the :identifier is already listed in :dmphub_modifications or the
|
100
|
+
# :dmproadmap_related_identifiers Arrays
|
101
|
+
next if known_mods.include?(id) || asserted.include?(id)
|
102
|
+
|
103
|
+
related_identifier['work_type'] = DEFAULT_WORK_TYPE if related_identifier['work_type'].nil?
|
104
|
+
related_identifier['descriptor'] = DEFAULT_DESCRIPTOR if related_identifier['descriptor'].nil?
|
105
|
+
additions << related_identifier
|
106
|
+
end
|
107
|
+
|
108
|
+
latest_version['dmproadmap_related_identifiers'] = [] if latest_version['dmproadmap_related_identifiers'].nil?
|
109
|
+
assertion = _generate_assertion(updater: updater, note: note,
|
110
|
+
mods: JSON.parse({ dmproadmap_related_identifiers: additions }.to_json))
|
111
|
+
if logger.respond_to?(:debug)
|
112
|
+
logger.debug(message: 'Adding change to :dmphub_modifications.',
|
113
|
+
details: assertion)
|
114
|
+
end
|
115
|
+
latest_version['dmphub_modifications'] << assertion
|
116
|
+
latest_version
|
117
|
+
end
|
118
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
119
|
+
# rubocop:enable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
120
|
+
|
121
|
+
# Verify that the DMP ID record does not already have the specified funding change and then add it
|
122
|
+
# to the :latest_version in the :dmphub_modifications Array
|
123
|
+
#
|
124
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
125
|
+
# rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
126
|
+
def _add_funding_mod(updater:, latest_version:, funding:, note: '', logger: nil)
|
127
|
+
return latest_version unless updater.is_a?(String) && latest_version.is_a?(Hash) && funding.is_a?(Array)
|
128
|
+
|
129
|
+
known_mods = latest_version['dmphub_modifications'].map do |mod|
|
130
|
+
next if mod.nil?
|
131
|
+
|
132
|
+
mod.fetch('funding', {}).fetch('grant_id', {})['identifier']&.downcase&.strip
|
133
|
+
end
|
134
|
+
known_mods = known_mods.flatten.compact.uniq
|
135
|
+
|
136
|
+
asserted = latest_version.fetch('project', [])&.map do |project|
|
137
|
+
next if project.nil?
|
138
|
+
|
139
|
+
project&.fetch('funding', [])&.first&.fetch('grant_id', {})&.[]('identifier')&.downcase&.strip
|
140
|
+
end
|
141
|
+
asserted = asserted.flatten.compact.uniq
|
142
|
+
|
143
|
+
fund = funding.reject { |entry| entry['grant_id'].nil? }.first
|
144
|
+
# Skip if there is no :grant_id
|
145
|
+
return latest_version if !fund.is_a?(Hash) || fund.fetch('grant_id', {})['identifier'].nil?
|
146
|
+
|
147
|
+
grant_id = fund.fetch('grant_id', {})['identifier'].downcase.strip
|
148
|
+
# Skip if the :grant_id is already listed as a :dmphub_modifications or project: :funding
|
149
|
+
return latest_version if known_mods.include?(grant_id) || asserted.include?(grant_id)
|
150
|
+
|
151
|
+
latest_version['dmphub_modifications'] = [] if latest_version['dmphub_modifications'].nil?
|
152
|
+
mod = JSON.parse({ funding: fund }.to_json)
|
153
|
+
mod['funding']['funding_status'] = 'granted'
|
154
|
+
assertion = _generate_assertion(updater: updater, mods: mod, note: note)
|
155
|
+
if logger.respond_to?(:debug)
|
156
|
+
logger.debug(message: 'Adding change to :dmphub_modifications.',
|
157
|
+
details: assertion)
|
158
|
+
end
|
159
|
+
latest_version['dmphub_modifications'] << assertion
|
160
|
+
latest_version
|
161
|
+
end
|
162
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
163
|
+
# rubocop:enable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
164
|
+
|
66
165
|
# Generate an assertion entry. For example:
|
67
166
|
#
|
68
167
|
# {
|
@@ -70,56 +169,41 @@ puts "MODIFIED_VERSION ASSERTIONS: #{modified_version['dmphub_modifications']}"
|
|
70
169
|
# "provenance": "dmphub",
|
71
170
|
# "timestamp": "2023-07-07T14:50:23+00:00",
|
72
171
|
# "note": "data received from the NIH API",
|
73
|
-
# "
|
74
|
-
# "
|
75
|
-
#
|
76
|
-
#
|
77
|
-
# "
|
78
|
-
#
|
79
|
-
#
|
80
|
-
#
|
81
|
-
#
|
82
|
-
#
|
83
|
-
#
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
87
|
-
#
|
88
|
-
#
|
89
|
-
#
|
90
|
-
#
|
91
|
-
#
|
92
|
-
#
|
93
|
-
#
|
94
|
-
# "end": "2025-12-31T23:59:59+07:00"
|
95
|
-
# }
|
96
|
-
# ],
|
97
|
-
# "funding": [
|
98
|
-
# {
|
99
|
-
# "funder_id": {
|
100
|
-
# "identifier": "https://doi.org/10.13039/501100001807",
|
101
|
-
# "type": "fundref"
|
102
|
-
# },
|
103
|
-
# "funding_status": "granted",
|
104
|
-
# "grant_id": {
|
105
|
-
# "identifier": "2019/22702-3",
|
106
|
-
# "type": "other"
|
107
|
-
# }
|
108
|
-
# }
|
109
|
-
# ]
|
172
|
+
# "dmproadmap_related_identifiers": {
|
173
|
+
# "work_type": "article",
|
174
|
+
# "descriptor": "is_cited_by",
|
175
|
+
# "type": "doi",
|
176
|
+
# "identifier": "https://dx.doi.org/99.9876/ZYX987.V6"
|
177
|
+
# }
|
178
|
+
# }
|
179
|
+
#
|
180
|
+
# OR:
|
181
|
+
#
|
182
|
+
# {
|
183
|
+
# "id": "ABCD1234",
|
184
|
+
# "provenance": "dmphub",
|
185
|
+
# "timestamp": "2023-07-07T14:50:23+00:00",
|
186
|
+
# "note": "data received from the NIH API",
|
187
|
+
# "funding": {
|
188
|
+
# "funding_status": "granted",
|
189
|
+
# "grant_id": {
|
190
|
+
# "identifier": "2019/22702-3",
|
191
|
+
# "type": "other"
|
192
|
+
# }
|
110
193
|
# }
|
111
|
-
#
|
194
|
+
# }
|
112
195
|
def _generate_assertion(updater:, mods:, note: '')
|
113
|
-
return nil if updater.nil? || !
|
196
|
+
return nil if updater.nil? || !mods.is_a?(Hash)
|
114
197
|
|
115
|
-
|
198
|
+
assertion = {
|
116
199
|
id: SecureRandom.hex(4).upcase,
|
117
200
|
provenance: updater.gsub('PROVENANCE#', ''),
|
118
201
|
timestamp: Time.now.utc.iso8601,
|
119
|
-
status: '
|
120
|
-
note: note
|
121
|
-
|
122
|
-
}
|
202
|
+
status: 'pending',
|
203
|
+
note: note
|
204
|
+
}
|
205
|
+
mods.each_pair { |key, val| assertion[key] = val }
|
206
|
+
JSON.parse(assertion.to_json)
|
123
207
|
end
|
124
208
|
end
|
125
209
|
end
|
data/lib/uc3-dmp-id/creator.rb
CHANGED
@@ -6,31 +6,32 @@ require 'time'
|
|
6
6
|
module Uc3DmpId
|
7
7
|
class CreatorError < StandardError; end
|
8
8
|
|
9
|
+
# Class that registers a new DMP ID
|
9
10
|
class Creator
|
10
11
|
MSG_NO_BASE_URL = 'No base URL found for DMP ID (e.g. `doi.org`)'
|
11
12
|
MSG_NO_SHOULDER = 'No DOI shoulder found. (e.g. `10.12345/`)'
|
12
13
|
MSG_UNABLE_TO_MINT = 'Unable to mint a unique DMP ID.'
|
13
14
|
|
14
15
|
class << self
|
16
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
17
|
+
# rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
15
18
|
def create(provenance:, json:, logger: nil)
|
16
19
|
raise CreatorError, MSG_NO_SHOULDER if ENV['DMP_ID_SHOULDER'].nil?
|
17
20
|
raise CreatorError, MSG_NO_BASE_URL if ENV['DMP_ID_BASE_URL'].nil?
|
18
21
|
|
19
22
|
# Fail if the provenance is not defined
|
20
|
-
raise
|
23
|
+
raise CreatorError, Helper::MSG_DMP_FORBIDDEN unless provenance.is_a?(Hash) && !provenance['PK'].nil?
|
21
24
|
|
22
25
|
# Validate the incoming JSON first
|
23
26
|
json = Helper.parse_json(json: json)
|
24
27
|
errs = Validator.validate(mode: 'author', json: json)
|
25
28
|
raise CreatorError, errs.join(', ') if errs.is_a?(Array) && errs.any? && errs.first != Validator::MSG_VALID_JSON
|
26
29
|
|
27
|
-
#
|
28
|
-
|
30
|
+
# Try to find it by the :dmp_id first and Fail if found
|
31
|
+
dmp_id = Helper.dmp_id_to_pk(json: json.fetch('dmp', {})['dmp_id'])
|
32
|
+
result = Finder.exists?(p_key: dmp_id, logger: logger) unless dmp_id.nil?
|
33
|
+
raise CreatorError, Helper::MSG_DMP_EXISTS if result.is_a?(Hash)
|
29
34
|
|
30
|
-
# TODO: Swap this out with the Finder search once the Dynamo indexes are working
|
31
|
-
# Try to find it first and Fail if found
|
32
|
-
result = Finder.by_json(json: json, logger: logger)
|
33
|
-
raise CreatorError, Uc3DmpId::MSG_DMP_EXISTS if result.is_a?(Hash)
|
34
35
|
# raise CreatorError, Uc3DmpId::MSG_DMP_EXISTS unless json['PK'].nil?
|
35
36
|
|
36
37
|
client = Uc3DmpDynamo::Client.new
|
@@ -48,28 +49,32 @@ module Uc3DmpId
|
|
48
49
|
|
49
50
|
# Create the item
|
50
51
|
resp = client.put_item(json: annotated, logger: logger)
|
51
|
-
raise CreatorError,
|
52
|
+
raise CreatorError, Helper::MSG_DMP_NO_DMP_ID if resp.nil?
|
52
53
|
|
53
54
|
_post_process(json: annotated, logger: logger)
|
54
55
|
Helper.cleanse_dmp_json(json: JSON.parse({ dmp: annotated }.to_json))
|
55
56
|
end
|
57
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
58
|
+
# rubocop:enable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
56
59
|
|
57
60
|
private
|
58
61
|
|
62
|
+
# rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
59
63
|
def _preregister_dmp_id(client:, provenance:, json:, logger: nil)
|
60
64
|
# Use the specified DMP ID if the provenance has permission
|
61
65
|
seeding = provenance.fetch('seedingWithLiveDmpIds', false).to_s.downcase == 'true'
|
62
66
|
seed_id = json.fetch('dmp', {})['dmproadmap_external_system_identifier']
|
63
67
|
|
64
68
|
# If we are seeding already registered DMP IDs from the Provenance system, then return the original DMP ID
|
65
|
-
logger.debug(message: "Seeding DMP ID with #{seed_id.gsub(%r{https?://}, '')}") if
|
69
|
+
logger.debug(message: "Seeding DMP ID with #{seed_id.gsub(%r{https?://}, '')}") if logger.respond_to?(:debug) &&
|
70
|
+
seeding && !seed_id.nil?
|
66
71
|
return seed_id.gsub(%r{https?://}, '') if seeding && !seed_id.nil?
|
67
72
|
|
68
|
-
#Generate a new DMP ID
|
73
|
+
# Generate a new DMP ID
|
69
74
|
dmp_id = ''
|
70
75
|
counter = 0
|
71
76
|
while dmp_id == '' && counter <= 10
|
72
|
-
prefix = "#{ENV
|
77
|
+
prefix = "#{ENV.fetch('DMP_ID_SHOULDER', nil)}#{SecureRandom.hex(2).upcase}#{SecureRandom.hex(2)}"
|
73
78
|
dmp_id = prefix unless Finder.exists?(client: client, p_key: prefix)
|
74
79
|
counter += 1
|
75
80
|
end
|
@@ -80,15 +85,13 @@ module Uc3DmpId
|
|
80
85
|
url = ENV['DMP_ID_BASE_URL'].gsub(%r{https?://}, '')
|
81
86
|
"#{Helper::PK_DMP_PREFIX}#{url.end_with?('/') ? url : "#{url}/"}#{dmp_id}"
|
82
87
|
end
|
83
|
-
# rubocop:enable Metrics/AbcSize, Metrics/
|
88
|
+
# rubocop:enable Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
84
89
|
|
85
90
|
# Once the DMP has been created, we need to register it's DMP ID
|
86
91
|
# -------------------------------------------------------------------------
|
87
92
|
def _post_process(json:, logger: nil)
|
88
93
|
return false unless json.is_a?(Hash)
|
89
94
|
|
90
|
-
# We are creating, so this is always true
|
91
|
-
json['dmphub_updater_is_provenance'] = true
|
92
95
|
# Publish the change to the EventBridge
|
93
96
|
publisher = Uc3DmpEventBridge::Publisher.new
|
94
97
|
publisher.publish(source: 'DmpCreator', event_type: 'EZID update', dmp: json, logger: logger)
|
@@ -103,8 +106,9 @@ module Uc3DmpId
|
|
103
106
|
SK: json['SK'],
|
104
107
|
dmproadmap_related_identifiers: citable_identifiers
|
105
108
|
}
|
106
|
-
logger.debug(message:
|
107
|
-
publisher.publish(source: '
|
109
|
+
logger.debug(message: 'Fetching citations', details: citable_identifiers) if logger.respond_to?(:debug)
|
110
|
+
publisher.publish(source: 'DmpCreator', dmp: json, event_type: 'Citation Fetch', detail: citer_detail,
|
111
|
+
logger: logger)
|
108
112
|
true
|
109
113
|
end
|
110
114
|
end
|
data/lib/uc3-dmp-id/deleter.rb
CHANGED
@@ -12,47 +12,48 @@ module Uc3DmpId
|
|
12
12
|
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
13
13
|
# -------------------------------------------------------------------------
|
14
14
|
def tombstone(provenance:, p_key:, logger: nil)
|
15
|
-
raise DeleterError, MSG_DMP_INVALID_DMP_ID unless p_key.is_a?(String) && !p_key.strip.empty?
|
15
|
+
raise DeleterError, Helper::MSG_DMP_INVALID_DMP_ID unless p_key.is_a?(String) && !p_key.strip.empty?
|
16
16
|
|
17
17
|
# Fail if the provenance is not defined
|
18
|
-
raise DeleterError, MSG_DMP_FORBIDDEN unless provenance.is_a?(Hash) && !provenance['PK'].nil?
|
18
|
+
raise DeleterError, Helper::MSG_DMP_FORBIDDEN unless provenance.is_a?(Hash) && !provenance['PK'].nil?
|
19
19
|
|
20
20
|
# Fetch the latest version of the DMP ID by it's PK
|
21
21
|
client = Uc3DmpDynamo::Client.new
|
22
|
-
dmp = Finder.by_pk(p_key: p_key, client: client, logger: logger)
|
23
|
-
raise DeleterError, MSG_DMP_NOT_FOUND unless dmp.is_a?(Hash) && !dmp['dmp'].nil?
|
22
|
+
dmp = Finder.by_pk(p_key: p_key, client: client, cleanse: false, logger: logger)
|
23
|
+
raise DeleterError, Helper::MSG_DMP_NOT_FOUND unless dmp.is_a?(Hash) && !dmp['dmp'].nil?
|
24
24
|
|
25
25
|
# Only allow this if the provenance is the owner of the DMP!
|
26
|
-
raise DeleterError, MSG_DMP_FORBIDDEN if dmp['dmp']['dmphub_provenance_id'] != provenance['PK']
|
26
|
+
raise DeleterError, Helper::MSG_DMP_FORBIDDEN if dmp['dmp']['dmphub_provenance_id'] != provenance['PK']
|
27
27
|
# Make sure they're not trying to update a historical copy of the DMP
|
28
|
-
raise DeleterError, MSG_DMP_NO_HISTORICALS if dmp['dmp']['SK'] != Helper::DMP_LATEST_VERSION
|
28
|
+
raise DeleterError, Helper::MSG_DMP_NO_HISTORICALS if dmp['dmp']['SK'] != Helper::DMP_LATEST_VERSION
|
29
29
|
|
30
30
|
# Annotate the DMP ID
|
31
31
|
dmp['dmp']['SK'] = Helper::DMP_TOMBSTONE_VERSION
|
32
|
-
dmp['dmp']['
|
33
|
-
|
34
|
-
logger.info(message: "Tomstoning DMP ID: #{p_key}") if logger.respond_to?(:debug)
|
32
|
+
dmp['dmp']['title'] = "OBSOLETE: #{dmp['dmp']['title']}"
|
33
|
+
logger.info(message: "Tombstoning DMP ID: #{p_key}") if logger.respond_to?(:debug)
|
35
34
|
|
36
35
|
# Set the :modified timestamps
|
37
36
|
now = Time.now.utc.iso8601
|
38
|
-
dmp['modified'] = now
|
37
|
+
dmp['dmp']['modified'] = now
|
38
|
+
dmp['dmp']['dmphub_tombstoned_at'] = now
|
39
39
|
|
40
40
|
# Create the Tombstone version
|
41
|
-
resp = client.put_item(json: dmp, logger: logger)
|
42
|
-
raise DeleterError, MSG_DMP_NO_TOMBSTONE if resp.nil?
|
41
|
+
resp = client.put_item(json: dmp['dmp'], logger: logger)
|
42
|
+
raise DeleterError, Helper::MSG_DMP_NO_TOMBSTONE if resp.nil?
|
43
43
|
|
44
44
|
# Delete the Latest version
|
45
|
-
|
45
|
+
client.delete_item(p_key: p_key, s_key: Helper::DMP_LATEST_VERSION, logger: logger)
|
46
46
|
|
47
47
|
# TODO: We should do a check here to see if it was successful!
|
48
48
|
|
49
49
|
# Notify EZID about the removal
|
50
50
|
_post_process(json: dmp, logger: logger)
|
51
|
+
|
51
52
|
# Return the tombstoned record
|
52
|
-
Helper.cleanse_dmp_json(json:
|
53
|
+
Helper.cleanse_dmp_json(json: dmp)
|
53
54
|
rescue Aws::Errors::ServiceError => e
|
54
|
-
logger.error(message: e.message, details: e.backtrace)
|
55
|
-
|
55
|
+
logger.error(message: e.message, details: e.backtrace) if logger.respond_to?(:error)
|
56
|
+
raise DeleterError, Helper::MSG_SERVER_ERROR
|
56
57
|
end
|
57
58
|
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
58
59
|
|
@@ -63,8 +64,6 @@ module Uc3DmpId
|
|
63
64
|
def _post_process(json:, logger: nil)
|
64
65
|
return false unless json.is_a?(Hash)
|
65
66
|
|
66
|
-
# Indicate whether or not the updater is the provenance system
|
67
|
-
json['dmphub_updater_is_provenance'] = true
|
68
67
|
# Publish the change to the EventBridge
|
69
68
|
publisher = Uc3DmpEventBridge::Publisher.new
|
70
69
|
publisher.publish(source: 'DmpDeleter', event_type: 'EZID update', dmp: json, logger: logger)
|