longleaf 0.1.0 → 1.1.1
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/.circleci/config.yml +94 -0
- data/.editorconfig +13 -0
- data/.gitignore +4 -1
- data/.rubocop.yml +44 -0
- data/.rubocop_todo.yml +834 -0
- data/.yardopts +1 -0
- data/Gemfile +16 -1
- data/README.md +98 -12
- data/Rakefile +6 -0
- data/bin/setup +16 -1
- data/docs/aboutlongleaf.md +28 -0
- data/docs/extra.css +32 -0
- data/docs/img/change-file.png +0 -0
- data/docs/img/ll-example-preserved.png +0 -0
- data/docs/index.md +19 -0
- data/docs/install.md +66 -0
- data/docs/ll-example/config-example-relative.yml +33 -0
- data/docs/ll-example/files-dir/LLexample-PDF.pdf +0 -0
- data/docs/ll-example/files-dir/LLexample-TOCHANGE.txt +15 -0
- data/docs/ll-example/files-dir/LLexample-tokeep.txt +10 -0
- data/docs/ll-example/metadata-dir/.gitkeep +0 -0
- data/docs/ll-example/replica-files/.gitkeep +0 -0
- data/docs/ll-example/replica-metadata/.gitkeep +0 -0
- data/docs/quickstart.md +270 -0
- data/docs/rdocs/Longleaf.html +135 -0
- data/docs/rdocs/Longleaf/AppFields.html +178 -0
- data/docs/rdocs/Longleaf/ApplicationConfigDeserializer.html +631 -0
- data/docs/rdocs/Longleaf/ApplicationConfigManager.html +610 -0
- data/docs/rdocs/Longleaf/ApplicationConfigValidator.html +238 -0
- data/docs/rdocs/Longleaf/CLI.html +909 -0
- data/docs/rdocs/Longleaf/ChecksumMismatchError.html +151 -0
- data/docs/rdocs/Longleaf/ConfigBuilder.html +1339 -0
- data/docs/rdocs/Longleaf/ConfigurationError.html +143 -0
- data/docs/rdocs/Longleaf/ConfigurationValidator.html +227 -0
- data/docs/rdocs/Longleaf/DeregisterCommand.html +420 -0
- data/docs/rdocs/Longleaf/DeregisterEvent.html +453 -0
- data/docs/rdocs/Longleaf/DeregistrationError.html +151 -0
- data/docs/rdocs/Longleaf/DigestHelper.html +419 -0
- data/docs/rdocs/Longleaf/EventError.html +147 -0
- data/docs/rdocs/Longleaf/EventNames.html +163 -0
- data/docs/rdocs/Longleaf/EventStatusTracking.html +656 -0
- data/docs/rdocs/Longleaf/FileCheckService.html +540 -0
- data/docs/rdocs/Longleaf/FileHelpers.html +520 -0
- data/docs/rdocs/Longleaf/FileRecord.html +716 -0
- data/docs/rdocs/Longleaf/FileSelector.html +901 -0
- data/docs/rdocs/Longleaf/FixityCheckService.html +691 -0
- data/docs/rdocs/Longleaf/IndexManager.html +1155 -0
- data/docs/rdocs/Longleaf/InvalidDigestAlgorithmError.html +143 -0
- data/docs/rdocs/Longleaf/InvalidStoragePathError.html +143 -0
- data/docs/rdocs/Longleaf/Logging.html +405 -0
- data/docs/rdocs/Longleaf/Logging/RedirectingLogger.html +1213 -0
- data/docs/rdocs/Longleaf/LongleafError.html +139 -0
- data/docs/rdocs/Longleaf/MDFields.html +193 -0
- data/docs/rdocs/Longleaf/MetadataBuilder.html +787 -0
- data/docs/rdocs/Longleaf/MetadataDeserializer.html +537 -0
- data/docs/rdocs/Longleaf/MetadataError.html +143 -0
- data/docs/rdocs/Longleaf/MetadataPersistenceManager.html +539 -0
- data/docs/rdocs/Longleaf/MetadataRecord.html +1411 -0
- data/docs/rdocs/Longleaf/MetadataSerializer.html +786 -0
- data/docs/rdocs/Longleaf/PreservationServiceError.html +147 -0
- data/docs/rdocs/Longleaf/PreserveCommand.html +410 -0
- data/docs/rdocs/Longleaf/PreserveEvent.html +491 -0
- data/docs/rdocs/Longleaf/RegisterCommand.html +428 -0
- data/docs/rdocs/Longleaf/RegisterEvent.html +628 -0
- data/docs/rdocs/Longleaf/RegisteredFileSelector.html +446 -0
- data/docs/rdocs/Longleaf/RegistrationError.html +151 -0
- data/docs/rdocs/Longleaf/ReindexCommand.html +576 -0
- data/docs/rdocs/Longleaf/RsyncReplicationService.html +1180 -0
- data/docs/rdocs/Longleaf/SequelIndexDriver.html +1978 -0
- data/docs/rdocs/Longleaf/ServiceCandidateFilesystemIterator.html +572 -0
- data/docs/rdocs/Longleaf/ServiceCandidateIndexIterator.html +532 -0
- data/docs/rdocs/Longleaf/ServiceCandidateLocator.html +333 -0
- data/docs/rdocs/Longleaf/ServiceClassCache.html +725 -0
- data/docs/rdocs/Longleaf/ServiceDateHelper.html +425 -0
- data/docs/rdocs/Longleaf/ServiceDefinition.html +683 -0
- data/docs/rdocs/Longleaf/ServiceDefinitionManager.html +371 -0
- data/docs/rdocs/Longleaf/ServiceDefinitionValidator.html +269 -0
- data/docs/rdocs/Longleaf/ServiceFields.html +173 -0
- data/docs/rdocs/Longleaf/ServiceManager.html +1229 -0
- data/docs/rdocs/Longleaf/ServiceMappingManager.html +410 -0
- data/docs/rdocs/Longleaf/ServiceMappingValidator.html +347 -0
- data/docs/rdocs/Longleaf/ServiceRecord.html +821 -0
- data/docs/rdocs/Longleaf/StorageLocation.html +985 -0
- data/docs/rdocs/Longleaf/StorageLocationManager.html +729 -0
- data/docs/rdocs/Longleaf/StorageLocationUnavailableError.html +143 -0
- data/docs/rdocs/Longleaf/StorageLocationValidator.html +373 -0
- data/docs/rdocs/Longleaf/StoragePathValidator.html +253 -0
- data/docs/rdocs/Longleaf/SystemConfigBuilder.html +441 -0
- data/docs/rdocs/Longleaf/SystemConfigFields.html +163 -0
- data/docs/rdocs/Longleaf/ValidateConfigCommand.html +451 -0
- data/docs/rdocs/Longleaf/ValidateMetadataCommand.html +408 -0
- data/docs/rdocs/_index.html +660 -0
- data/docs/rdocs/class_list.html +51 -0
- data/docs/rdocs/css/common.css +1 -0
- data/docs/rdocs/css/full_list.css +58 -0
- data/docs/rdocs/css/style.css +496 -0
- data/docs/rdocs/file.README.html +165 -0
- data/docs/rdocs/file_list.html +56 -0
- data/docs/rdocs/frames.html +17 -0
- data/docs/rdocs/index.html +165 -0
- data/docs/rdocs/js/app.js +303 -0
- data/docs/rdocs/js/full_list.js +216 -0
- data/docs/rdocs/js/jquery.js +4 -0
- data/docs/rdocs/method_list.html +2051 -0
- data/docs/rdocs/top-level-namespace.html +110 -0
- data/lib/longleaf/candidates/file_selector.rb +150 -0
- data/lib/longleaf/candidates/manifest_digest_provider.rb +17 -0
- data/lib/longleaf/candidates/physical_path_provider.rb +17 -0
- data/lib/longleaf/candidates/registered_file_selector.rb +67 -0
- data/lib/longleaf/candidates/service_candidate_filesystem_iterator.rb +93 -0
- data/lib/longleaf/candidates/service_candidate_index_iterator.rb +84 -0
- data/lib/longleaf/candidates/service_candidate_locator.rb +23 -0
- data/lib/longleaf/candidates/single_digest_provider.rb +13 -0
- data/lib/longleaf/cli.rb +252 -46
- data/lib/longleaf/commands/deregister_command.rb +51 -0
- data/lib/longleaf/commands/preserve_command.rb +50 -0
- data/lib/longleaf/commands/register_command.rb +34 -43
- data/lib/longleaf/commands/reindex_command.rb +92 -0
- data/lib/longleaf/commands/validate_config_command.rb +33 -8
- data/lib/longleaf/commands/validate_metadata_command.rb +51 -0
- data/lib/longleaf/errors.rb +26 -7
- data/lib/longleaf/events/deregister_event.rb +53 -0
- data/lib/longleaf/events/event_names.rb +9 -0
- data/lib/longleaf/events/event_status_tracking.rb +59 -0
- data/lib/longleaf/events/preserve_event.rb +82 -0
- data/lib/longleaf/events/register_event.rb +59 -51
- data/lib/longleaf/helpers/case_insensitive_hash.rb +38 -0
- data/lib/longleaf/helpers/digest_helper.rb +56 -0
- data/lib/longleaf/helpers/s3_uri_helper.rb +86 -0
- data/lib/longleaf/helpers/selection_options_parser.rb +215 -0
- data/lib/longleaf/helpers/service_date_helper.rb +78 -0
- data/lib/longleaf/indexing/index_manager.rb +101 -0
- data/lib/longleaf/indexing/sequel_index_driver.rb +306 -0
- data/lib/longleaf/logging.rb +5 -4
- data/lib/longleaf/logging/redirecting_logger.rb +30 -25
- data/lib/longleaf/models/app_fields.rb +7 -2
- data/lib/longleaf/models/file_record.rb +31 -8
- data/lib/longleaf/models/filesystem_metadata_location.rb +56 -0
- data/lib/longleaf/models/filesystem_storage_location.rb +52 -0
- data/lib/longleaf/models/md_fields.rb +3 -1
- data/lib/longleaf/models/metadata_location.rb +47 -0
- data/lib/longleaf/models/metadata_record.rb +43 -16
- data/lib/longleaf/models/s3_storage_location.rb +138 -0
- data/lib/longleaf/models/service_definition.rb +7 -6
- data/lib/longleaf/models/service_fields.rb +7 -1
- data/lib/longleaf/models/service_record.rb +10 -6
- data/lib/longleaf/models/storage_location.rb +24 -19
- data/lib/longleaf/models/storage_types.rb +9 -0
- data/lib/longleaf/models/system_config_fields.rb +9 -0
- data/lib/longleaf/preservation_services/file_check_service.rb +59 -0
- data/lib/longleaf/preservation_services/fixity_check_service.rb +124 -0
- data/lib/longleaf/preservation_services/rsync_replication_service.rb +198 -0
- data/lib/longleaf/preservation_services/s3_replication_service.rb +131 -0
- data/lib/longleaf/services/application_config_deserializer.rb +81 -24
- data/lib/longleaf/services/application_config_manager.rb +20 -6
- data/lib/longleaf/services/application_config_validator.rb +19 -9
- data/lib/longleaf/services/configuration_validator.rb +67 -4
- data/lib/longleaf/services/filesystem_location_validator.rb +16 -0
- data/lib/longleaf/services/metadata_deserializer.rb +115 -42
- data/lib/longleaf/services/metadata_persistence_manager.rb +47 -0
- data/lib/longleaf/services/metadata_serializer.rb +156 -23
- data/lib/longleaf/services/metadata_validator.rb +76 -0
- data/lib/longleaf/services/s3_location_validator.rb +19 -0
- data/lib/longleaf/services/service_class_cache.rb +112 -0
- data/lib/longleaf/services/service_definition_manager.rb +10 -7
- data/lib/longleaf/services/service_definition_validator.rb +25 -18
- data/lib/longleaf/services/service_manager.rb +86 -11
- data/lib/longleaf/services/service_mapping_manager.rb +13 -12
- data/lib/longleaf/services/service_mapping_validator.rb +36 -26
- data/lib/longleaf/services/storage_location_manager.rb +76 -15
- data/lib/longleaf/services/storage_location_validator.rb +49 -35
- data/lib/longleaf/specs/config_builder.rb +47 -23
- data/lib/longleaf/specs/config_validator_helpers.rb +16 -0
- data/lib/longleaf/specs/custom_matchers.rb +9 -0
- data/lib/longleaf/specs/file_helpers.rb +61 -0
- data/lib/longleaf/specs/metadata_builder.rb +98 -0
- data/lib/longleaf/specs/system_config_builder.rb +27 -0
- data/lib/longleaf/version.rb +1 -1
- data/longleaf.gemspec +20 -7
- data/mkdocs.yml +21 -0
- metadata +308 -24
- data/.travis.yml +0 -4
- data/lib/longleaf/commands/abstract_command.rb +0 -37
- data/lib/longleaf/services/storage_path_validator.rb +0 -16
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require 'longleaf/services/application_config_deserializer'
|
|
2
|
+
require 'longleaf/events/deregister_event'
|
|
3
|
+
require 'longleaf/models/file_record'
|
|
4
|
+
require 'longleaf/events/event_names'
|
|
5
|
+
require 'longleaf/events/event_status_tracking'
|
|
6
|
+
|
|
7
|
+
module Longleaf
|
|
8
|
+
# Command for deregistering files with longleaf
|
|
9
|
+
class DeregisterCommand
|
|
10
|
+
include Longleaf::EventStatusTracking
|
|
11
|
+
|
|
12
|
+
def initialize(app_manager)
|
|
13
|
+
@app_manager = app_manager
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Execute the deregister command on the given parameters
|
|
17
|
+
# @param file_selector [FileSelector] selector for files to deregister
|
|
18
|
+
# @param force [Boolean] force flag
|
|
19
|
+
# @return [Integer] status code
|
|
20
|
+
def execute(file_selector:, force: false)
|
|
21
|
+
start_time = Time.now
|
|
22
|
+
logger.info('Performing deregister command')
|
|
23
|
+
begin
|
|
24
|
+
# Perform deregister events on each of the file paths provided
|
|
25
|
+
loop do
|
|
26
|
+
f_path = file_selector.next_path
|
|
27
|
+
break if f_path.nil?
|
|
28
|
+
|
|
29
|
+
storage_location = @app_manager.location_manager.get_location_by_path(f_path)
|
|
30
|
+
|
|
31
|
+
file_rec = FileRecord.new(f_path, storage_location)
|
|
32
|
+
unless file_rec.metadata_present?
|
|
33
|
+
raise DeregistrationError.new("Cannot deregister #{f_path}, file is not registered.")
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
@app_manager.md_manager.load(file_rec)
|
|
37
|
+
|
|
38
|
+
event = DeregisterEvent.new(file_rec: file_rec, force: force, app_manager: @app_manager)
|
|
39
|
+
track_status(event.perform)
|
|
40
|
+
end
|
|
41
|
+
rescue RegistrationError, DeregistrationError, InvalidStoragePathError, StorageLocationUnavailableError => err
|
|
42
|
+
record_failure(EventNames::DEREGISTER, nil, err.message)
|
|
43
|
+
rescue => err
|
|
44
|
+
record_failure(EventNames::DEREGISTER, error: err)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
logger.info("Completed deregister command in #{Time.now - start_time}s")
|
|
48
|
+
return_status
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
require 'longleaf/errors'
|
|
2
|
+
require 'longleaf/events/event_status_tracking'
|
|
3
|
+
require 'longleaf/events/preserve_event'
|
|
4
|
+
require 'longleaf/services/application_config_deserializer'
|
|
5
|
+
require 'longleaf/candidates/file_selector'
|
|
6
|
+
require 'longleaf/candidates/service_candidate_locator'
|
|
7
|
+
require 'longleaf/events/event_names'
|
|
8
|
+
require 'longleaf/logging'
|
|
9
|
+
|
|
10
|
+
module Longleaf
|
|
11
|
+
# Command for preserving files
|
|
12
|
+
class PreserveCommand
|
|
13
|
+
include Longleaf::Logging
|
|
14
|
+
include Longleaf::EventStatusTracking
|
|
15
|
+
|
|
16
|
+
def initialize(app_manager)
|
|
17
|
+
@app_manager = app_manager
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Execute the preserve command on the given parameters
|
|
21
|
+
# @param file_selector [FileSelector] selector for files to preserve
|
|
22
|
+
# @param force [Boolean] force flag
|
|
23
|
+
# @return [Integer] status code
|
|
24
|
+
def execute(file_selector:, force: false)
|
|
25
|
+
start_time = Time.now
|
|
26
|
+
logger.info('Performing preserve command')
|
|
27
|
+
begin
|
|
28
|
+
# Perform preserve events on each of the file paths provided
|
|
29
|
+
candidate_locator = ServiceCandidateLocator.new(@app_manager)
|
|
30
|
+
candidate_it = candidate_locator.candidate_iterator(file_selector, EventNames::PRESERVE, force)
|
|
31
|
+
candidate_it.each do |file_rec|
|
|
32
|
+
begin
|
|
33
|
+
logger.debug("Selected candidate #{file_rec.path} for a preserve event")
|
|
34
|
+
preserve_event = PreserveEvent.new(file_rec: file_rec, force: force, app_manager: @app_manager)
|
|
35
|
+
track_status(preserve_event.perform)
|
|
36
|
+
rescue InvalidStoragePathError => e
|
|
37
|
+
record_failure(EventNames::PRESERVE, nil, e.message)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
rescue LongleafError => e
|
|
41
|
+
record_failure(EventNames::PRESERVE, nil, e.message)
|
|
42
|
+
rescue => err
|
|
43
|
+
record_failure(EventNames::PRESERVE, error: err)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
logger.info("Completed preserve command in #{Time.now - start_time}s")
|
|
47
|
+
return_status
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -1,59 +1,50 @@
|
|
|
1
1
|
require 'longleaf/services/application_config_deserializer'
|
|
2
2
|
require 'longleaf/events/register_event'
|
|
3
3
|
require 'longleaf/models/file_record'
|
|
4
|
-
require 'longleaf/
|
|
4
|
+
require 'longleaf/events/event_names'
|
|
5
|
+
require 'longleaf/events/event_status_tracking'
|
|
5
6
|
|
|
6
|
-
# Command for registering files with longleaf
|
|
7
7
|
module Longleaf
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
# Command for registering files with longleaf
|
|
9
|
+
class RegisterCommand
|
|
10
|
+
include Longleaf::EventStatusTracking
|
|
11
|
+
|
|
12
|
+
def initialize(app_manager)
|
|
13
|
+
@app_manager = app_manager
|
|
12
14
|
end
|
|
13
15
|
|
|
14
16
|
# Execute the register command on the given parameters
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
# @param file_selector [FileSelector] selector for files to register
|
|
18
|
+
# @param force [Boolean] force flag
|
|
19
|
+
# @param digest_provider [ManifestDigestProvider] object which provides digests for files being registered
|
|
20
|
+
# @param physical_provider [PhysicalPathProvider] object which provides physical paths for files being registered
|
|
21
|
+
# @return [Integer] status code
|
|
22
|
+
def execute(file_selector:, force: false, digest_provider: nil, physical_provider: nil)
|
|
23
|
+
start_time = Time.now
|
|
24
|
+
logger.info('Performing register command')
|
|
21
25
|
begin
|
|
22
|
-
# Retrieve the application configuration
|
|
23
|
-
app_manager = Longleaf::ApplicationConfigDeserializer.deserialize(@config_path)
|
|
24
|
-
|
|
25
26
|
# Perform register events on each of the file paths provided
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
register_event = RegisterEvent.new(file_rec: file_rec, force: force, app_manager: app_manager,
|
|
40
|
-
checksums: checksums)
|
|
41
|
-
register_event.perform
|
|
42
|
-
|
|
43
|
-
record_success(RegisterEvent::EVENT_NAME, f_path)
|
|
44
|
-
rescue RegistrationError => err
|
|
45
|
-
record_failure(RegisterEvent::EVENT_NAME, f_path, err.message)
|
|
46
|
-
rescue InvalidStoragePathError => err
|
|
47
|
-
record_failure(RegisterEvent::EVENT_NAME, f_path, err.message)
|
|
48
|
-
end
|
|
27
|
+
loop do
|
|
28
|
+
f_path = file_selector.next_path
|
|
29
|
+
break if f_path.nil?
|
|
30
|
+
|
|
31
|
+
storage_location = @app_manager.location_manager.get_location_by_path(f_path)
|
|
32
|
+
|
|
33
|
+
phys_path = physical_provider.get_physical_path(f_path)
|
|
34
|
+
file_rec = FileRecord.new(f_path, storage_location, nil, phys_path)
|
|
35
|
+
|
|
36
|
+
register_event = RegisterEvent.new(file_rec: file_rec, force: force, app_manager: @app_manager,
|
|
37
|
+
digest_provider: digest_provider)
|
|
38
|
+
track_status(register_event.perform)
|
|
49
39
|
end
|
|
50
|
-
rescue
|
|
51
|
-
record_failure(
|
|
40
|
+
rescue InvalidStoragePathError, StorageLocationUnavailableError => err
|
|
41
|
+
record_failure(EventNames::REGISTER, nil, err.message)
|
|
52
42
|
rescue => err
|
|
53
|
-
record_failure(
|
|
43
|
+
record_failure(EventNames::REGISTER, error: err)
|
|
54
44
|
end
|
|
55
|
-
|
|
45
|
+
|
|
46
|
+
logger.info("Completed register command in #{Time.now - start_time}s")
|
|
56
47
|
return_status
|
|
57
48
|
end
|
|
58
49
|
end
|
|
59
|
-
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
require 'longleaf/errors'
|
|
2
|
+
require 'longleaf/events/event_status_tracking'
|
|
3
|
+
require 'longleaf/logging'
|
|
4
|
+
|
|
5
|
+
module Longleaf
|
|
6
|
+
# Command for reindexing metadata
|
|
7
|
+
class ReindexCommand
|
|
8
|
+
include Longleaf::Logging
|
|
9
|
+
include Longleaf::EventStatusTracking
|
|
10
|
+
|
|
11
|
+
def initialize(app_manager)
|
|
12
|
+
@app_manager = app_manager
|
|
13
|
+
@index_manager = @app_manager.index_manager
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Execute the reindex command
|
|
17
|
+
# @param only_if_stale [boolean] if true, then the reindex command will perform no operation unless the index is stale.
|
|
18
|
+
# @return [Integer] status code
|
|
19
|
+
def execute(only_if_stale: false)
|
|
20
|
+
if !@index_manager.using_index?
|
|
21
|
+
record_failure("Cannot perform reindex, no index is configured")
|
|
22
|
+
return return_status
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
if only_if_stale && !@index_manager.index_stale?
|
|
26
|
+
record_success("Index is not stale, performing no action")
|
|
27
|
+
return return_status
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
start_time = Time.now
|
|
31
|
+
logger.info('Performing full reindex')
|
|
32
|
+
results = nil
|
|
33
|
+
begin
|
|
34
|
+
start_time = Time.now.utc
|
|
35
|
+
|
|
36
|
+
selector = all_storage_locations_selector
|
|
37
|
+
|
|
38
|
+
# Repopulate the index
|
|
39
|
+
results = index_all(selector)
|
|
40
|
+
|
|
41
|
+
# List and then clear all files which were not reindexed
|
|
42
|
+
@index_manager.each_registered_path(selector, older_than: start_time) do |file_path|
|
|
43
|
+
logger.warn("Clearing '#{file_path}' from index, file is no longer present.")
|
|
44
|
+
end
|
|
45
|
+
@index_manager.clear_index(start_time)
|
|
46
|
+
|
|
47
|
+
# Update the state of the index to indicate it has been reindexed
|
|
48
|
+
@index_manager.update_index_state
|
|
49
|
+
rescue => err
|
|
50
|
+
record_failure("Encountered error while reindexing", error: err)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
if results['fail'] > 0
|
|
54
|
+
record_success("Completed reindexing, #{results['success']} successful, #{results['fail']} failed.")
|
|
55
|
+
else
|
|
56
|
+
record_success("Completed reindexing, #{results['success']} successful.")
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
logger.info("Completed full reindex in #{Time.now - start_time}s")
|
|
60
|
+
return_status
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
private
|
|
64
|
+
def index_all(selector)
|
|
65
|
+
count = 0
|
|
66
|
+
failures = 0
|
|
67
|
+
|
|
68
|
+
selector.each do |file_path|
|
|
69
|
+
begin
|
|
70
|
+
storage_loc = @app_manager.location_manager.get_location_by_path(file_path)
|
|
71
|
+
file_rec = FileRecord.new(file_path, storage_loc)
|
|
72
|
+
|
|
73
|
+
@app_manager.md_manager.load(file_rec)
|
|
74
|
+
@index_manager.index(file_rec)
|
|
75
|
+
|
|
76
|
+
record_success("Reindexed #{file_rec.path}")
|
|
77
|
+
count += 1
|
|
78
|
+
rescue LongleafError => err
|
|
79
|
+
record_failure("Failed to reindex #{file_rec.path}: #{err.message}")
|
|
80
|
+
failures += 1
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
{'success' => count, 'fail' => failures}
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def all_storage_locations_selector
|
|
87
|
+
storage_loc_names = @app_manager.location_manager.locations.keys
|
|
88
|
+
|
|
89
|
+
RegisteredFileSelector.new(storage_locations: storage_loc_names, app_config: @app_manager)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -1,29 +1,54 @@
|
|
|
1
1
|
require 'longleaf/services/application_config_deserializer'
|
|
2
|
-
require 'longleaf/
|
|
2
|
+
require 'longleaf/events/event_status_tracking'
|
|
3
3
|
|
|
4
4
|
module Longleaf
|
|
5
|
-
|
|
5
|
+
# Command for validating an application configuration file
|
|
6
|
+
class ValidateConfigCommand
|
|
7
|
+
include Longleaf::EventStatusTracking
|
|
8
|
+
|
|
6
9
|
def initialize(config_path)
|
|
7
10
|
@config_path = config_path
|
|
8
11
|
end
|
|
9
|
-
|
|
12
|
+
|
|
13
|
+
# Execute the validate command on the specified configuration yml file
|
|
10
14
|
def execute
|
|
15
|
+
start_time = Time.now
|
|
16
|
+
logger.info('Performing validate configuration command')
|
|
11
17
|
begin
|
|
12
18
|
app_config_manager = Longleaf::ApplicationConfigDeserializer.deserialize(@config_path)
|
|
13
|
-
|
|
19
|
+
|
|
14
20
|
location_manager = app_config_manager.location_manager
|
|
15
21
|
location_manager.locations.each do |name, location|
|
|
16
22
|
location.available?
|
|
17
23
|
end
|
|
18
|
-
|
|
24
|
+
|
|
25
|
+
validate_services(app_config_manager.service_manager)
|
|
26
|
+
|
|
19
27
|
record_success("Application configuration passed validation: #{@config_path}")
|
|
20
28
|
rescue Longleaf::ConfigurationError, Longleaf::StorageLocationUnavailableError => err
|
|
21
|
-
record_failure("Application configuration invalid due to the following issue:\n#{err.message}")
|
|
29
|
+
record_failure("Application configuration invalid due to the following issue(s):\n#{err.message}")
|
|
22
30
|
rescue => err
|
|
23
31
|
record_failure("Failed to validate application configuration", error: err)
|
|
24
32
|
end
|
|
25
|
-
|
|
33
|
+
|
|
34
|
+
logger.info("Completed validate configuration command in #{Time.now - start_time}s")
|
|
26
35
|
return_status
|
|
27
36
|
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
# Verify that all defined services are valid and may be instantiated with the given configuration,
|
|
40
|
+
# according to internal expectations.
|
|
41
|
+
# @raise ConfigurationError if any services may not be instantiated
|
|
42
|
+
def validate_services(service_manager)
|
|
43
|
+
def_manager = service_manager.definition_manager
|
|
44
|
+
|
|
45
|
+
def_manager.services.each do |service_name, service_def|
|
|
46
|
+
begin
|
|
47
|
+
service_manager.service(service_name)
|
|
48
|
+
rescue => e
|
|
49
|
+
raise ConfigurationError.new(e.message)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
28
53
|
end
|
|
29
|
-
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require 'longleaf/services/application_config_deserializer'
|
|
2
|
+
require 'longleaf/models/file_record'
|
|
3
|
+
require 'longleaf/events/event_status_tracking'
|
|
4
|
+
require 'longleaf/errors'
|
|
5
|
+
|
|
6
|
+
module Longleaf
|
|
7
|
+
# Command for validating file metadata longleaf
|
|
8
|
+
class ValidateMetadataCommand
|
|
9
|
+
include Longleaf::EventStatusTracking
|
|
10
|
+
|
|
11
|
+
def initialize(app_manager)
|
|
12
|
+
@app_manager = app_manager
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Execute the validation command
|
|
16
|
+
# @param file_selector [FileSelector] selector for files to register
|
|
17
|
+
# @return [Integer] status code
|
|
18
|
+
def execute(file_selector:)
|
|
19
|
+
start_time = Time.now
|
|
20
|
+
logger.info('Performing validate metadata command')
|
|
21
|
+
begin
|
|
22
|
+
# Perform metadata validation on each of the file paths provided
|
|
23
|
+
loop do
|
|
24
|
+
f_path = file_selector.next_path
|
|
25
|
+
break if f_path.nil?
|
|
26
|
+
|
|
27
|
+
storage_location = @app_manager.location_manager.get_location_by_path(f_path)
|
|
28
|
+
|
|
29
|
+
begin
|
|
30
|
+
file_rec = FileRecord.new(f_path, storage_location)
|
|
31
|
+
unless file_rec.metadata_present?
|
|
32
|
+
raise MetadataError.new("Cannot validate metadata for #{f_path}, file is not registered.")
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
@app_manager.md_manager.load(file_rec)
|
|
36
|
+
record_success("Metadata for file passed validation: #{f_path}")
|
|
37
|
+
rescue LongleafError => err
|
|
38
|
+
record_failure(err.message)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
rescue RegistrationError, InvalidStoragePathError, StorageLocationUnavailableError => err
|
|
42
|
+
record_failure(err.message)
|
|
43
|
+
rescue => err
|
|
44
|
+
record_failure("Encountered error while validating metadata files", error: err)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
logger.info("Completed validate metadata command in #{Time.now - start_time}s")
|
|
48
|
+
return_status
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
data/lib/longleaf/errors.rb
CHANGED
|
@@ -1,15 +1,34 @@
|
|
|
1
1
|
module Longleaf
|
|
2
|
+
# General Longleaf error
|
|
2
3
|
class LongleafError < StandardError; end
|
|
3
|
-
|
|
4
|
+
|
|
5
|
+
# Invalid application configuration error
|
|
4
6
|
class ConfigurationError < LongleafError; end
|
|
5
|
-
|
|
7
|
+
|
|
8
|
+
# Invalid storage path error
|
|
6
9
|
class InvalidStoragePathError < LongleafError; end
|
|
7
|
-
|
|
10
|
+
|
|
11
|
+
# Metadata does not meet requirements error
|
|
8
12
|
class MetadataError < LongleafError; end
|
|
9
|
-
|
|
13
|
+
|
|
14
|
+
# Unavailable storage location error
|
|
10
15
|
class StorageLocationUnavailableError < LongleafError; end
|
|
11
|
-
|
|
16
|
+
|
|
17
|
+
# Error related to executing a preservation event
|
|
12
18
|
class EventError < LongleafError; end
|
|
13
|
-
|
|
19
|
+
|
|
20
|
+
# Error with the registration state of a file or while attempting to perform a registration event
|
|
14
21
|
class RegistrationError < EventError; end
|
|
15
|
-
|
|
22
|
+
|
|
23
|
+
# Error while attempting to perform a deregistration event
|
|
24
|
+
class DeregistrationError < EventError; end
|
|
25
|
+
|
|
26
|
+
# Error while performing a preservation service
|
|
27
|
+
class PreservationServiceError < LongleafError; end
|
|
28
|
+
|
|
29
|
+
# Fixity check failure error
|
|
30
|
+
class ChecksumMismatchError < PreservationServiceError; end
|
|
31
|
+
|
|
32
|
+
# Error indicating an unknown or invalid digest algorithm was specified
|
|
33
|
+
class InvalidDigestAlgorithmError < LongleafError; end
|
|
34
|
+
end
|