moab-versioning 4.4.0 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/moab/bagger.rb +1 -1
- data/lib/moab/exceptions.rb +4 -0
- data/lib/moab/file_group.rb +6 -6
- data/lib/moab/file_group_difference.rb +23 -23
- data/lib/moab/file_group_difference_subset.rb +3 -3
- data/lib/moab/file_instance.rb +1 -1
- data/lib/moab/file_instance_difference.rb +3 -3
- data/lib/moab/file_inventory.rb +9 -9
- data/lib/moab/file_inventory_difference.rb +6 -6
- data/lib/moab/file_manifestation.rb +2 -2
- data/lib/moab/file_signature.rb +5 -5
- data/lib/moab/signature_catalog.rb +10 -10
- data/lib/moab/signature_catalog_entry.rb +4 -4
- data/lib/moab/stanford.rb +0 -10
- data/lib/moab/storage_object.rb +5 -5
- data/lib/moab/storage_object_validator.rb +2 -2
- data/lib/moab/storage_object_version.rb +12 -12
- data/lib/moab/storage_repository.rb +1 -1
- data/lib/moab/storage_services.rb +3 -9
- data/lib/moab/version_metadata_entry.rb +4 -4
- data/lib/moab.rb +0 -8
- data/lib/serializer/manifest.rb +2 -2
- data/lib/serializer/serializable.rb +1 -1
- data/lib/stanford/content_inventory.rb +19 -19
- data/lib/stanford/storage_repository.rb +2 -2
- metadata +9 -15
- data/lib/moab/deposit_bag_validator.rb +0 -328
- data/lib/moab/version_metadata.rb +0 -34
- data/lib/moab/version_metadata_event.rb +0 -42
- data/lib/stanford/active_fedora_object.rb +0 -30
- data/lib/stanford/dor_metadata.rb +0 -43
- data/lib/stanford/moab_storage_directory.rb +0 -38
@@ -45,7 +45,7 @@ module Moab
|
|
45
45
|
|
46
46
|
# @return [String] The unique identifier concatenating digital object id with version id
|
47
47
|
def composite_key
|
48
|
-
@storage_object.digital_object_id
|
48
|
+
"#{@storage_object.digital_object_id}-#{StorageObject.version_dirname(@version_id)}"
|
49
49
|
end
|
50
50
|
|
51
51
|
# @return [Boolean] true if the object version directory exists
|
@@ -115,12 +115,12 @@ module Moab
|
|
115
115
|
|
116
116
|
@inventory_cache[type] = FileInventory.read_xml_file(@version_pathname.join('manifests'), type)
|
117
117
|
else
|
118
|
-
groups = %w[content metadata].collect { |id| FileGroup.new(:
|
118
|
+
groups = %w[content metadata].collect { |id| FileGroup.new(group_id: id) }
|
119
119
|
FileInventory.new(
|
120
|
-
:
|
121
|
-
:
|
122
|
-
:
|
123
|
-
:
|
120
|
+
type: 'version',
|
121
|
+
digital_object_id: @storage_object.digital_object_id,
|
122
|
+
version_id: @version_id,
|
123
|
+
groups: groups
|
124
124
|
)
|
125
125
|
end
|
126
126
|
end
|
@@ -131,7 +131,7 @@ module Moab
|
|
131
131
|
if version_id > 0
|
132
132
|
SignatureCatalog.read_xml_file(@version_pathname.join('manifests'))
|
133
133
|
else
|
134
|
-
SignatureCatalog.new(:
|
134
|
+
SignatureCatalog.new(digital_object_id: @storage_object.digital_object_id)
|
135
135
|
end
|
136
136
|
end
|
137
137
|
|
@@ -202,12 +202,12 @@ module Moab
|
|
202
202
|
# @return [void] examine the version's directory and create/serialize a {FileInventory} containing the manifest files
|
203
203
|
def generate_manifest_inventory
|
204
204
|
manifest_inventory = FileInventory.new(
|
205
|
-
:
|
206
|
-
:
|
207
|
-
:
|
205
|
+
type: 'manifests',
|
206
|
+
digital_object_id: @storage_object.digital_object_id,
|
207
|
+
version_id: @version_id
|
208
208
|
)
|
209
209
|
pathname = @version_pathname.join('manifests')
|
210
|
-
manifest_inventory.groups << FileGroup.new(:
|
210
|
+
manifest_inventory.groups << FileGroup.new(group_id: 'manifests').group_from_directory(pathname, false)
|
211
211
|
manifest_inventory.write_xml_file(pathname)
|
212
212
|
end
|
213
213
|
|
@@ -312,7 +312,7 @@ module Moab
|
|
312
312
|
version_additions = file_inventory('additions')
|
313
313
|
result.subentities << VerificationResult.verify_value('composite_key', composite_key, version_additions.composite_key)
|
314
314
|
data_directory = @version_pathname.join('data')
|
315
|
-
directory_inventory = FileInventory.new(:
|
315
|
+
directory_inventory = FileInventory.new(type: 'directory').inventory_from_directory(data_directory)
|
316
316
|
diff = FileInventoryDifference.new
|
317
317
|
diff.compare(version_additions, directory_inventory)
|
318
318
|
compare_result = VerificationResult.new('file_differences')
|
@@ -160,7 +160,7 @@ module Moab
|
|
160
160
|
# @param druid [String] The object identifier
|
161
161
|
# @return [void] transfer the object to the preservation repository
|
162
162
|
def store_new_object_version(druid, bag_pathname)
|
163
|
-
storage_object(druid,
|
163
|
+
storage_object(druid, true).ingest_bag(bag_pathname)
|
164
164
|
end
|
165
165
|
|
166
166
|
private
|
@@ -83,12 +83,6 @@ module Moab
|
|
83
83
|
@@repository.storage_object(object_id).current_version_id
|
84
84
|
end
|
85
85
|
|
86
|
-
# @param [String] object_id The digital object identifier of the object
|
87
|
-
# @return [Pathname] Pathname object containing the full path for the specified file
|
88
|
-
def self.version_metadata(object_id)
|
89
|
-
retrieve_file('metadata', 'versionMetadata.xml', object_id)
|
90
|
-
end
|
91
|
-
|
92
86
|
# @param [String] object_id The digital object identifier of the object
|
93
87
|
# @param [Integer] version_id The ID of the version, if nil use latest version
|
94
88
|
# @return [FileInventory] the file inventory for the specified object version
|
@@ -110,7 +104,7 @@ module Moab
|
|
110
104
|
# @return [Pathname] Pathname object containing the full path for the specified file
|
111
105
|
def self.retrieve_file(file_category, file_id, object_id, version_id = nil)
|
112
106
|
storage_object_version = @@repository.storage_object(object_id).find_object_version(version_id)
|
113
|
-
|
107
|
+
storage_object_version.find_filepath(file_category, file_id)
|
114
108
|
end
|
115
109
|
|
116
110
|
# @param [String] file_category The category of file ('content', 'metdata', or 'manifest')
|
@@ -120,7 +114,7 @@ module Moab
|
|
120
114
|
# @return [Pathname] Pathname object containing the full path for the specified file
|
121
115
|
def self.retrieve_file_using_signature(file_category, file_signature, object_id, version_id = nil)
|
122
116
|
storage_object_version = @@repository.storage_object(object_id).find_object_version(version_id)
|
123
|
-
|
117
|
+
storage_object_version.find_filepath_using_signature(file_category, file_signature)
|
124
118
|
end
|
125
119
|
|
126
120
|
# @param [String] file_category The category of file ('content', 'metdata', or 'manifest')
|
@@ -130,7 +124,7 @@ module Moab
|
|
130
124
|
# @return [FileSignature] The signature of the file
|
131
125
|
def self.retrieve_file_signature(file_category, file_id, object_id, version_id = nil)
|
132
126
|
storage_object_version = @@repository.storage_object(object_id).find_object_version(version_id)
|
133
|
-
|
127
|
+
storage_object_version.find_signature(file_category, file_id)
|
134
128
|
end
|
135
129
|
|
136
130
|
# @param [String] object_id The digital object identifier of the object
|
@@ -24,7 +24,7 @@ module Moab
|
|
24
24
|
|
25
25
|
# @attribute
|
26
26
|
# @return [Integer] The object version number (A sequential integer)
|
27
|
-
attribute :version_id, Integer, :
|
27
|
+
attribute :version_id, Integer, tag: 'versionId', key: true, on_save: proc { |n| n.to_s }
|
28
28
|
|
29
29
|
# @attribute
|
30
30
|
# @return [String] "an external version label that increments the most significant digit for major revisions,
|
@@ -46,14 +46,14 @@ module Moab
|
|
46
46
|
|
47
47
|
# @attribute
|
48
48
|
# @return [FileGroupDifference] Summary of content file differences since previous version
|
49
|
-
element :content_changes, FileGroupDifference, :
|
49
|
+
element :content_changes, FileGroupDifference, tag: 'fileGroupDifference'
|
50
50
|
|
51
51
|
# @attribute
|
52
52
|
# @return [FileGroupDifference] Summary of metadata file differences since previous version
|
53
|
-
element :metadata_changes, FileGroupDifference, :
|
53
|
+
element :metadata_changes, FileGroupDifference, tag: 'fileGroupDifference'
|
54
54
|
|
55
55
|
# @attribute
|
56
56
|
# @return [Array<VersionMetadataEvent>] Array of events with timestamps that track lifecycle stages
|
57
|
-
has_many :events, VersionMetadataEvent, :
|
57
|
+
has_many :events, VersionMetadataEvent, tag: 'event'
|
58
58
|
end
|
59
59
|
end
|
data/lib/moab.rb
CHANGED
@@ -20,10 +20,6 @@
|
|
20
20
|
# * {FileInstanceDifference} [1..*] = contains difference information at the file level
|
21
21
|
# * {FileSignature} [1..2] = contains the file signature(s) of two file instances being compared
|
22
22
|
#
|
23
|
-
# * <b>{VersionMetadata} = descriptive information about a digital object's versions</b>
|
24
|
-
# * {VersionMetadataEntry} [1..*] = attributes of a digital object version
|
25
|
-
# * {VersionMetadataEvent} [1..*] = object version lifecycle events with timestamps
|
26
|
-
#
|
27
23
|
# * <b>{StorageObject} = represents a digital object's repository storage location and ingest/dissemination methods</b>
|
28
24
|
# * {StorageObjectVersion} [1..*] = represents a version subdirectory within an object's home directory
|
29
25
|
# * {Bagger} [1] = utility for creating bagit packages for ingest or dissemination
|
@@ -48,9 +44,6 @@ require 'moab/file_instance_difference'
|
|
48
44
|
require 'moab/file_group_difference_subset'
|
49
45
|
require 'moab/file_group_difference'
|
50
46
|
require 'moab/file_inventory_difference'
|
51
|
-
require 'moab/version_metadata_event'
|
52
|
-
require 'moab/version_metadata_entry'
|
53
|
-
require 'moab/version_metadata'
|
54
47
|
require 'moab/bagger'
|
55
48
|
require 'moab/storage_object'
|
56
49
|
require 'moab/storage_object_version'
|
@@ -59,4 +52,3 @@ require 'moab/storage_services'
|
|
59
52
|
require 'moab/exceptions'
|
60
53
|
require 'moab/verification_result'
|
61
54
|
require 'moab/storage_object_validator'
|
62
|
-
require 'moab/deposit_bag_validator'
|
data/lib/serializer/manifest.rb
CHANGED
@@ -22,7 +22,7 @@ module Serializer
|
|
22
22
|
filename
|
23
23
|
else
|
24
24
|
cname = name.split(/::/).last
|
25
|
-
cname[0, 1].downcase
|
25
|
+
"#{cname[0, 1].downcase}#{cname[1..]}.xml"
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
@@ -59,7 +59,7 @@ module Serializer
|
|
59
59
|
def self.write_xml_file(xml_object, parent_dir, filename = nil)
|
60
60
|
parent_dir.mkpath
|
61
61
|
xml_pathname(parent_dir, filename).open('w') do |f|
|
62
|
-
xmlBuilder = Nokogiri::XML::Builder.new(:
|
62
|
+
xmlBuilder = Nokogiri::XML::Builder.new(encoding: 'UTF-8')
|
63
63
|
xmlBuilder = xml_object.to_xml(xmlBuilder)
|
64
64
|
f << xmlBuilder.to_xml
|
65
65
|
end
|
@@ -23,7 +23,7 @@ module Stanford
|
|
23
23
|
# Many of these objects have contentMetadata with no child elements, such as this:
|
24
24
|
# <contentMetadata objectId="bd608mj3166" type="file"/>
|
25
25
|
# but there are also objects that have no datasteam of this name at all
|
26
|
-
cm_inventory = Moab::FileInventory.new(:
|
26
|
+
cm_inventory = Moab::FileInventory.new(type: "version", digital_object_id: object_id, version_id: version_id)
|
27
27
|
content_group = group_from_cm(content_metadata, subset)
|
28
28
|
cm_inventory.groups << content_group
|
29
29
|
cm_inventory
|
@@ -49,7 +49,7 @@ module Stanford
|
|
49
49
|
else
|
50
50
|
raise(Moab::MoabRuntimeError, "Unknown disposition subset (#{subset})")
|
51
51
|
end
|
52
|
-
content_group = Moab::FileGroup.new(:
|
52
|
+
content_group = Moab::FileGroup.new(group_id: 'content', data_source: "contentMetadata-#{subset}")
|
53
53
|
nodeset.each do |file_node|
|
54
54
|
signature = generate_signature(file_node)
|
55
55
|
instance = generate_instance(file_node)
|
@@ -85,10 +85,10 @@ module Stanford
|
|
85
85
|
instance = Moab::FileInstance.new
|
86
86
|
instance.path = node.attributes['id'].content
|
87
87
|
instance.datetime = begin
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
88
|
+
node.attributes['datetime'].content
|
89
|
+
rescue
|
90
|
+
nil
|
91
|
+
end
|
92
92
|
instance
|
93
93
|
end
|
94
94
|
|
@@ -98,23 +98,23 @@ module Stanford
|
|
98
98
|
# @example {include:file:spec/features/stanford/content_metadata_write_spec.rb}
|
99
99
|
def generate_content_metadata(file_group, object_id, version_id)
|
100
100
|
cm = Nokogiri::XML::Builder.new do |xml|
|
101
|
-
xml.contentMetadata(:
|
102
|
-
xml.resource(:
|
101
|
+
xml.contentMetadata(type: "sample", objectId: object_id) do
|
102
|
+
xml.resource(type: "version", sequence: "1", id: "version-#{version_id}") do
|
103
103
|
file_group.files.each do |file_manifestation|
|
104
104
|
signature = file_manifestation.signature
|
105
105
|
file_manifestation.instances.each do |instance|
|
106
106
|
xml.file(
|
107
|
-
:
|
108
|
-
:
|
109
|
-
:
|
110
|
-
:
|
111
|
-
:
|
112
|
-
:
|
107
|
+
id: instance.path,
|
108
|
+
size: signature.size,
|
109
|
+
datetime: instance.datetime,
|
110
|
+
shelve: 'yes',
|
111
|
+
publish: 'yes',
|
112
|
+
preserve: 'yes'
|
113
113
|
) do
|
114
114
|
fixity = signature.fixity
|
115
|
-
xml.checksum(:
|
116
|
-
xml.checksum(:
|
117
|
-
xml.checksum(:
|
115
|
+
xml.checksum(type: "MD5") { xml.text signature.md5 } if fixity[:md5]
|
116
|
+
xml.checksum(type: "SHA-1") { xml.text signature.sha1 } if fixity[:sha1]
|
117
|
+
xml.checksum(type: "SHA-256") { xml.text signature.sha256 } if fixity[:sha256]
|
118
118
|
end
|
119
119
|
end
|
120
120
|
end
|
@@ -128,7 +128,7 @@ module Stanford
|
|
128
128
|
# @return [Boolean] True if contentMetadata has essential file attributes, else raise exception
|
129
129
|
def validate_content_metadata(content_metadata)
|
130
130
|
result = validate_content_metadata_details(content_metadata)
|
131
|
-
raise Moab::InvalidMetadataException, result[0]
|
131
|
+
raise Moab::InvalidMetadataException, "#{result[0]} ..." unless result.empty?
|
132
132
|
|
133
133
|
true
|
134
134
|
end
|
@@ -191,7 +191,7 @@ module Stanford
|
|
191
191
|
remediate_file_size(file_node, signature)
|
192
192
|
remediate_checksum_nodes(file_node, signature)
|
193
193
|
end
|
194
|
-
ng_doc.to_xml(:
|
194
|
+
ng_doc.to_xml(indent: 2)
|
195
195
|
end
|
196
196
|
|
197
197
|
# @param [Nokogiri::XML::Element] file_node the File stanza being remediated
|
@@ -31,9 +31,9 @@ module Stanford
|
|
31
31
|
# @param object_id [String] The identifier of the digital object whose path is requested
|
32
32
|
# @return [String] the druid tree directory path based on the given object identifier.
|
33
33
|
def druid_tree(object_id)
|
34
|
-
#
|
34
|
+
# NOTE: this seems an odd place to do druid validation, but leaving it here for now
|
35
35
|
syntax_msg = "Identifier has invalid suri syntax: #{object_id}"
|
36
|
-
raise(Moab::InvalidSuriSyntaxError, syntax_msg
|
36
|
+
raise(Moab::InvalidSuriSyntaxError, "#{syntax_msg} nil or empty") if object_id.to_s.empty?
|
37
37
|
|
38
38
|
identifier = object_id.split(':')[-1]
|
39
39
|
raise(Moab::InvalidSuriSyntaxError, syntax_msg) if identifier.to_s.empty?
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: moab-versioning
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Darren Weber
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date:
|
14
|
+
date: 2021-10-19 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: druid-tools
|
@@ -145,28 +145,28 @@ dependencies:
|
|
145
145
|
requirements:
|
146
146
|
- - "~>"
|
147
147
|
- !ruby/object:Gem::Version
|
148
|
-
version:
|
148
|
+
version: '1.7'
|
149
149
|
type: :development
|
150
150
|
prerelease: false
|
151
151
|
version_requirements: !ruby/object:Gem::Requirement
|
152
152
|
requirements:
|
153
153
|
- - "~>"
|
154
154
|
- !ruby/object:Gem::Version
|
155
|
-
version:
|
155
|
+
version: '1.7'
|
156
156
|
- !ruby/object:Gem::Dependency
|
157
157
|
name: rubocop-rspec
|
158
158
|
requirement: !ruby/object:Gem::Requirement
|
159
159
|
requirements:
|
160
160
|
- - "~>"
|
161
161
|
- !ruby/object:Gem::Version
|
162
|
-
version:
|
162
|
+
version: '2.1'
|
163
163
|
type: :development
|
164
164
|
prerelease: false
|
165
165
|
version_requirements: !ruby/object:Gem::Requirement
|
166
166
|
requirements:
|
167
167
|
- - "~>"
|
168
168
|
- !ruby/object:Gem::Version
|
169
|
-
version:
|
169
|
+
version: '2.1'
|
170
170
|
description: Contains classes to process digital object version content and metadata
|
171
171
|
email:
|
172
172
|
- darren.weber@stanford.edu
|
@@ -177,7 +177,6 @@ files:
|
|
177
177
|
- lib/moab.rb
|
178
178
|
- lib/moab/bagger.rb
|
179
179
|
- lib/moab/config.rb
|
180
|
-
- lib/moab/deposit_bag_validator.rb
|
181
180
|
- lib/moab/exceptions.rb
|
182
181
|
- lib/moab/file_group.rb
|
183
182
|
- lib/moab/file_group_difference.rb
|
@@ -198,16 +197,11 @@ files:
|
|
198
197
|
- lib/moab/storage_services.rb
|
199
198
|
- lib/moab/utc_time.rb
|
200
199
|
- lib/moab/verification_result.rb
|
201
|
-
- lib/moab/version_metadata.rb
|
202
200
|
- lib/moab/version_metadata_entry.rb
|
203
|
-
- lib/moab/version_metadata_event.rb
|
204
201
|
- lib/serializer.rb
|
205
202
|
- lib/serializer/manifest.rb
|
206
203
|
- lib/serializer/serializable.rb
|
207
|
-
- lib/stanford/active_fedora_object.rb
|
208
204
|
- lib/stanford/content_inventory.rb
|
209
|
-
- lib/stanford/dor_metadata.rb
|
210
|
-
- lib/stanford/moab_storage_directory.rb
|
211
205
|
- lib/stanford/storage_object_validator.rb
|
212
206
|
- lib/stanford/storage_repository.rb
|
213
207
|
- lib/stanford/storage_services.rb
|
@@ -221,16 +215,16 @@ require_paths:
|
|
221
215
|
- lib
|
222
216
|
required_ruby_version: !ruby/object:Gem::Requirement
|
223
217
|
requirements:
|
224
|
-
- - "
|
218
|
+
- - ">="
|
225
219
|
- !ruby/object:Gem::Version
|
226
|
-
version: '2.
|
220
|
+
version: '2.6'
|
227
221
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
228
222
|
requirements:
|
229
223
|
- - ">="
|
230
224
|
- !ruby/object:Gem::Version
|
231
225
|
version: '0'
|
232
226
|
requirements: []
|
233
|
-
rubygems_version: 3.
|
227
|
+
rubygems_version: 3.1.4
|
234
228
|
signing_key:
|
235
229
|
specification_version: 4
|
236
230
|
summary: Ruby implementation of digital object versioning toolkit used by the SULAIR
|