pushmi_pullyu 2.0.7 → 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
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