longleaf 0.2.0.pre.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (165) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +84 -0
  3. data/.gitignore +4 -2
  4. data/.rubocop.yml +42 -2
  5. data/.rubocop_todo.yml +390 -311
  6. data/.yardopts +1 -0
  7. data/Gemfile +16 -1
  8. data/README.md +67 -13
  9. data/Rakefile +6 -0
  10. data/bin/setup +16 -1
  11. data/docs/aboutlongleaf.md +28 -0
  12. data/docs/extra.css +32 -0
  13. data/docs/img/change-file.png +0 -0
  14. data/docs/img/ll-example-preserved.png +0 -0
  15. data/docs/index.md +19 -0
  16. data/docs/install.md +66 -0
  17. data/docs/ll-example/config-example-relative.yml +33 -0
  18. data/docs/ll-example/files-dir/LLexample-PDF.pdf +0 -0
  19. data/docs/ll-example/files-dir/LLexample-TOCHANGE.txt +15 -0
  20. data/docs/ll-example/files-dir/LLexample-tokeep.txt +10 -0
  21. data/docs/ll-example/metadata-dir/.gitkeep +0 -0
  22. data/docs/ll-example/replica-files/.gitkeep +0 -0
  23. data/docs/ll-example/replica-metadata/.gitkeep +0 -0
  24. data/docs/quickstart.md +270 -0
  25. data/docs/rdocs/Longleaf.html +135 -0
  26. data/docs/rdocs/Longleaf/AppFields.html +178 -0
  27. data/docs/rdocs/Longleaf/ApplicationConfigDeserializer.html +631 -0
  28. data/docs/rdocs/Longleaf/ApplicationConfigManager.html +610 -0
  29. data/docs/rdocs/Longleaf/ApplicationConfigValidator.html +238 -0
  30. data/docs/rdocs/Longleaf/CLI.html +909 -0
  31. data/docs/rdocs/Longleaf/ChecksumMismatchError.html +151 -0
  32. data/docs/rdocs/Longleaf/ConfigBuilder.html +1339 -0
  33. data/docs/rdocs/Longleaf/ConfigurationError.html +143 -0
  34. data/docs/rdocs/Longleaf/ConfigurationValidator.html +227 -0
  35. data/docs/rdocs/Longleaf/DeregisterCommand.html +420 -0
  36. data/docs/rdocs/Longleaf/DeregisterEvent.html +453 -0
  37. data/docs/rdocs/Longleaf/DeregistrationError.html +151 -0
  38. data/docs/rdocs/Longleaf/DigestHelper.html +419 -0
  39. data/docs/rdocs/Longleaf/EventError.html +147 -0
  40. data/docs/rdocs/Longleaf/EventNames.html +163 -0
  41. data/docs/rdocs/Longleaf/EventStatusTracking.html +656 -0
  42. data/docs/rdocs/Longleaf/FileCheckService.html +540 -0
  43. data/docs/rdocs/Longleaf/FileHelpers.html +520 -0
  44. data/docs/rdocs/Longleaf/FileRecord.html +716 -0
  45. data/docs/rdocs/Longleaf/FileSelector.html +901 -0
  46. data/docs/rdocs/Longleaf/FixityCheckService.html +691 -0
  47. data/docs/rdocs/Longleaf/IndexManager.html +1155 -0
  48. data/docs/rdocs/Longleaf/InvalidDigestAlgorithmError.html +143 -0
  49. data/docs/rdocs/Longleaf/InvalidStoragePathError.html +143 -0
  50. data/docs/rdocs/Longleaf/Logging.html +405 -0
  51. data/docs/rdocs/Longleaf/Logging/RedirectingLogger.html +1213 -0
  52. data/docs/rdocs/Longleaf/LongleafError.html +139 -0
  53. data/docs/rdocs/Longleaf/MDFields.html +193 -0
  54. data/docs/rdocs/Longleaf/MetadataBuilder.html +787 -0
  55. data/docs/rdocs/Longleaf/MetadataDeserializer.html +537 -0
  56. data/docs/rdocs/Longleaf/MetadataError.html +143 -0
  57. data/docs/rdocs/Longleaf/MetadataPersistenceManager.html +539 -0
  58. data/docs/rdocs/Longleaf/MetadataRecord.html +1411 -0
  59. data/docs/rdocs/Longleaf/MetadataSerializer.html +786 -0
  60. data/docs/rdocs/Longleaf/PreservationServiceError.html +147 -0
  61. data/docs/rdocs/Longleaf/PreserveCommand.html +410 -0
  62. data/docs/rdocs/Longleaf/PreserveEvent.html +491 -0
  63. data/docs/rdocs/Longleaf/RegisterCommand.html +428 -0
  64. data/docs/rdocs/Longleaf/RegisterEvent.html +628 -0
  65. data/docs/rdocs/Longleaf/RegisteredFileSelector.html +446 -0
  66. data/docs/rdocs/Longleaf/RegistrationError.html +151 -0
  67. data/docs/rdocs/Longleaf/ReindexCommand.html +576 -0
  68. data/docs/rdocs/Longleaf/RsyncReplicationService.html +1180 -0
  69. data/docs/rdocs/Longleaf/SequelIndexDriver.html +1978 -0
  70. data/docs/rdocs/Longleaf/ServiceCandidateFilesystemIterator.html +572 -0
  71. data/docs/rdocs/Longleaf/ServiceCandidateIndexIterator.html +532 -0
  72. data/docs/rdocs/Longleaf/ServiceCandidateLocator.html +333 -0
  73. data/docs/rdocs/Longleaf/ServiceClassCache.html +725 -0
  74. data/docs/rdocs/Longleaf/ServiceDateHelper.html +425 -0
  75. data/docs/rdocs/Longleaf/ServiceDefinition.html +683 -0
  76. data/docs/rdocs/Longleaf/ServiceDefinitionManager.html +371 -0
  77. data/docs/rdocs/Longleaf/ServiceDefinitionValidator.html +269 -0
  78. data/docs/rdocs/Longleaf/ServiceFields.html +173 -0
  79. data/docs/rdocs/Longleaf/ServiceManager.html +1229 -0
  80. data/docs/rdocs/Longleaf/ServiceMappingManager.html +410 -0
  81. data/docs/rdocs/Longleaf/ServiceMappingValidator.html +347 -0
  82. data/docs/rdocs/Longleaf/ServiceRecord.html +821 -0
  83. data/docs/rdocs/Longleaf/StorageLocation.html +985 -0
  84. data/docs/rdocs/Longleaf/StorageLocationManager.html +729 -0
  85. data/docs/rdocs/Longleaf/StorageLocationUnavailableError.html +143 -0
  86. data/docs/rdocs/Longleaf/StorageLocationValidator.html +373 -0
  87. data/docs/rdocs/Longleaf/StoragePathValidator.html +253 -0
  88. data/docs/rdocs/Longleaf/SystemConfigBuilder.html +441 -0
  89. data/docs/rdocs/Longleaf/SystemConfigFields.html +163 -0
  90. data/docs/rdocs/Longleaf/ValidateConfigCommand.html +451 -0
  91. data/docs/rdocs/Longleaf/ValidateMetadataCommand.html +408 -0
  92. data/docs/rdocs/_index.html +660 -0
  93. data/docs/rdocs/class_list.html +51 -0
  94. data/docs/rdocs/css/common.css +1 -0
  95. data/docs/rdocs/css/full_list.css +58 -0
  96. data/docs/rdocs/css/style.css +496 -0
  97. data/docs/rdocs/file.README.html +165 -0
  98. data/docs/rdocs/file_list.html +56 -0
  99. data/docs/rdocs/frames.html +17 -0
  100. data/docs/rdocs/index.html +165 -0
  101. data/docs/rdocs/js/app.js +303 -0
  102. data/docs/rdocs/js/full_list.js +216 -0
  103. data/docs/rdocs/js/jquery.js +4 -0
  104. data/docs/rdocs/method_list.html +2051 -0
  105. data/docs/rdocs/top-level-namespace.html +110 -0
  106. data/lib/longleaf/candidates/file_selector.rb +47 -15
  107. data/lib/longleaf/candidates/registered_file_selector.rb +67 -0
  108. data/lib/longleaf/candidates/service_candidate_filesystem_iterator.rb +29 -35
  109. data/lib/longleaf/candidates/service_candidate_index_iterator.rb +84 -0
  110. data/lib/longleaf/candidates/service_candidate_locator.rb +9 -4
  111. data/lib/longleaf/cli.rb +162 -80
  112. data/lib/longleaf/commands/deregister_command.rb +12 -11
  113. data/lib/longleaf/commands/preserve_command.rb +13 -8
  114. data/lib/longleaf/commands/register_command.rb +9 -6
  115. data/lib/longleaf/commands/reindex_command.rb +92 -0
  116. data/lib/longleaf/commands/validate_config_command.rb +27 -6
  117. data/lib/longleaf/commands/validate_metadata_command.rb +11 -9
  118. data/lib/longleaf/errors.rb +12 -12
  119. data/lib/longleaf/events/deregister_event.rb +13 -15
  120. data/lib/longleaf/events/event_status_tracking.rb +7 -7
  121. data/lib/longleaf/events/preserve_event.rb +24 -14
  122. data/lib/longleaf/events/register_event.rb +21 -35
  123. data/lib/longleaf/helpers/digest_helper.rb +4 -4
  124. data/lib/longleaf/helpers/service_date_helper.rb +5 -6
  125. data/lib/longleaf/indexing/index_manager.rb +101 -0
  126. data/lib/longleaf/indexing/sequel_index_driver.rb +324 -0
  127. data/lib/longleaf/logging.rb +4 -4
  128. data/lib/longleaf/logging/redirecting_logger.rb +20 -20
  129. data/lib/longleaf/models/app_fields.rb +2 -1
  130. data/lib/longleaf/models/file_record.rb +10 -6
  131. data/lib/longleaf/models/md_fields.rb +1 -1
  132. data/lib/longleaf/models/metadata_record.rb +22 -12
  133. data/lib/longleaf/models/service_definition.rb +3 -3
  134. data/lib/longleaf/models/service_fields.rb +1 -1
  135. data/lib/longleaf/models/service_record.rb +6 -5
  136. data/lib/longleaf/models/storage_location.rb +26 -7
  137. data/lib/longleaf/models/system_config_fields.rb +9 -0
  138. data/lib/longleaf/preservation_services/file_check_service.rb +58 -0
  139. data/lib/longleaf/preservation_services/fixity_check_service.rb +16 -14
  140. data/lib/longleaf/preservation_services/rsync_replication_service.rb +32 -31
  141. data/lib/longleaf/services/application_config_deserializer.rb +55 -18
  142. data/lib/longleaf/services/application_config_manager.rb +16 -4
  143. data/lib/longleaf/services/application_config_validator.rb +1 -2
  144. data/lib/longleaf/services/configuration_validator.rb +6 -4
  145. data/lib/longleaf/services/metadata_deserializer.rb +40 -38
  146. data/lib/longleaf/services/metadata_persistence_manager.rb +46 -0
  147. data/lib/longleaf/services/metadata_serializer.rb +23 -22
  148. data/lib/longleaf/services/service_class_cache.rb +15 -15
  149. data/lib/longleaf/services/service_definition_manager.rb +5 -6
  150. data/lib/longleaf/services/service_definition_validator.rb +5 -6
  151. data/lib/longleaf/services/service_manager.rb +37 -17
  152. data/lib/longleaf/services/service_mapping_manager.rb +9 -9
  153. data/lib/longleaf/services/service_mapping_validator.rb +9 -10
  154. data/lib/longleaf/services/storage_location_manager.rb +22 -8
  155. data/lib/longleaf/services/storage_location_validator.rb +11 -8
  156. data/lib/longleaf/services/storage_path_validator.rb +1 -1
  157. data/lib/longleaf/specs/config_builder.rb +30 -17
  158. data/lib/longleaf/specs/custom_matchers.rb +1 -1
  159. data/lib/longleaf/specs/file_helpers.rb +15 -14
  160. data/lib/longleaf/specs/metadata_builder.rb +91 -0
  161. data/lib/longleaf/specs/system_config_builder.rb +27 -0
  162. data/lib/longleaf/version.rb +1 -1
  163. data/longleaf.gemspec +17 -7
  164. data/mkdocs.yml +20 -0
  165. metadata +233 -22
@@ -1,4 +1,5 @@
1
1
  require 'longleaf/candidates/service_candidate_filesystem_iterator'
2
+ require 'longleaf/candidates/service_candidate_index_iterator'
2
3
 
3
4
  module Longleaf
4
5
  # Service which locates files that have services which need to be performed on them.
@@ -6,13 +7,17 @@ module Longleaf
6
7
  def initialize(app_config)
7
8
  @app_config = app_config
8
9
  end
9
-
10
+
10
11
  # Get a iterator of the candidates matching the given FileSelector which need services run.
11
12
  # @param file_selector [FileSelector] selector identifying the files to pull candidates from.
12
13
  # @return an iterator
13
14
  def candidate_iterator(file_selector, event, force = false)
14
- # Get filesystem based implementation
15
- ServiceCandidateFilesystemIterator.new(file_selector, event, @app_config, force)
15
+ if @app_config.index_manager.using_index?
16
+ ServiceCandidateIndexIterator.new(file_selector, event, @app_config, force)
17
+ else
18
+ # Get filesystem based implementation
19
+ ServiceCandidateFilesystemIterator.new(file_selector, event, @app_config, force)
20
+ end
16
21
  end
17
22
  end
18
- end
23
+ end
data/lib/longleaf/cli.rb CHANGED
@@ -2,55 +2,101 @@ require 'thor'
2
2
  require 'yaml'
3
3
  require 'longleaf/logging'
4
4
  require 'longleaf/errors'
5
+ require 'longleaf/version'
5
6
  require 'longleaf/commands/deregister_command'
6
7
  require 'longleaf/commands/validate_config_command'
7
8
  require 'longleaf/commands/validate_metadata_command'
8
9
  require 'longleaf/commands/register_command'
10
+ require 'longleaf/commands/reindex_command'
9
11
  require 'longleaf/commands/preserve_command'
10
12
  require 'longleaf/candidates/file_selector'
13
+ require 'longleaf/candidates/registered_file_selector'
11
14
 
12
15
  module Longleaf
13
16
  # Main commandline interface setup for Longleaf using Thor.
14
17
  class CLI < Thor
15
18
  include Longleaf::Logging
16
-
17
- class_option(:config, :aliases => "-c",
18
- :default => ENV['LONGLEAF_CFG'],
19
- :required => true,
20
- :desc => 'Absolute path to the application configuration used for this command. By default, the value of the environment variable LONGLEAF_CFG is used.')
21
- class_option(:load_path, :aliases => "-I",
22
- :desc => 'Specify comma seperated directories to add to the $LOAD_PATH, which can be used to specify additional paths from which to load preservation services.')
23
- # Logging/output options
24
- class_option(:failure_only,
25
- :type => :boolean,
26
- :default => false,
27
- :desc => 'Only display failure messages to STDOUT.')
28
- class_option(:log_level,
29
- :default => 'WARN',
30
- :desc => 'Level of logging to send to STDERR, following standard ruby Logger levels. This includes: DEBUG, INFO, WARN, ERROR, FATAL, UNKNOWN. Default is WARN.')
31
- class_option(:log_format,
32
- :desc => 'Format to use for log information sent to STDERR. Can contain the following parameters, which must be wrapped in %{}: severity, datetime, progname, msg. Default is "%{severity} [%{datetime}]: %{msg}"')
33
- class_option(:log_datetime,
34
- :desc => 'Format to use for timestamps used in logging to STDERR, following strftime syntax.')
35
-
19
+
20
+ # Register a shared method option in a shared option group
21
+ def self.add_shared_option(name, group, options = {})
22
+ @shared_groups = {} if @shared_groups.nil?
23
+ @shared_groups[group] = {} if @shared_groups[group].nil?
24
+ @shared_groups[group][name] = options
25
+ end
26
+
27
+ # Add all of the shared options in the specified group as method options
28
+ def self.shared_options_group(group_name)
29
+ @shared_groups[group_name].each do |opt_name, opt|
30
+ option opt_name, opt
31
+ end
32
+ end
33
+
34
+ # Config options
35
+ add_shared_option(
36
+ :config, :common, {
37
+ :aliases => "-c",
38
+ :default => ENV['LONGLEAF_CFG'],
39
+ :required => false,
40
+ :desc => 'Path to the application configuration used for this command. By default, the value of the environment variable LONGLEAF_CFG is used. A config path is required for most commands.' })
41
+ add_shared_option(
42
+ :load_path, :common, {
43
+ :aliases => "-I",
44
+ :desc => 'Specify comma seperated directories to add to the $LOAD_PATH, which can be used to specify additional paths from which to load preservation services.' })
45
+
46
+ # Logging options
47
+ add_shared_option(
48
+ :failure_only, :common, {
49
+ :type => :boolean,
50
+ :default => false,
51
+ :desc => 'Only display failure messages to STDOUT.' })
52
+ add_shared_option(
53
+ :log_level, :common, {
54
+ :default => 'WARN',
55
+ :desc => 'Level of logging to send to STDERR, following standard ruby Logger levels. This includes: DEBUG, INFO, WARN, ERROR, FATAL, UNKNOWN.' })
56
+ add_shared_option(
57
+ :log_format, :common, {
58
+ :desc => 'Format to use for log information sent to STDERR. Can contain the following parameters, which must be wrapped in %{}: severity, datetime, progname, msg. Default is "%{severity} [%{datetime}]: %{msg}"' })
59
+ add_shared_option(
60
+ :log_datetime, :common, {
61
+ :desc => 'Format to use for timestamps used in logging to STDERR, following strftime syntax.' })
62
+
63
+ # File selection options
64
+ add_shared_option(
65
+ :file, :file_selection, {
66
+ :aliases => "-f",
67
+ :required => false,
68
+ :desc => 'File or files to perform this operation on. If multiple files are provided, they must be comma separated.' })
69
+ add_shared_option(
70
+ :location, :file_selection, {
71
+ :aliases => "-s",
72
+ :required => false,
73
+ :desc => 'Name or comma separated names of storage locations to perform this operation over.' })
74
+
75
+ # Commands
76
+ map %w[--version] => :__print_version
77
+ desc "--version", "Prints the Longleaf version number."
78
+ def __print_version
79
+ puts "longleaf version #{Longleaf::VERSION}"
80
+ end
81
+
36
82
  desc "register", "Register files with Longleaf"
37
- method_option(:file, :aliases => "-f",
38
- :required => true,
39
- :desc => 'File or files to register. Paths must be absolute. If multiple files are provided, they must be comma separated.')
83
+ shared_options_group(:file_selection)
40
84
  method_option(:force,
41
- :type => :boolean,
85
+ :type => :boolean,
42
86
  :default => false,
43
87
  :desc => 'Force the registration of already registered files.')
44
88
  method_option(:checksums,
45
- :desc => %q{Checksums for the submitted file. Each checksum must be prefaced with an algorithm prefix. Multiple checksums must be comma separated. If multiple files were submitted, they will be provided with the same checksums. For example:
89
+ :desc => %q{Checksums for the submitted file. Each checksum must be prefaced with an algorithm prefix. Multiple checksums must be comma separated. If multiple files were submitted, they will be provided with the same checksums. For example:
46
90
  '--checksums "md5:d8e8fca2dc0f896fd7cb4cb0031ba249,sha1:4e1243bd22c66e76c2ba9eddc1f91394e57f9f83"'})
91
+ shared_options_group(:common)
47
92
  # Register event command
48
93
  def register
94
+ verify_config_provided(options)
49
95
  setup_logger(options)
50
-
51
- config_path = options[:config]
52
- app_config_manager = load_application_config(options[:config])
53
- file_selector = create_file_selector(options[:file], nil, app_config_manager)
96
+
97
+ app_config_manager = load_application_config(options)
98
+
99
+ file_selector = create_file_selector(options, app_config_manager)
54
100
  if options[:checksums]
55
101
  checksums = options[:checksums]
56
102
  # validate checksum list format, must a comma delimited list of prefix:checksums
@@ -62,78 +108,106 @@ module Longleaf
62
108
  exit 1
63
109
  end
64
110
  end
65
-
111
+
66
112
  command = RegisterCommand.new(app_config_manager)
67
113
  exit command.execute(file_selector: file_selector, force: options[:force], checksums: checksums)
68
114
  end
69
-
115
+
70
116
  desc "deregister", "Deregister files with Longleaf"
71
- method_option(:file, :aliases => "-f",
72
- :required => true,
73
- :desc => 'File or files to deregister. Paths must be absolute. If multiple files are provided, they must be comma separated.')
117
+ shared_options_group(:file_selection)
74
118
  method_option(:force,
75
- :type => :boolean,
119
+ :type => :boolean,
76
120
  :default => false,
77
121
  :desc => 'Force the deregistration of already deregistered files.')
122
+ shared_options_group(:common)
78
123
  # Deregister event command
79
124
  def deregister
125
+ verify_config_provided(options)
80
126
  setup_logger(options)
81
-
82
- config_path = options[:config]
83
- app_config_manager = load_application_config(options[:config])
84
- file_selector = create_file_selector(options[:file], nil, app_config_manager)
85
-
127
+
128
+ app_config_manager = load_application_config(options)
129
+ file_selector = create_registered_selector(options, app_config_manager)
130
+
86
131
  command = DeregisterCommand.new(app_config_manager)
87
132
  exit command.execute(file_selector: file_selector, force: options[:force])
88
133
  end
89
-
134
+
90
135
  desc "preserve", "Perform preservation services on files with Longleaf"
91
- method_option(:file, :aliases => "-f",
92
- :required => false,
93
- :desc => 'File or files to preserve. Paths must be absolute. If multiple files are provided, they must be comma separated.')
94
- method_option(:location, :aliases => "-s",
95
- :required => false,
96
- :desc => 'Name or comma separated names of storage locations to preserve.')
136
+ shared_options_group(:file_selection)
97
137
  method_option(:force,
98
- :type => :boolean,
138
+ :type => :boolean,
99
139
  :default => false,
100
140
  :desc => 'Force the execution of preservation services, disregarding scheduling information.')
141
+ shared_options_group(:common)
101
142
  def preserve
143
+ verify_config_provided(options)
102
144
  setup_logger(options)
103
-
145
+
104
146
  extend_load_path(options[:load_path])
105
- app_config_manager = load_application_config(options[:config])
106
- file_selector = create_file_selector(options[:file], options[:location], app_config_manager)
107
-
147
+ app_config_manager = load_application_config(options)
148
+ file_selector = create_registered_selector(options, app_config_manager)
149
+
108
150
  command = PreserveCommand.new(app_config_manager)
109
151
  exit command.execute(file_selector: file_selector, force: options[:force])
110
152
  end
111
-
153
+
112
154
  desc "validate_config", "Validate an application configuration file, provided using --config."
155
+ shared_options_group(:common)
113
156
  # Application configuration validation command
114
157
  def validate_config
158
+ verify_config_provided(options)
115
159
  setup_logger(options)
116
-
160
+ extend_load_path(options[:load_path])
161
+
117
162
  exit Longleaf::ValidateConfigCommand.new(options[:config]).execute
118
163
  end
119
-
164
+
120
165
  desc "validate_metadata", "Validate metadata files."
121
- method_option(:file, :aliases => "-f",
122
- :required => false,
123
- :desc => 'File or files of which to validate the metadata. Paths must be absolute. If multiple files are provided, they must be comma separated.')
124
- method_option(:location, :aliases => "-s",
125
- :required => false,
126
- :desc => 'Name or comma separated names of storage locations to validate.')
166
+ shared_options_group(:file_selection)
167
+ shared_options_group(:common)
127
168
  # File metadata validation command
128
169
  def validate_metadata
170
+ verify_config_provided(options)
129
171
  setup_logger(options)
130
-
131
- app_config_manager = load_application_config(options[:config])
132
- file_selector = create_file_selector(options[:file], options[:location], app_config_manager)
133
-
172
+
173
+ app_config_manager = load_application_config(options)
174
+ file_selector = create_registered_selector(options, app_config_manager)
175
+
134
176
  exit Longleaf::ValidateMetadataCommand.new(app_config_manager).execute(file_selector: file_selector)
135
177
  end
136
-
178
+
179
+ desc "setup_index", "Sets up the structure of the metadata index, if one is configured using the system configuration file provided using the --system_config option. Some index types may require additional steps to be taken by an administrator before hand, such as creating users and databases."
180
+ shared_options_group(:common)
181
+ def setup_index
182
+ verify_config_provided(options)
183
+ setup_logger(options)
184
+
185
+ app_config_manager = load_application_config(options)
186
+
187
+ if app_config_manager.index_manager.using_index?
188
+ app_config_manager.index_manager.setup_index
189
+ logger.success("Setup of index complete")
190
+ exit 0
191
+ else
192
+ logger.failure("No index configured, unable to perform setup.")
193
+ exit 1
194
+ end
195
+ end
196
+
197
+ desc "reindex", "Perform a full reindex of file metadata stored within the configured storage locations."
198
+ method_option(:if_stale,
199
+ :type => :boolean,
200
+ :default => false,
201
+ :desc => 'Only perform the reindex if the index is known to be stale, generally after an config file change.')
202
+ shared_options_group(:common)
203
+ def reindex
204
+ verify_config_provided(options)
205
+ setup_logger(options)
206
+ app_config_manager = load_application_config(options)
207
+
208
+ exit Longleaf::ReindexCommand.new(app_config_manager).execute(only_if_stale: options[:if_stale])
209
+ end
210
+
137
211
  no_commands do
138
212
  def setup_logger(options)
139
213
  initialize_logger(options[:failure_only],
@@ -141,34 +215,42 @@ module Longleaf
141
215
  options[:log_format],
142
216
  options[:log_datetime])
143
217
  end
144
-
145
- def load_application_config(config_path)
218
+
219
+ def load_application_config(options)
146
220
  begin
147
- app_manager = ApplicationConfigDeserializer.deserialize(config_path)
221
+ app_manager = ApplicationConfigDeserializer.deserialize(options[:config])
148
222
  rescue ConfigurationError => err
149
223
  logger.failure("Failed to load application configuration due to the following issue:\n#{err.message}")
150
224
  exit 1
151
225
  end
152
226
  end
153
-
154
- def create_file_selector(file_paths, storage_locations, app_config_manager)
155
- file_paths = file_paths&.split(/\s*,\s*/)
156
- storage_locations = storage_locations&.split(/\s*,\s*/)
157
-
227
+
228
+ def verify_config_provided(options)
229
+ if options[:config].nil? || options[:config].empty?
230
+ raise "No value provided for required options '--config'"
231
+ end
232
+ end
233
+
234
+ def create_file_selector(options, app_config_manager, selector_class: FileSelector)
235
+ file_paths = options[:file]&.split(/\s*,\s*/)
236
+ storage_locations = options[:location]&.split(/\s*,\s*/)
237
+
158
238
  begin
159
- FileSelector.new(file_paths: file_paths, storage_locations: storage_locations, app_config: app_config_manager)
239
+ selector_class.new(file_paths: file_paths, storage_locations: storage_locations, app_config: app_config_manager)
160
240
  rescue ArgumentError => e
161
241
  logger.failure(e.message)
162
242
  exit 1
163
243
  end
164
244
  end
165
-
245
+
246
+ def create_registered_selector(options, app_config_manager)
247
+ create_file_selector(options, app_config_manager, selector_class: RegisteredFileSelector)
248
+ end
249
+
166
250
  def extend_load_path(load_paths)
167
251
  load_paths = load_paths&.split(/\s*,\s*/)
168
- if !load_paths.nil?
169
- load_paths.each { |path| $LOAD_PATH.unshift(path) }
170
- end
252
+ load_paths&.each { |path| $LOAD_PATH.unshift(path) }
171
253
  end
172
254
  end
173
255
  end
174
- end
256
+ end
@@ -3,13 +3,12 @@ require 'longleaf/events/deregister_event'
3
3
  require 'longleaf/models/file_record'
4
4
  require 'longleaf/events/event_names'
5
5
  require 'longleaf/events/event_status_tracking'
6
- require 'longleaf/services/metadata_deserializer'
7
6
 
8
7
  module Longleaf
9
8
  # Command for deregistering files with longleaf
10
9
  class DeregisterCommand
11
10
  include Longleaf::EventStatusTracking
12
-
11
+
13
12
  def initialize(app_manager)
14
13
  @app_manager = app_manager
15
14
  end
@@ -19,32 +18,34 @@ module Longleaf
19
18
  # @param force [Boolean] force flag
20
19
  # @return [Integer] status code
21
20
  def execute(file_selector:, force: false)
21
+ start_time = Time.now
22
+ logger.info('Performing deregister command')
22
23
  begin
23
24
  # Perform deregister events on each of the file paths provided
24
25
  loop do
25
26
  f_path = file_selector.next_path
26
27
  break if f_path.nil?
27
-
28
+
28
29
  storage_location = @app_manager.location_manager.get_location_by_path(f_path)
29
-
30
+
30
31
  file_rec = FileRecord.new(f_path, storage_location)
31
32
  unless file_rec.metadata_present?
32
33
  raise DeregistrationError.new("Cannot deregister #{f_path}, file is not registered.")
33
34
  end
34
-
35
- file_rec.metadata_record = MetadataDeserializer.deserialize(file_path: file_rec.metadata_path,
36
- digest_algs: storage_location.metadata_digests)
37
-
35
+
36
+ @app_manager.md_manager.load(file_rec)
37
+
38
38
  event = DeregisterEvent.new(file_rec: file_rec, force: force, app_manager: @app_manager)
39
39
  track_status(event.perform)
40
40
  end
41
- rescue DeregistrationError, InvalidStoragePathError, StorageLocationUnavailableError => err
41
+ rescue RegistrationError, DeregistrationError, InvalidStoragePathError, StorageLocationUnavailableError => err
42
42
  record_failure(EventNames::DEREGISTER, nil, err.message)
43
43
  rescue => err
44
44
  record_failure(EventNames::DEREGISTER, error: err)
45
45
  end
46
-
46
+
47
+ logger.info("Completed deregister command in #{Time.now - start_time}s")
47
48
  return_status
48
49
  end
49
50
  end
50
- end
51
+ end
@@ -12,33 +12,38 @@ module Longleaf
12
12
  class PreserveCommand
13
13
  include Longleaf::Logging
14
14
  include Longleaf::EventStatusTracking
15
-
15
+
16
16
  def initialize(app_manager)
17
17
  @app_manager = app_manager
18
18
  end
19
-
19
+
20
20
  # Execute the preserve command on the given parameters
21
21
  # @param file_selector [FileSelector] selector for files to preserve
22
22
  # @param force [Boolean] force flag
23
23
  # @return [Integer] status code
24
24
  def execute(file_selector:, force: false)
25
+ start_time = Time.now
26
+ logger.info('Performing preserve command')
25
27
  begin
26
28
  # Perform preserve events on each of the file paths provided
27
29
  candidate_locator = ServiceCandidateLocator.new(@app_manager)
28
30
  candidate_it = candidate_locator.candidate_iterator(file_selector, EventNames::PRESERVE, force)
29
31
  candidate_it.each do |file_rec|
30
- f_path = file_rec.path
31
-
32
- logger.debug("Selected candidate #{file_rec.path} for a preserve event")
33
- preserve_event = PreserveEvent.new(file_rec: file_rec, force: force, app_manager: @app_manager)
34
- track_status(preserve_event.perform)
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
35
39
  end
36
40
  rescue LongleafError => e
37
41
  record_failure(EventNames::PRESERVE, nil, e.message)
38
42
  rescue => err
39
43
  record_failure(EventNames::PRESERVE, error: err)
40
44
  end
41
-
45
+
46
+ logger.info("Completed preserve command in #{Time.now - start_time}s")
42
47
  return_status
43
48
  end
44
49
  end