longleaf 0.2.0.pre.1 → 0.3.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/.circleci/config.yml +84 -0
- data/.gitignore +4 -2
- data/.rubocop.yml +42 -2
- data/.rubocop_todo.yml +390 -311
- data/.yardopts +1 -0
- data/Gemfile +16 -1
- data/README.md +67 -13
- 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 +47 -15
- data/lib/longleaf/candidates/registered_file_selector.rb +67 -0
- data/lib/longleaf/candidates/service_candidate_filesystem_iterator.rb +29 -35
- data/lib/longleaf/candidates/service_candidate_index_iterator.rb +84 -0
- data/lib/longleaf/candidates/service_candidate_locator.rb +9 -4
- data/lib/longleaf/cli.rb +162 -80
- data/lib/longleaf/commands/deregister_command.rb +12 -11
- data/lib/longleaf/commands/preserve_command.rb +13 -8
- data/lib/longleaf/commands/register_command.rb +9 -6
- data/lib/longleaf/commands/reindex_command.rb +92 -0
- data/lib/longleaf/commands/validate_config_command.rb +27 -6
- data/lib/longleaf/commands/validate_metadata_command.rb +11 -9
- data/lib/longleaf/errors.rb +12 -12
- data/lib/longleaf/events/deregister_event.rb +13 -15
- data/lib/longleaf/events/event_status_tracking.rb +7 -7
- data/lib/longleaf/events/preserve_event.rb +24 -14
- data/lib/longleaf/events/register_event.rb +21 -35
- data/lib/longleaf/helpers/digest_helper.rb +4 -4
- data/lib/longleaf/helpers/service_date_helper.rb +5 -6
- data/lib/longleaf/indexing/index_manager.rb +101 -0
- data/lib/longleaf/indexing/sequel_index_driver.rb +324 -0
- data/lib/longleaf/logging.rb +4 -4
- data/lib/longleaf/logging/redirecting_logger.rb +20 -20
- data/lib/longleaf/models/app_fields.rb +2 -1
- data/lib/longleaf/models/file_record.rb +10 -6
- data/lib/longleaf/models/md_fields.rb +1 -1
- data/lib/longleaf/models/metadata_record.rb +22 -12
- data/lib/longleaf/models/service_definition.rb +3 -3
- data/lib/longleaf/models/service_fields.rb +1 -1
- data/lib/longleaf/models/service_record.rb +6 -5
- data/lib/longleaf/models/storage_location.rb +26 -7
- data/lib/longleaf/models/system_config_fields.rb +9 -0
- data/lib/longleaf/preservation_services/file_check_service.rb +58 -0
- data/lib/longleaf/preservation_services/fixity_check_service.rb +16 -14
- data/lib/longleaf/preservation_services/rsync_replication_service.rb +32 -31
- data/lib/longleaf/services/application_config_deserializer.rb +55 -18
- data/lib/longleaf/services/application_config_manager.rb +16 -4
- data/lib/longleaf/services/application_config_validator.rb +1 -2
- data/lib/longleaf/services/configuration_validator.rb +6 -4
- data/lib/longleaf/services/metadata_deserializer.rb +40 -38
- data/lib/longleaf/services/metadata_persistence_manager.rb +46 -0
- data/lib/longleaf/services/metadata_serializer.rb +23 -22
- data/lib/longleaf/services/service_class_cache.rb +15 -15
- data/lib/longleaf/services/service_definition_manager.rb +5 -6
- data/lib/longleaf/services/service_definition_validator.rb +5 -6
- data/lib/longleaf/services/service_manager.rb +37 -17
- data/lib/longleaf/services/service_mapping_manager.rb +9 -9
- data/lib/longleaf/services/service_mapping_validator.rb +9 -10
- data/lib/longleaf/services/storage_location_manager.rb +22 -8
- data/lib/longleaf/services/storage_location_validator.rb +11 -8
- data/lib/longleaf/services/storage_path_validator.rb +1 -1
- data/lib/longleaf/specs/config_builder.rb +30 -17
- data/lib/longleaf/specs/custom_matchers.rb +1 -1
- data/lib/longleaf/specs/file_helpers.rb +15 -14
- data/lib/longleaf/specs/metadata_builder.rb +91 -0
- data/lib/longleaf/specs/system_config_builder.rb +27 -0
- data/lib/longleaf/version.rb +1 -1
- data/longleaf.gemspec +17 -7
- data/mkdocs.yml +20 -0
- metadata +233 -22
|
@@ -8,7 +8,7 @@ module Longleaf
|
|
|
8
8
|
# Command for registering files with longleaf
|
|
9
9
|
class RegisterCommand
|
|
10
10
|
include Longleaf::EventStatusTracking
|
|
11
|
-
|
|
11
|
+
|
|
12
12
|
def initialize(app_manager)
|
|
13
13
|
@app_manager = app_manager
|
|
14
14
|
end
|
|
@@ -19,16 +19,18 @@ module Longleaf
|
|
|
19
19
|
# @param checksums [Array] array of checksums
|
|
20
20
|
# @return [Integer] status code
|
|
21
21
|
def execute(file_selector:, force: false, checksums: nil)
|
|
22
|
+
start_time = Time.now
|
|
23
|
+
logger.info('Performing register command')
|
|
22
24
|
begin
|
|
23
25
|
# Perform register events on each of the file paths provided
|
|
24
26
|
loop do
|
|
25
27
|
f_path = file_selector.next_path
|
|
26
28
|
break if f_path.nil?
|
|
27
|
-
|
|
29
|
+
|
|
28
30
|
storage_location = @app_manager.location_manager.get_location_by_path(f_path)
|
|
29
|
-
|
|
31
|
+
|
|
30
32
|
file_rec = FileRecord.new(f_path, storage_location)
|
|
31
|
-
|
|
33
|
+
|
|
32
34
|
register_event = RegisterEvent.new(file_rec: file_rec, force: force, app_manager: @app_manager,
|
|
33
35
|
checksums: checksums)
|
|
34
36
|
track_status(register_event.perform)
|
|
@@ -38,8 +40,9 @@ module Longleaf
|
|
|
38
40
|
rescue => err
|
|
39
41
|
record_failure(EventNames::REGISTER, error: err)
|
|
40
42
|
end
|
|
41
|
-
|
|
43
|
+
|
|
44
|
+
logger.info("Completed register command in #{Time.now - start_time}s")
|
|
42
45
|
return_status
|
|
43
46
|
end
|
|
44
47
|
end
|
|
45
|
-
end
|
|
48
|
+
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
|
|
@@ -5,29 +5,50 @@ module Longleaf
|
|
|
5
5
|
# Command for validating an application configuration file
|
|
6
6
|
class ValidateConfigCommand
|
|
7
7
|
include Longleaf::EventStatusTracking
|
|
8
|
-
|
|
8
|
+
|
|
9
9
|
def initialize(config_path)
|
|
10
10
|
@config_path = config_path
|
|
11
11
|
end
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
# Execute the validate command on the specified configuration yml file
|
|
14
14
|
def execute
|
|
15
|
+
start_time = Time.now
|
|
16
|
+
logger.info('Performing validate configuration command')
|
|
15
17
|
begin
|
|
16
18
|
app_config_manager = Longleaf::ApplicationConfigDeserializer.deserialize(@config_path)
|
|
17
|
-
|
|
19
|
+
|
|
18
20
|
location_manager = app_config_manager.location_manager
|
|
19
21
|
location_manager.locations.each do |name, location|
|
|
20
22
|
location.available?
|
|
21
23
|
end
|
|
22
|
-
|
|
24
|
+
|
|
25
|
+
validate_services(app_config_manager.service_manager)
|
|
26
|
+
|
|
23
27
|
record_success("Application configuration passed validation: #{@config_path}")
|
|
24
28
|
rescue Longleaf::ConfigurationError, Longleaf::StorageLocationUnavailableError => err
|
|
25
29
|
record_failure("Application configuration invalid due to the following issue:\n#{err.message}")
|
|
26
30
|
rescue => err
|
|
27
31
|
record_failure("Failed to validate application configuration", error: err)
|
|
28
32
|
end
|
|
29
|
-
|
|
33
|
+
|
|
34
|
+
logger.info("Completed validate configuration command in #{Time.now - start_time}s")
|
|
30
35
|
return_status
|
|
31
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
|
|
32
53
|
end
|
|
33
|
-
end
|
|
54
|
+
end
|
|
@@ -7,7 +7,7 @@ module Longleaf
|
|
|
7
7
|
# Command for validating file metadata longleaf
|
|
8
8
|
class ValidateMetadataCommand
|
|
9
9
|
include Longleaf::EventStatusTracking
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
def initialize(app_manager)
|
|
12
12
|
@app_manager = app_manager
|
|
13
13
|
end
|
|
@@ -16,34 +16,36 @@ module Longleaf
|
|
|
16
16
|
# @param file_selector [FileSelector] selector for files to register
|
|
17
17
|
# @return [Integer] status code
|
|
18
18
|
def execute(file_selector:)
|
|
19
|
+
start_time = Time.now
|
|
20
|
+
logger.info('Performing validate metadata command')
|
|
19
21
|
begin
|
|
20
22
|
# Perform metadata validation on each of the file paths provided
|
|
21
23
|
loop do
|
|
22
24
|
f_path = file_selector.next_path
|
|
23
25
|
break if f_path.nil?
|
|
24
|
-
|
|
26
|
+
|
|
25
27
|
storage_location = @app_manager.location_manager.get_location_by_path(f_path)
|
|
26
|
-
|
|
28
|
+
|
|
27
29
|
begin
|
|
28
30
|
file_rec = FileRecord.new(f_path, storage_location)
|
|
29
31
|
unless file_rec.metadata_present?
|
|
30
32
|
raise MetadataError.new("Cannot validate metadata for #{f_path}, file is not registered.")
|
|
31
33
|
end
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
digest_algs: storage_location.metadata_digests)
|
|
34
|
+
|
|
35
|
+
@app_manager.md_manager.load(file_rec)
|
|
35
36
|
record_success("Metadata for file passed validation: #{f_path}")
|
|
36
37
|
rescue LongleafError => err
|
|
37
38
|
record_failure(err.message)
|
|
38
39
|
end
|
|
39
40
|
end
|
|
40
|
-
rescue InvalidStoragePathError, StorageLocationUnavailableError => err
|
|
41
|
+
rescue RegistrationError, InvalidStoragePathError, StorageLocationUnavailableError => err
|
|
41
42
|
record_failure(err.message)
|
|
42
43
|
rescue => err
|
|
43
44
|
record_failure("Encountered error while validating metadata files", error: err)
|
|
44
45
|
end
|
|
45
|
-
|
|
46
|
+
|
|
47
|
+
logger.info("Completed validate metadata command in #{Time.now - start_time}s")
|
|
46
48
|
return_status
|
|
47
49
|
end
|
|
48
50
|
end
|
|
49
|
-
end
|
|
51
|
+
end
|
data/lib/longleaf/errors.rb
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
1
|
module Longleaf
|
|
2
2
|
# General Longleaf error
|
|
3
3
|
class LongleafError < StandardError; end
|
|
4
|
-
|
|
4
|
+
|
|
5
5
|
# Invalid application configuration error
|
|
6
6
|
class ConfigurationError < LongleafError; end
|
|
7
|
-
|
|
7
|
+
|
|
8
8
|
# Invalid storage path error
|
|
9
9
|
class InvalidStoragePathError < LongleafError; end
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
# Metadata does not meet requirements error
|
|
12
12
|
class MetadataError < LongleafError; end
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
# Unavailable storage location error
|
|
15
15
|
class StorageLocationUnavailableError < LongleafError; end
|
|
16
|
-
|
|
16
|
+
|
|
17
17
|
# Error related to executing a preservation event
|
|
18
18
|
class EventError < LongleafError; end
|
|
19
|
-
|
|
20
|
-
# Error while attempting to perform a registration event
|
|
19
|
+
|
|
20
|
+
# Error with the registration state of a file or while attempting to perform a registration event
|
|
21
21
|
class RegistrationError < EventError; end
|
|
22
|
-
|
|
22
|
+
|
|
23
23
|
# Error while attempting to perform a deregistration event
|
|
24
24
|
class DeregistrationError < EventError; end
|
|
25
|
-
|
|
25
|
+
|
|
26
26
|
# Error while performing a preservation service
|
|
27
27
|
class PreservationServiceError < LongleafError; end
|
|
28
|
-
|
|
28
|
+
|
|
29
29
|
# Fixity check failure error
|
|
30
30
|
class ChecksumMismatchError < PreservationServiceError; end
|
|
31
|
-
|
|
31
|
+
|
|
32
32
|
# Error indicating an unknown or invalid digest algorithm was specified
|
|
33
33
|
class InvalidDigestAlgorithmError < LongleafError; end
|
|
34
|
-
end
|
|
34
|
+
end
|
|
@@ -7,7 +7,7 @@ module Longleaf
|
|
|
7
7
|
# Event to deregister a file from longleaf
|
|
8
8
|
class DeregisterEvent
|
|
9
9
|
include Longleaf::EventStatusTracking
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
# @param file_rec [FileRecord] file record
|
|
12
12
|
# @param app_manager [ApplicationConfigManager] the application configuration
|
|
13
13
|
# @param force [boolean] if true, then already deregistered files will be deregistered again
|
|
@@ -18,38 +18,36 @@ module Longleaf
|
|
|
18
18
|
raise ArgumentError.new('Must provide an ApplicationConfigManager') if app_manager.nil?
|
|
19
19
|
raise ArgumentError.new('Parameter app_manager must be an ApplicationConfigManager') \
|
|
20
20
|
unless app_manager.is_a?(ApplicationConfigManager)
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
@app_manager = app_manager
|
|
23
23
|
@file_rec = file_rec
|
|
24
24
|
@force = force
|
|
25
25
|
end
|
|
26
|
-
|
|
26
|
+
|
|
27
27
|
# Perform a deregistration event on the given file record
|
|
28
|
-
# @raise DeregistrationError if a file cannot be deregistered
|
|
28
|
+
# @raise DeregistrationError if a file cannot be deregistered
|
|
29
29
|
def perform
|
|
30
30
|
begin
|
|
31
31
|
md_rec = @file_rec.metadata_record
|
|
32
|
-
|
|
32
|
+
|
|
33
33
|
# Only need to deregister a deregistered file if the force flag is provided
|
|
34
34
|
if md_rec.deregistered? && !@force
|
|
35
35
|
raise DeregistrationError.new("Unable to deregister '#{@file_rec.path}', it is already deregistered.")
|
|
36
36
|
end
|
|
37
|
-
|
|
38
|
-
md_rec.deregistered = Time.now.utc.iso8601
|
|
39
|
-
|
|
40
|
-
# persist the metadata
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
digest_algs: @file_rec.storage_location.metadata_digests)
|
|
44
|
-
|
|
37
|
+
|
|
38
|
+
md_rec.deregistered = Time.now.utc.iso8601(3)
|
|
39
|
+
|
|
40
|
+
# persist the metadata
|
|
41
|
+
@app_manager.md_manager.persist(@file_rec)
|
|
42
|
+
|
|
45
43
|
record_success(EventNames::DEREGISTER, @file_rec.path)
|
|
46
44
|
rescue DeregistrationError => err
|
|
47
45
|
record_failure(EventNames::DEREGISTER, @file_rec.path, err.message)
|
|
48
46
|
rescue InvalidStoragePathError => err
|
|
49
47
|
record_failure(EventNames::DEREGISTER, @file_rec.path, err.message)
|
|
50
48
|
end
|
|
51
|
-
|
|
49
|
+
|
|
52
50
|
return_status
|
|
53
51
|
end
|
|
54
52
|
end
|
|
55
|
-
end
|
|
53
|
+
end
|
|
@@ -4,14 +4,14 @@ module Longleaf
|
|
|
4
4
|
# Helper methods for tracking and recording the overall outcome of a preservation event.
|
|
5
5
|
module EventStatusTracking
|
|
6
6
|
include Longleaf::Logging
|
|
7
|
-
|
|
7
|
+
|
|
8
8
|
# Record a successful operation to the output and the overall status of this event.
|
|
9
9
|
# @param args [Array] arguments to pass to logger
|
|
10
10
|
def record_success(*args)
|
|
11
11
|
logger.success(*args)
|
|
12
12
|
track_success
|
|
13
13
|
end
|
|
14
|
-
|
|
14
|
+
|
|
15
15
|
# Update the status of this action with a success outcome.
|
|
16
16
|
def track_success
|
|
17
17
|
if @return_status.nil? || @return_status == 0
|
|
@@ -20,14 +20,14 @@ module Longleaf
|
|
|
20
20
|
@return_status = 2
|
|
21
21
|
end
|
|
22
22
|
end
|
|
23
|
-
|
|
23
|
+
|
|
24
24
|
# Record a failed operation to the output and the overall status of this event.
|
|
25
25
|
# @param args [Array] arguments to pass to logger
|
|
26
26
|
def record_failure(*args)
|
|
27
27
|
logger.failure(*args)
|
|
28
28
|
track_failure
|
|
29
29
|
end
|
|
30
|
-
|
|
30
|
+
|
|
31
31
|
# Update the status of this action with a failure outcome.
|
|
32
32
|
def track_failure
|
|
33
33
|
if @return_status.nil? || @return_status == 1
|
|
@@ -36,7 +36,7 @@ module Longleaf
|
|
|
36
36
|
@return_status = 2
|
|
37
37
|
end
|
|
38
38
|
end
|
|
39
|
-
|
|
39
|
+
|
|
40
40
|
# Update the status of this action with the provided outcome status number.
|
|
41
41
|
# @param status [Integer] outcome status
|
|
42
42
|
def track_status(status)
|
|
@@ -48,7 +48,7 @@ module Longleaf
|
|
|
48
48
|
track_failure
|
|
49
49
|
end
|
|
50
50
|
end
|
|
51
|
-
|
|
51
|
+
|
|
52
52
|
# @return [Integer] the return status for this event, where 0 indicates success,
|
|
53
53
|
# 1 indicates failure, and 2 indicates partial failure
|
|
54
54
|
def return_status
|
|
@@ -56,4 +56,4 @@ module Longleaf
|
|
|
56
56
|
@return_status
|
|
57
57
|
end
|
|
58
58
|
end
|
|
59
|
-
end
|
|
59
|
+
end
|
|
@@ -8,30 +8,37 @@ module Longleaf
|
|
|
8
8
|
class PreserveEvent
|
|
9
9
|
include Longleaf::Logging
|
|
10
10
|
include Longleaf::EventStatusTracking
|
|
11
|
-
|
|
11
|
+
|
|
12
12
|
# @param file_rec [FileRecord] file record
|
|
13
13
|
# @param app_manager [ApplicationConfigManager] the application configuration
|
|
14
14
|
# @param force [boolean] if true, then services run regardless of whether they are flagged as needed
|
|
15
15
|
def initialize(file_rec:, app_manager:, force: false)
|
|
16
16
|
raise ArgumentError.new('Must provide a file_rec parameter') if file_rec.nil?
|
|
17
17
|
raise ArgumentError.new('Must provide an ApplicationConfigManager') if app_manager.nil?
|
|
18
|
-
|
|
18
|
+
|
|
19
19
|
@app_manager = app_manager
|
|
20
20
|
@file_rec = file_rec
|
|
21
21
|
@force = force
|
|
22
22
|
end
|
|
23
|
-
|
|
23
|
+
|
|
24
24
|
# Perform a preserve event on the given file, updating its metadata record if any services were executed.
|
|
25
25
|
def perform
|
|
26
26
|
storage_loc = @file_rec.storage_location
|
|
27
27
|
service_manager = @app_manager.service_manager
|
|
28
28
|
md_rec = @file_rec.metadata_record
|
|
29
29
|
f_path = @file_rec.path
|
|
30
|
-
|
|
30
|
+
|
|
31
31
|
logger.info("Performing preserve event on #{@file_rec.path}")
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
|
|
33
|
+
needs_persist = false
|
|
34
34
|
begin
|
|
35
|
+
if !File.exist?(f_path)
|
|
36
|
+
# Need to persist metadata to avoid repeating processing of this file too soon.
|
|
37
|
+
needs_persist = true
|
|
38
|
+
record_failure(EventNames::PRESERVE, f_path, "File is registered but missing.")
|
|
39
|
+
return return_status
|
|
40
|
+
end
|
|
41
|
+
|
|
35
42
|
# get the list of services applicable to this location and event
|
|
36
43
|
service_manager.list_services(location: storage_loc.name, event: EventNames::PRESERVE).each do |service_name|
|
|
37
44
|
# Skip over this service if it does not need to be run, unless force flag active
|
|
@@ -39,32 +46,35 @@ module Longleaf
|
|
|
39
46
|
logger.debug("Service #{service_name} not needed for file '#{@file_rec.path}', skipping")
|
|
40
47
|
next
|
|
41
48
|
end
|
|
42
|
-
|
|
49
|
+
|
|
43
50
|
begin
|
|
44
51
|
logger.info("Performing preserve service #{service_name} for #{@file_rec.path}")
|
|
52
|
+
needs_persist = true
|
|
45
53
|
# execute the service
|
|
46
54
|
service_manager.perform_service(service_name, @file_rec, EventNames::PRESERVE)
|
|
47
|
-
|
|
55
|
+
|
|
48
56
|
# record the outcome
|
|
49
57
|
@file_rec.metadata_record.update_service_as_performed(service_name)
|
|
50
|
-
service_performed = true
|
|
51
58
|
record_success(EventNames::PRESERVE, f_path, nil, service_name)
|
|
52
59
|
rescue PreservationServiceError => e
|
|
60
|
+
@file_rec.metadata_record.update_service_as_failed(service_name)
|
|
53
61
|
record_failure(EventNames::PRESERVE, f_path, e.message, service_name)
|
|
62
|
+
rescue StorageLocationUnavailableError => e
|
|
63
|
+
raise e
|
|
54
64
|
rescue StandardError => e
|
|
65
|
+
@file_rec.metadata_record.update_service_as_failed(service_name)
|
|
55
66
|
record_failure(EventNames::PRESERVE, f_path, nil, service_name, error: e)
|
|
56
67
|
return return_status
|
|
57
68
|
end
|
|
58
69
|
end
|
|
59
70
|
ensure
|
|
60
71
|
# persist the metadata out to file if any services were executed
|
|
61
|
-
if
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
digest_algs: storage_loc.metadata_digests)
|
|
72
|
+
if needs_persist
|
|
73
|
+
# persist the metadata
|
|
74
|
+
@app_manager.md_manager.persist(@file_rec)
|
|
65
75
|
end
|
|
66
76
|
end
|
|
67
|
-
|
|
77
|
+
|
|
68
78
|
return_status
|
|
69
79
|
end
|
|
70
80
|
end
|