pushmi_pullyu 2.0.7 → 2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: de3e5873be562beedd8ebf27f364d50e2ac993f6331cfd27480614de061a01ab
4
- data.tar.gz: 5e07018702ff3f8660db82ee6e2cb481c650cb10413172eb36d4791e2ec97d3a
3
+ metadata.gz: b4380518d529c79ac7972e3ab29dee3524082df9e66a3f0f1e3eefbb5c08855d
4
+ data.tar.gz: c43b7f5a944ceb4fafa298ebbb7ec47725a8bbff04a8b04ea51874b6bacc2ba6
5
5
  SHA512:
6
- metadata.gz: 4ac86a98c6c63c3d8fe32c7f8238d676fcfd5193b291bf115af9999351d0ac36a23e84e4d75f4443bea2b7f6c73cfcc309117a8d02aba1292d9044014229f5c2
7
- data.tar.gz: a01c230a0ac56783ae878bdc2fd83ac351706623c612d61d270ad005b47d550d28d4fc4ef1a0c2c7f09c1caa17c837157b72e8233f4a64d7c033418546a72fbb
6
+ metadata.gz: 0c7e9b00f0e8a6727393da41e9060dff06a6b8aba0baf9f7ed84bbc89e17e0988e1858a8c0bd925983ccda379e249374af0c738be976ec21708a3cf6be35b20e
7
+ data.tar.gz: 6ed33393e60e371ea74b9eba143ff3ce3f6ddac81954ddf944d68f3d75087f2adc777ac4f8a8db4037c20131201ec0f1325a90d465b3cd06be6fa04a878a728d
data/CHANGELOG.md CHANGED
@@ -6,7 +6,14 @@ PushmiPullyu is a Ruby application, whose primary job is to manage the flow of c
6
6
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
7
7
  and releases in PushmiPullyu adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
8
8
 
9
- ## [Unreleased]
9
+ ## [2.1.1]
10
+ - Increase clarity of log files [#433](https://github.com/ualbertalib/pushmi_pullyu/issues/433)
11
+
12
+ ## [2.1.0]
13
+ - Add more logging information [#433](https://github.com/ualbertalib/pushmi_pullyu/issues/433)
14
+ - Add V3 authentication [#349](https://github.com/ualbertalib/pushmi_pullyu/issues/349)
15
+
16
+ - Add logic to perform authentication against the V3 Auth protocol
10
17
 
11
18
  ## [2.0.7] - 2023-09-13
12
19
 
data/Gemfile CHANGED
@@ -9,8 +9,8 @@ group :development, :test do
9
9
  gem 'pry', '~> 0.10', '>= 0.10.4'
10
10
  gem 'pry-byebug', '~> 3.6'
11
11
  gem 'rake', '~> 13.0'
12
- gem 'rspec', '~> 3.0'
13
- gem 'rubocop', '~> 1.57'
12
+ gem 'rspec', '~> 3.13'
13
+ gem 'rubocop', '~> 1.64'
14
14
  gem 'rubocop-rspec', '~> 2.24'
15
15
  gem 'timecop', '~> 0.9'
16
16
  gem 'vcr', '~> 5.0'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- pushmi_pullyu (2.0.7)
4
+ pushmi_pullyu (2.1.1)
5
5
  activesupport (>= 5, < 8)
6
6
  bagit (~> 0.4)
7
7
  connection_pool (~> 2.2)
@@ -34,7 +34,7 @@ GEM
34
34
  bagit (0.4.6)
35
35
  docopt (~> 0.5.0)
36
36
  validatable (~> 1.6)
37
- base64 (0.1.1)
37
+ base64 (0.2.0)
38
38
  bigdecimal (3.1.4)
39
39
  builder (3.2.4)
40
40
  byebug (11.1.3)
@@ -65,7 +65,7 @@ GEM
65
65
  no_proxy_fix
66
66
  octokit (~> 6.0)
67
67
  terminal-table (>= 1, < 4)
68
- diff-lcs (1.5.0)
68
+ diff-lcs (1.5.1)
69
69
  docopt (0.5.0)
70
70
  domain_name (0.5.20190701)
71
71
  unf (>= 0.0.5, < 1.0.0)
@@ -94,7 +94,7 @@ GEM
94
94
  domain_name (~> 0.5)
95
95
  i18n (1.14.1)
96
96
  concurrent-ruby (~> 1.0)
97
- json (2.6.3)
97
+ json (2.7.2)
98
98
  kramdown (2.4.0)
99
99
  rexml
100
100
  kramdown-parser-gfm (1.1.0)
@@ -123,8 +123,8 @@ GEM
123
123
  open4 (1.3.4)
124
124
  openstack (3.3.21)
125
125
  json
126
- parallel (1.23.0)
127
- parser (3.2.2.4)
126
+ parallel (1.24.0)
127
+ parser (3.3.1.0)
128
128
  ast (~> 2.4.1)
129
129
  racc
130
130
  pry (0.14.2)
@@ -134,7 +134,7 @@ GEM
134
134
  byebug (~> 11.0)
135
135
  pry (>= 0.13, < 0.15)
136
136
  public_suffix (5.0.3)
137
- racc (1.7.1)
137
+ racc (1.8.0)
138
138
  rainbow (3.1.1)
139
139
  rake (13.0.6)
140
140
  rchardet (1.8.0)
@@ -150,45 +150,45 @@ GEM
150
150
  rdf-xsd (3.2.1)
151
151
  rdf (~> 3.2)
152
152
  rexml (~> 3.2)
153
- redis (5.0.7)
154
- redis-client (>= 0.9.0)
155
- redis-client (0.17.0)
153
+ redis (5.0.8)
154
+ redis-client (>= 0.17.0)
155
+ redis-client (0.17.1)
156
156
  connection_pool
157
- regexp_parser (2.8.2)
157
+ regexp_parser (2.9.2)
158
158
  rest-client (2.1.0)
159
159
  http-accept (>= 1.7.0, < 2.0)
160
160
  http-cookie (>= 1.0.2, < 2.0)
161
161
  mime-types (>= 1.16, < 4.0)
162
162
  netrc (~> 0.8)
163
- rexml (3.2.6)
163
+ rexml (3.2.8)
164
+ strscan (>= 3.0.9)
164
165
  rollbar (3.4.1)
165
- rspec (3.12.0)
166
- rspec-core (~> 3.12.0)
167
- rspec-expectations (~> 3.12.0)
168
- rspec-mocks (~> 3.12.0)
169
- rspec-core (3.12.0)
170
- rspec-support (~> 3.12.0)
171
- rspec-expectations (3.12.0)
166
+ rspec (3.13.0)
167
+ rspec-core (~> 3.13.0)
168
+ rspec-expectations (~> 3.13.0)
169
+ rspec-mocks (~> 3.13.0)
170
+ rspec-core (3.13.0)
171
+ rspec-support (~> 3.13.0)
172
+ rspec-expectations (3.13.0)
172
173
  diff-lcs (>= 1.2.0, < 2.0)
173
- rspec-support (~> 3.12.0)
174
- rspec-mocks (3.12.0)
174
+ rspec-support (~> 3.13.0)
175
+ rspec-mocks (3.13.0)
175
176
  diff-lcs (>= 1.2.0, < 2.0)
176
- rspec-support (~> 3.12.0)
177
- rspec-support (3.12.0)
178
- rubocop (1.57.1)
179
- base64 (~> 0.1.1)
177
+ rspec-support (~> 3.13.0)
178
+ rspec-support (3.13.0)
179
+ rubocop (1.64.0)
180
180
  json (~> 2.3)
181
181
  language_server-protocol (>= 3.17.0)
182
182
  parallel (~> 1.10)
183
- parser (>= 3.2.2.4)
183
+ parser (>= 3.3.0.2)
184
184
  rainbow (>= 2.2.2, < 4.0)
185
185
  regexp_parser (>= 1.8, < 3.0)
186
186
  rexml (>= 3.2.5, < 4.0)
187
- rubocop-ast (>= 1.28.1, < 2.0)
187
+ rubocop-ast (>= 1.31.1, < 2.0)
188
188
  ruby-progressbar (~> 1.7)
189
189
  unicode-display_width (>= 2.4.0, < 3.0)
190
- rubocop-ast (1.29.0)
191
- parser (>= 3.2.1.0)
190
+ rubocop-ast (1.31.3)
191
+ parser (>= 3.3.1.0)
192
192
  rubocop-capybara (2.19.0)
193
193
  rubocop (~> 1.41)
194
194
  rubocop-factory_bot (2.24.0)
@@ -215,6 +215,7 @@ GEM
215
215
  sparql-client (3.2.2)
216
216
  net-http-persistent (~> 4.0, >= 4.0.2)
217
217
  rdf (~> 3.2, >= 3.2.11)
218
+ strscan (3.1.0)
218
219
  sxp (1.2.4)
219
220
  matrix (~> 0.4)
220
221
  rdf (~> 3.2)
@@ -248,8 +249,8 @@ DEPENDENCIES
248
249
  pry-byebug (~> 3.6)
249
250
  pushmi_pullyu!
250
251
  rake (~> 13.0)
251
- rspec (~> 3.0)
252
- rubocop (~> 1.57)
252
+ rspec (~> 3.13)
253
+ rubocop (~> 1.64)
253
254
  rubocop-rspec (~> 2.24)
254
255
  timecop (~> 0.9)
255
256
  vcr (~> 5.0)
@@ -32,7 +32,10 @@ swift:
32
32
  auth_url: http://localhost:8080/auth/v1.0
33
33
  project_name: demo
34
34
  project_domain_name: default
35
- container: ERA
35
+ container: era
36
+ # These 2 extra parameters are now required for keystone v3 authentication
37
+ auth_version: v3
38
+ user_domain: default
36
39
 
37
40
  rollbar:
38
41
  token: 'abc123xyz'
@@ -199,6 +199,8 @@ class PushmiPullyu::CLI
199
199
  def run_preservation_cycle
200
200
  begin
201
201
  entity = queue.wait_next_item
202
+ PushmiPullyu::Logging.log_preservation_attempt(entity,
203
+ queue.get_entity_ingestion_attempt(entity))
202
204
  return unless entity && entity[:type].present? && entity[:uuid].present?
203
205
  rescue StandardError => e
204
206
  log_exception(e)
@@ -212,7 +214,7 @@ class PushmiPullyu::CLI
212
214
  # Push tarred AIP to swift API
213
215
  deposited_file = swift.deposit_file(aip_filename, options[:swift][:container])
214
216
  # Log successful preservation event to the log files
215
- PushmiPullyu::Logging.log_preservation_event(deposited_file, aip_directory)
217
+ PushmiPullyu::Logging.log_preservation_success(entity, deposited_file, aip_directory)
216
218
  end
217
219
  # An EntityInvalid expection means there is a problem with the entity information format so there is no point in
218
220
  # readding it to the queue as it will always fail
@@ -221,7 +223,9 @@ class PushmiPullyu::CLI
221
223
  log_exception(e)
222
224
  begin
223
225
  queue.add_entity_in_timeframe(entity)
226
+ PushmiPullyu::Logging.log_preservation_fail_and_retry(entity, queue.get_entity_ingestion_attempt(entity), e)
224
227
  rescue PushmiPullyu::PreservationQueue::MaxDepositAttemptsReached => e
228
+ PushmiPullyu::Logging.log_preservation_failure(entity, queue.get_entity_ingestion_attempt(entity), e)
225
229
  log_exception(e)
226
230
  end
227
231
 
@@ -244,7 +248,11 @@ class PushmiPullyu::CLI
244
248
 
245
249
  def setup_log
246
250
  if options[:daemonize]
247
- PushmiPullyu::Logging.initialize_logger(PushmiPullyu.application_log_file)
251
+ PushmiPullyu::Logging.initialize_loggers(
252
+ log_target: PushmiPullyu.application_log_file,
253
+ events_target: "#{PushmiPullyu.options[:logdir]}/preservation_events.log",
254
+ json_target: "#{PushmiPullyu.options[:logdir]}/preservation_events.json"
255
+ )
248
256
  else
249
257
  logger.formatter = PushmiPullyu::Logging::SimpleFormatter.new
250
258
  end
@@ -266,10 +274,12 @@ class PushmiPullyu::CLI
266
274
  def swift
267
275
  @swift ||= PushmiPullyu::SwiftDepositer.new(username: options[:swift][:username],
268
276
  password: options[:swift][:password],
269
- tenant: options[:swift][:tenant],
270
277
  project_name: options[:swift][:project_name],
278
+ tenant: options[:swift][:tenant],
271
279
  project_domain_name: options[:swift][:project_domain_name],
272
- auth_url: options[:swift][:auth_url])
280
+ user_domain: options[:swift][:user_domain],
281
+ auth_url: options[:swift][:auth_url],
282
+ auth_version: options[:swift][:auth_version])
273
283
  end
274
284
 
275
285
  # On first call of shutdown, this will gracefully close the main run loop
@@ -21,14 +21,17 @@ module PushmiPullyu::Logging
21
21
 
22
22
  attr_writer :logger
23
23
 
24
- def initialize_logger(log_target = $stdout)
24
+ def initialize_loggers(log_target: $stdout, events_target: $stdout, json_target: $stdout)
25
+ @preservation_logger = Logger.new(events_target)
26
+ @preservation_json_logger = Logger.new(json_target)
27
+
25
28
  @logger = Logger.new(log_target)
26
29
  @logger.level = Logger::INFO
27
30
  @logger
28
31
  end
29
32
 
30
33
  def logger
31
- @logger ||= initialize_logger
34
+ @logger ||= initialize_loggers
32
35
  end
33
36
 
34
37
  def log_aip_activity(aip_directory, message)
@@ -43,10 +46,13 @@ module PushmiPullyu::Logging
43
46
  aip_logger.close
44
47
  end
45
48
 
46
- def log_preservation_event(deposited_file, aip_directory)
47
- preservation_logger = Logger.new("#{PushmiPullyu.options[:logdir]}/preservation_events.log")
48
- preservation_json_logger = Logger.new("#{PushmiPullyu.options[:logdir]}/preservation_events.json")
49
+ def log_preservation_event(message, message_json)
50
+ logger.info(message)
51
+ @preservation_logger.info(message)
52
+ @preservation_json_logger.info("#{message_json},")
53
+ end
49
54
 
55
+ def log_preservation_success(entity, deposited_file, aip_directory)
50
56
  message = "#{deposited_file.name} was successfully deposited into Swift Storage!\n" \
51
57
  "Here are the details of this preservation event:\n" \
52
58
  "\tUUID: '#{deposited_file.name}'\n" \
@@ -68,15 +74,76 @@ module PushmiPullyu::Logging
68
74
  end
69
75
  end
70
76
 
71
- # Log to both the application log, and the preservation log file
72
- logger.info(message)
73
- preservation_logger.info(message)
77
+ message_information = {
78
+ event_type: :success,
79
+ event_time: Time.now.to_s,
80
+ entity_type: entity[:type],
81
+ entity_uuid: entity[:uuid],
82
+ event_details: preservation_success_to_json(deposited_file, aip_directory)
83
+ }
84
+
85
+ log_preservation_event(message, message_information.to_json)
86
+ end
74
87
 
75
- preservation_logger.close
88
+ def log_preservation_fail_and_retry(entity, try_attempt, exception)
89
+ # We add + 1 to try_attempt because humans like to start counting from 1
90
+ try_attempt += 1
91
+ message = "#{entity[:type]} failed to be deposited and will try again.\n" \
92
+ "Here are the details of this preservation event:\n" \
93
+ "\t#{entity[:type]} uuid: #{entity[:uuid]}" \
94
+ "\tReadding to preservation queue with try attempt: #{try_attempt}\n" \
95
+ "\tError of type: #{exception.class.name}\n" \
96
+ "\tError message: #{exception.message}\n"
97
+
98
+ message_information = {
99
+ event_type: :fail_and_retry,
100
+ event_time: Time.now.to_s,
101
+ entity_type: entity[:type],
102
+ entity_uuid: entity[:uuid],
103
+ try_attempt: try_attempt,
104
+ error_message: exception.message
105
+ }
106
+
107
+ log_preservation_event(message, message_information.to_json)
108
+ end
109
+
110
+ def log_preservation_failure(entity, try_attempt, exception)
111
+ # We add + 1 to try_attempt because humans like to start counting from 1
112
+ try_attempt += 1
113
+ message = "#{entity[:type]} failed to be deposited.\n" \
114
+ "Here are the details of this preservation event:\n" \
115
+ "\t#{entity[:type]} uuid: #{entity[:uuid]}" \
116
+ "\tTry attempt: #{try_attempt}\n"
117
+
118
+ message_information = {
119
+ event_type: :failure,
120
+ event_time: Time.now.to_s,
121
+ entity_type: entity[:type],
122
+ entity_uuid: entity[:uuid],
123
+ try_attempt: try_attempt,
124
+ error_message: exception.message
125
+ }
126
+
127
+ log_preservation_event(message, message_information.to_json)
128
+ end
76
129
 
77
- message_json_str = preservation_event_to_json(deposited_file, aip_directory)
78
- preservation_json_logger.info("#{message_json_str},")
79
- preservation_json_logger.close
130
+ def log_preservation_attempt(entity, try_attempt)
131
+ # We add + 1 to try_attempt because humans like to start counting from 1
132
+ try_attempt += 1
133
+ message = "#{entity[:type]} will attempt to be deposited.\n" \
134
+ "Here are the details of this preservation event:\n" \
135
+ "\t#{entity[:type]} uuid: #{entity[:uuid]}" \
136
+ "\tTry attempt: #{try_attempt}\n"
137
+
138
+ message_information = {
139
+ event_type: :attempt,
140
+ event_time: Time.now.to_s,
141
+ entity_type: entity[:type],
142
+ entity_uuid: entity[:uuid],
143
+ try_attempt: try_attempt
144
+ }
145
+
146
+ log_preservation_event(message, message_information.to_json)
80
147
  end
81
148
 
82
149
  ###
@@ -107,14 +174,14 @@ module PushmiPullyu::Logging
107
174
  # note:
108
175
  # to parse, the prefix "I, ... INFO --:" in each line needs to be
109
176
  # stripped using a bash command such as "sed"
110
- def preservation_event_to_json(deposited_file, aip_directory)
177
+ def preservation_success_to_json(deposited_file, aip_directory)
111
178
  message = {}
112
179
 
113
180
  message['do_uuid'] = deposited_file.name.to_s
114
181
  message['aip_deposited_at'] = deposited_file.last_modified.to_s
115
182
  message['aip_md5sum'] = deposited_file.etag.to_s
116
183
  message['aip_sha256'] = ''
117
- message['aip_metadata'] = deposited_file.metadata.to_json.to_s
184
+ message['aip_metadata'] = deposited_file.metadata
118
185
 
119
186
  file_details = file_log_details(aip_directory)
120
187
 
@@ -131,14 +198,14 @@ module PushmiPullyu::Logging
131
198
  end
132
199
 
133
200
  message['aip_file_details'] = tmp_details
134
- message.to_json
201
+ message
135
202
  end
136
203
 
137
204
  def reopen
138
205
  if @logger
139
206
  @logger.reopen
140
207
  else
141
- @logger = initialize_logger
208
+ @logger = initialize_loggers
142
209
  end
143
210
  end
144
211
 
@@ -70,6 +70,13 @@ class PushmiPullyu::PreservationQueue
70
70
  end
71
71
  end
72
72
 
73
+ def get_entity_ingestion_attempt(entity)
74
+ entity_attempts_key = "#{PushmiPullyu.options[:ingestion_prefix]}#{entity[:uuid]}"
75
+ @redis.with do |connection|
76
+ return connection.get(entity_attempts_key).to_i
77
+ end
78
+ end
79
+
73
80
  def add_entity_in_timeframe(entity)
74
81
  entity_attempts_key = "#{PushmiPullyu.options[:ingestion_prefix]}#{entity[:uuid]}"
75
82
 
@@ -6,16 +6,24 @@ class PushmiPullyu::SwiftDepositer
6
6
  attr_reader :swift_connection
7
7
 
8
8
  def initialize(connection)
9
- @swift_connection = OpenStack::Connection.create(
9
+ # Generic authentication parameters
10
+ swift_connection_parameters = {
10
11
  username: connection[:username],
11
12
  api_key: connection[:password],
12
- auth_method: 'password',
13
13
  auth_url: connection[:auth_url],
14
14
  project_name: connection[:project_name],
15
- project_domain_name: connection[:project_domain_name],
16
- authtenant_name: connection[:tenant],
15
+ auth_method: 'password',
17
16
  service_type: 'object-store'
18
- )
17
+ }
18
+
19
+ if connection[:auth_version] == 'v3'
20
+ swift_connection_parameters[:user_domain] = connection[:user_domain]
21
+ elsif connection[:auth_version] == 'v1'
22
+ swift_connection_parameters[:project_domain_name] = connection[:project_domain_name]
23
+ swift_connection_parameters[:authtenant_name] = connection[:tenant]
24
+ end
25
+
26
+ @swift_connection = OpenStack::Connection.create(swift_connection_parameters)
19
27
  end
20
28
 
21
29
  def deposit_file(file_name, swift_container)
@@ -1,3 +1,3 @@
1
1
  module PushmiPullyu
2
- VERSION = '2.0.7'.freeze
2
+ VERSION = '2.1.1'.freeze
3
3
  end
data/lib/pushmi_pullyu.rb CHANGED
@@ -39,7 +39,9 @@ module PushmiPullyu
39
39
  auth_url: 'http://localhost:8080/auth/v1.0',
40
40
  project_name: 'demo',
41
41
  project_domain_name: 'default',
42
- container: 'ERA'
42
+ container: 'era',
43
+ auth_version: 'v3',
44
+ user_domain: 'default'
43
45
  },
44
46
  rollbar: {},
45
47
  # rubocop disable: Style/FetchEnvVar
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pushmi_pullyu
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.7
4
+ version: 2.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shane Murnaghan
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2023-10-16 00:00:00.000000000 Z
12
+ date: 2024-06-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -294,7 +294,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
294
294
  - !ruby/object:Gem::Version
295
295
  version: '0'
296
296
  requirements: []
297
- rubygems_version: 3.3.26
297
+ rubygems_version: 3.1.6
298
298
  signing_key:
299
299
  specification_version: 4
300
300
  summary: Ruby application to manage flow of content from Jupiter into Swift for preservation