moab-versioning 2.3.0 → 2.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e4b6638d612a715c99575b74595385e412fc8fd4
4
- data.tar.gz: dec35bf65bb48c61e4f84447f06a4a244d556f8e
3
+ metadata.gz: 2cf042d5123eebc1b9c1b9693e05c45c99912b39
4
+ data.tar.gz: 6e52763c9a40797606c858e7794eb9014d2fab7c
5
5
  SHA512:
6
- metadata.gz: f1ae80fe9600cea7429abaeec22a74d962e7eec43738364f65860b5d127449bf22aae5cb25d237d17eeb469b918a155e200bce6d42f597c61ab1cc6a862e37c6
7
- data.tar.gz: 2dd2b7cc61a003701e4bc2a08f7b63a0bd9b0927d03a30458ae24cc47e18b0e917709ffce7e6dcebbbd243ab5391456f84100b13d878e4ae1fcdd726348e6d47
6
+ metadata.gz: b2ee7236ad243d907c51fdd82835c0e12829dc99a2b1a65bc1f9ed2b3c0d70ce396ebe7c58459cfdf0a2c4aa3479363fa80352ce3a343e31a308ba78e2e52652
7
+ data.tar.gz: 0c61777fa909a4b57563ad3a9a94f1a8c46a6096dc58d97dd8c4ae86370c0e59899ae9dfb6805f3a96d00a20cb4a398e9bb3fc3d7615c5e0ba50d1b0bade36dd
data/lib/moab.rb CHANGED
@@ -56,3 +56,4 @@ require 'moab/storage_repository'
56
56
  require 'moab/storage_services'
57
57
  require 'moab/exceptions'
58
58
  require 'moab/verification_result'
59
+ require 'moab/storage_object_validator'
@@ -0,0 +1,180 @@
1
+ require 'moab'
2
+
3
+ module Moab
4
+ # Given a druid path, are the contents actually a well-formed Moab?
5
+ # Shameless green: repetitious code included.
6
+ class StorageObjectValidator
7
+
8
+ EXPECTED_DATA_SUB_DIRS = ["content", "metadata"].freeze
9
+ IMPLICIT_DIRS = ['.', '..'].freeze # unlike Find.find, Dir.entries returns these
10
+ DATA_DIR_NAME = "data".freeze
11
+ EXPECTED_VERSION_SUB_DIRS = [DATA_DIR_NAME, "manifests"].freeze
12
+ MANIFEST_INVENTORY_PATH = 'manifests/manifestInventory.xml'.freeze
13
+ SIGNATURE_CATALOG_PATH = 'manifests/signatureCatalog.xml'.freeze
14
+
15
+ # error codes
16
+ INCORRECT_DIR = 0
17
+ MISSING_DIR = 1
18
+ EXTRA_CHILD_DETECTED = 2
19
+ VERSION_DIR_BAD_FORMAT = 3
20
+ NO_SIGNATURE_CATALOG = 4
21
+ NO_MANIFEST_INVENTORY = 5
22
+ NO_XML_FILES = 6
23
+ VERSIONS_NOT_IN_ORDER = 7
24
+ FILES_IN_VERSION_DIR = 8
25
+
26
+ ERROR_CODE_TO_MESSAGES = {
27
+ INCORRECT_DIR=> "Incorrect items in path",
28
+ MISSING_DIR => "Missing directory: %{addl}",
29
+ EXTRA_CHILD_DETECTED => "Unexpected item in path: %{addl}",
30
+ VERSION_DIR_BAD_FORMAT => "Version directory name not in 'v00xx' format",
31
+ FILES_IN_VERSION_DIR => "Top level should contain only sequential version directories. Also contains files: %{addl}",
32
+ NO_SIGNATURE_CATALOG => "Version: %{addl} Missing signatureCatalog.xml",
33
+ NO_MANIFEST_INVENTORY => "Version: %{addl} Missing manifestInventory.xml",
34
+ NO_XML_FILES => "Version: %{addl} Missing all required metadata files",
35
+ VERSIONS_NOT_IN_ORDER => "Should contain only sequential version directories. Current directories: %{addl}"
36
+ }.freeze
37
+
38
+ attr_reader :storage_obj_path
39
+
40
+ def initialize(storage_object)
41
+ @storage_obj_path = storage_object.object_pathname
42
+ @directory_entries_hash = {}
43
+ end
44
+
45
+ def validation_errors
46
+ errors = []
47
+ errors.concat check_correctly_named_version_dirs
48
+ errors.concat check_sequential_version_dirs if errors.empty?
49
+ errors.concat check_correctly_formed_moabs if errors.empty?
50
+ errors
51
+ end
52
+
53
+ # TODO: Figure out which methods should be public
54
+
55
+ private
56
+
57
+ def version_directories
58
+ @vdirs ||= sub_dirs(storage_obj_path)
59
+ end
60
+
61
+ def check_correctly_named_version_dirs
62
+ errors = []
63
+ version_directories.each do |version_dir|
64
+ errors << result_hash(VERSION_DIR_BAD_FORMAT) unless version_dir =~ /^[v]\d{4}$/
65
+ end
66
+ errors
67
+ end
68
+
69
+ # This method will be called only if the version directories are correctly named
70
+ def check_sequential_version_dirs
71
+ errors = []
72
+ version_directories.each_with_index do |dir_name, index|
73
+ expected_vers_num = index + 1 # version numbering starts at 1, array indexing starts at 0
74
+ if dir_name[1..-1].to_i != expected_vers_num
75
+ errors << result_hash(VERSIONS_NOT_IN_ORDER, version_directories)
76
+ break
77
+ end
78
+ end
79
+
80
+ errors
81
+ end
82
+
83
+ def check_correctly_formed_moabs
84
+ errors = []
85
+ version_directories.each do |version_dir|
86
+ version_path = "#{storage_obj_path}/#{version_dir}"
87
+ version_sub_dirs = sub_dirs(version_path)
88
+ before_result_size = errors.size
89
+ errors.concat check_sub_dirs(version_sub_dirs, version_dir, EXPECTED_VERSION_SUB_DIRS)
90
+ after_result_size = errors.size
91
+ # run the following checks if this version dir passes check_sub_dirs, even if some prior version dirs didn't
92
+ if before_result_size == after_result_size
93
+ data_dir_path = "#{version_path}/#{DATA_DIR_NAME}"
94
+ data_sub_dirs = sub_dirs(data_dir_path)
95
+ errors.concat check_sub_dirs(data_sub_dirs, version_dir, EXPECTED_DATA_SUB_DIRS)
96
+ errors.concat check_required_manifest_files(version_path, version_dir)
97
+ end
98
+ end
99
+
100
+ errors
101
+ end
102
+
103
+ def check_sub_dirs(sub_dirs, version, required_sub_dirs)
104
+ errors = []
105
+ sub_dir_count = sub_dirs.size
106
+ if sub_dir_count == required_sub_dirs.size
107
+ errors.concat expected_dirs(sub_dirs, version, required_sub_dirs)
108
+ elsif sub_dir_count > required_sub_dirs.size
109
+ errors.concat found_unexpected(sub_dirs, version, required_sub_dirs)
110
+ elsif sub_dir_count < required_sub_dirs.size
111
+ errors.concat missing_dir(sub_dirs, version, required_sub_dirs)
112
+ end
113
+ errors
114
+ end
115
+
116
+ # This method removes the implicit '.' and '..' directories.
117
+ # Returns an array of strings.
118
+ def directory_entries(path)
119
+ @directory_entries_hash[path] ||=
120
+ begin
121
+ dirs = []
122
+ (Dir.entries(path).sort - IMPLICIT_DIRS).each do |child|
123
+ dirs << child
124
+ end
125
+ dirs
126
+ end
127
+ end
128
+
129
+ def sub_dirs(path)
130
+ directory_entries(path)
131
+ end
132
+
133
+ def found_unexpected(array, version, required_sub_dirs)
134
+ errors = []
135
+ unexpected = (array - required_sub_dirs)
136
+ unexpected = "#{unexpected} Version: #{version}"
137
+ errors << result_hash(EXTRA_CHILD_DETECTED, unexpected)
138
+ errors
139
+ end
140
+
141
+ def missing_dir(array, version, required_sub_dirs)
142
+ errors = []
143
+ missing = (required_sub_dirs - array)
144
+ missing ="#{missing} Version: #{version}"
145
+ errors << result_hash(MISSING_DIR, missing)
146
+ errors
147
+ end
148
+
149
+ def expected_dirs(array, _version, required_sub_dirs)
150
+ errors = []
151
+ errors << result_hash(INCORRECT_DIR) unless array == required_sub_dirs
152
+ errors
153
+ end
154
+
155
+ def result_hash(response_code, addl=nil)
156
+ { response_code => error_code_msg(response_code, addl) }
157
+ end
158
+
159
+ def error_code_msg(response_code, addl=nil)
160
+ format(ERROR_CODE_TO_MESSAGES[response_code], addl: addl)
161
+ end
162
+
163
+ def check_required_manifest_files(dir, version)
164
+ errors = []
165
+ has_manifest_inventory = File.exist?("#{dir}/#{MANIFEST_INVENTORY_PATH}")
166
+ has_signature_catalog = File.exist?("#{dir}/#{SIGNATURE_CATALOG_PATH}")
167
+ result = if has_manifest_inventory && has_signature_catalog
168
+ nil
169
+ elsif has_manifest_inventory && !has_signature_catalog
170
+ result_hash(NO_SIGNATURE_CATALOG, version)
171
+ elsif !has_manifest_inventory && has_signature_catalog
172
+ result_hash(NO_MANIFEST_INVENTORY, version)
173
+ else
174
+ result_hash(NO_XML_FILES, version)
175
+ end
176
+ errors << result if result
177
+ errors
178
+ end
179
+ end
180
+ end
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: 2.3.0
4
+ version: 2.4.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: 2017-11-01 00:00:00.000000000 Z
14
+ date: 2017-11-02 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: confstruct
@@ -261,6 +261,7 @@ files:
261
261
  - lib/moab/signature_catalog_entry.rb
262
262
  - lib/moab/stanford.rb
263
263
  - lib/moab/storage_object.rb
264
+ - lib/moab/storage_object_validator.rb
264
265
  - lib/moab/storage_object_version.rb
265
266
  - lib/moab/storage_repository.rb
266
267
  - lib/moab/storage_services.rb
@@ -296,7 +297,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
296
297
  requirements:
297
298
  - - ">="
298
299
  - !ruby/object:Gem::Version
299
- version: 1.3.6
300
+ version: '0'
300
301
  requirements: []
301
302
  rubyforge_project:
302
303
  rubygems_version: 2.6.11