eco-helpers 3.0.4 → 3.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -0
  3. data/CHANGELOG.md +44 -4
  4. data/eco-helpers.gemspec +1 -1
  5. data/lib/eco/api/common/class_helpers.rb +24 -23
  6. data/lib/eco/api/common/class_meta_basics.rb +0 -2
  7. data/lib/eco/api/common/loaders/use_case.rb +1 -0
  8. data/lib/eco/api/common/people/entry_factory.rb +6 -4
  9. data/lib/eco/api/common/people/person_entry.rb +4 -6
  10. data/lib/eco/api/common/people/person_entry_attribute_mapper.rb +25 -12
  11. data/lib/eco/api/common/people/person_parser.rb +8 -0
  12. data/lib/eco/api/common/session/base_session.rb +1 -1
  13. data/lib/eco/api/common/session/environment.rb +7 -0
  14. data/lib/eco/api/common/session/file_manager.rb +15 -8
  15. data/lib/eco/api/common/session/logger/cache.rb +14 -10
  16. data/lib/eco/api/common/session/logger/log.rb +8 -7
  17. data/lib/eco/api/common/session/mailer.rb +22 -13
  18. data/lib/eco/api/common/session/s3_uploader.rb +29 -20
  19. data/lib/eco/api/microcases/people_search.rb +1 -1
  20. data/lib/eco/api/organization/login_providers.rb +11 -4
  21. data/lib/eco/api/organization/node_classifications.rb +3 -0
  22. data/lib/eco/api/organization/presets_factory.rb +37 -31
  23. data/lib/eco/api/organization/tag_tree.rb +14 -5
  24. data/lib/eco/api/policies/default_policies/99_user_access_policy.rb +28 -18
  25. data/lib/eco/api/session/batch/errors.rb +38 -20
  26. data/lib/eco/api/session/batch/job.rb +252 -135
  27. data/lib/eco/api/session/batch/status.rb +55 -36
  28. data/lib/eco/api/session/batch.rb +2 -2
  29. data/lib/eco/api/session/config/base_config.rb +12 -11
  30. data/lib/eco/api/session/config/tagtree.rb +10 -14
  31. data/lib/eco/api/session/config/workflow.rb +15 -3
  32. data/lib/eco/api/session/config.rb +19 -26
  33. data/lib/eco/api/session.rb +13 -4
  34. data/lib/eco/api/usecases/cli.rb +4 -0
  35. data/lib/eco/api/usecases/default/locations/cli/codes_to_tags_cli.rb +18 -0
  36. data/lib/eco/api/usecases/default/locations/cli/csv_to_tree_cli.rb +12 -0
  37. data/lib/eco/api/usecases/default/locations/cli/tagtree_paths_cli.rb +12 -0
  38. data/lib/eco/api/usecases/default/locations/codes_to_tags_case.rb +32 -13
  39. data/lib/eco/api/usecases/default/locations/csv_to_tree_case.rb +15 -5
  40. data/lib/eco/api/usecases/default/locations/tagtree_extract_case.rb +6 -0
  41. data/lib/eco/api/usecases/default/locations/tagtree_paths_case.rb +51 -0
  42. data/lib/eco/api/usecases/default/locations.rb +1 -1
  43. data/lib/eco/api/usecases/default/people/amend/cli/reinvite_sync_cli.rb +8 -0
  44. data/lib/eco/api/usecases/default/people/amend/cli/reinvite_trans_cli.rb +11 -0
  45. data/lib/eco/api/usecases/default/people/amend/cli/restore_db_cli.rb +26 -0
  46. data/lib/eco/api/usecases/default/people/amend/reinvite_sync_case.rb +2 -0
  47. data/lib/eco/api/usecases/default/people/amend/reinvite_trans_case.rb +2 -0
  48. data/lib/eco/api/usecases/default/people/amend/restore_db_case.rb +3 -0
  49. data/lib/eco/api/usecases/default/people/treat/analyse_people_case.rb +15 -5
  50. data/lib/eco/api/usecases/default/people/treat/cli/analyse_people_cli.rb +66 -0
  51. data/lib/eco/api/usecases/default/people/treat/cli/org_data_convert_cli.rb +35 -0
  52. data/lib/eco/api/usecases/default/people/treat/cli/supers_cyclic_identify_cli.rb +15 -0
  53. data/lib/eco/api/usecases/default/people/treat/cli/supers_hierachy_cli.rb +15 -0
  54. data/lib/eco/api/usecases/default/people/treat/org_data_convert_case.rb +11 -5
  55. data/lib/eco/api/usecases/default/people/treat/supers_cyclic_identify_case.rb +28 -7
  56. data/lib/eco/api/usecases/default/people/treat/supers_hierarchy_case.rb +32 -9
  57. data/lib/eco/api/usecases/default/people/utils/set_default_tag_case.rb +2 -1
  58. data/lib/eco/api/usecases/default_cases/to_csv_case.rb +2 -2
  59. data/lib/eco/api/usecases/graphql/helpers/location/base/classifications_parser.rb +5 -0
  60. data/lib/eco/api/usecases/graphql/helpers/location/command/diffs/stages/commandable.rb +2 -0
  61. data/lib/eco/api/usecases/graphql/helpers/location/command/diffs/stages/diff_sortable.rb +2 -0
  62. data/lib/eco/api/usecases/graphql/helpers/location/command/result.rb +2 -1
  63. data/lib/eco/api/usecases/graphql/helpers/location/command/results.rb +3 -0
  64. data/lib/eco/api/usecases/graphql/helpers/location/command.rb +1 -0
  65. data/lib/eco/api/usecases/graphql/helpers/location/tags_remap.rb +3 -0
  66. data/lib/eco/api/usecases/graphql/samples/location/command/service/tree_update.rb +2 -0
  67. data/lib/eco/api/usecases/graphql/samples/location/command/track_changed_ids.rb +1 -0
  68. data/lib/eco/api/usecases/graphql/samples/location/service/tree_diff/convertible/parsing/classifications.rb +2 -0
  69. data/lib/eco/api/usecases/graphql/samples/location/service/tree_diff.rb +6 -2
  70. data/lib/eco/api/usecases/graphql/samples/location/service/tree_to_list/converter/parser.rb +6 -2
  71. data/lib/eco/api/usecases/graphql/samples/location/service/tree_to_list/converter.rb +2 -0
  72. data/lib/eco/api/usecases/ooze_cases/export_register_case.rb +1 -0
  73. data/lib/eco/api/usecases/ooze_samples/helpers_migration/copying.rb +66 -29
  74. data/lib/eco/api/usecases/ooze_samples/ooze_base_case.rb +25 -3
  75. data/lib/eco/api/usecases/ooze_samples/register_update_case.rb +10 -0
  76. data/lib/eco/api/usecases/use_case.rb +3 -1
  77. data/lib/eco/cli/config/use_cases.rb +4 -0
  78. data/lib/eco/cli/scripting/args_helpers.rb +3 -2
  79. data/lib/eco/cli/scripting/argument.rb +2 -2
  80. data/lib/eco/cli_default/input.rb +49 -45
  81. data/lib/eco/cli_default/input_filters.rb +32 -17
  82. data/lib/eco/cli_default/options.rb +8 -4
  83. data/lib/eco/cli_default/people.rb +1 -1
  84. data/lib/eco/cli_default/people_filters.rb +32 -24
  85. data/lib/eco/cli_default/usecases.rb +8 -121
  86. data/lib/eco/cli_default/workflow.rb +6 -4
  87. data/lib/eco/csv/split.rb +2 -0
  88. data/lib/eco/csv/table.rb +13 -0
  89. data/lib/eco/data/files/encoding.rb +15 -8
  90. data/lib/eco/data/files/helpers.rb +6 -2
  91. data/lib/eco/data/hashes/diff_result.rb +5 -0
  92. data/lib/eco/data/locations/node_diff/nodes_diff.rb +13 -0
  93. data/lib/eco/data/locations/node_diff.rb +4 -0
  94. data/lib/eco/data/locations/node_level.rb +6 -0
  95. data/lib/eco/language/auxiliar_logger.rb +2 -0
  96. data/lib/eco/version.rb +1 -1
  97. data/lib/eco-helpers.rb +1 -1
  98. metadata +15 -6
  99. data/lib/eco/api/usecases/default/locations/create_tag_paths_case.rb +0 -25
  100. data/lib/eco/api/usecases/default/people/amend/reinvite_trans_cli.rb +0 -4
@@ -1,18 +1,23 @@
1
+ # rubocop:disable Naming/MethodParameterName
1
2
  module Eco
2
3
  module API
3
4
  class Session
4
5
  class Batch
5
6
  # @attr_reader name [String] the name of this `batch job`
6
7
  # @attr_reader type [Symbol] a valid batch operation
7
- # @attr_reader sets [Array<Symbol>] the parts of the person model this batch is supposed to affect
8
- # @attr_reader usecase [Eco::API::UseCases::UseCase, nil] when provided: `usecase` that generated this `batch job`
9
- # @attr_reader status [Eco::API::Session::Batch::Status] if launched: the `status` of the `batch`
10
- # @attr_reader feedback [Eco::API::Session::Batch::Feedback] helper class for feedback and end-user decision making
8
+ # @attr_reader sets [Array<Symbol>] the parts of the person model this
9
+ # batch is supposed to affect
10
+ # @attr_reader usecase [Eco::API::UseCases::UseCase, nil] when provided:
11
+ # `usecase` that generated this `batch job`
12
+ # @attr_reader status [Eco::API::Session::Batch::Status] if launched:
13
+ # the `status` of the `batch`
14
+ # @attr_reader feedback [Eco::API::Session::Batch::Feedback] helper class
15
+ # for feedback and end-user decision making
11
16
  class Job < Eco::API::Common::Session::BaseSession
12
17
  include Eco::Language::Methods::DslAble
13
18
 
14
- @types = [:get, :create, :update, :delete]
15
- @sets = [:core, :details, :account]
19
+ @types = %i[get create update delete]
20
+ @sets = %i[core details account]
16
21
 
17
22
  class << self
18
23
  attr_reader :types, :sets
@@ -31,20 +36,30 @@ module Eco
31
36
  attr_reader :usecase
32
37
  attr_reader :status, :feedback
33
38
 
34
- # @param e [Eco::API::Common::Session::Environment] requires a session environment, as any child of `Eco::API::Common::Session::BaseSession`.
39
+ # @param ev [Eco::API::Common::Session::Environment] requires a session environment, as
40
+ # any child of `Eco::API::Common::Session::BaseSession`.
35
41
  # @param name [String] the name of this `batch job`
36
42
  # @param type [Symbol] a valid batch operation.
37
43
  # @param usecase [Eco::API::UseCases::UseCase, nil] when provided: `usecase` that generated this `batch job`.
38
- # This is necessary to know the `options` used to run the usecase, which could modify the `Batch::Job` behviour.
44
+ # This is necessary to know the `options` used to run the usecase, which could modify the
45
+ # `Batch::Job` behviour.
39
46
  # @param accept_update_with_no_id [Boolean] temporary contingency
40
47
  # This parameter has been added due to a bug on server side.
41
48
  # An external_id is still required.
42
- def initialize(e, name:, type:, sets:, usecase: nil, accept_update_with_no_id: false)
43
- raise "A name is required to refer a job. Given: #{name}" if !name
44
- raise "Type should be one of #{self.class.types}. Given: #{type}" unless self.class.valid_type?(type)
45
- raise "Sets should be some of #{self.class.sets}. Given: #{sets}" unless self.class.valid_sets?(sets)
46
- raise "usecase must be a Eco::API::UseCases::UseCase object. Given: #{usecase.class}" if usecase && !usecase.is_a?(Eco::API::UseCases::UseCase)
47
- super(e)
49
+ def initialize(ev, name:, type:, sets:, usecase: nil, accept_update_with_no_id: false)
50
+ msg = "A name is required to refer a job. Given: '#{name}'"
51
+ raise msg unless name
52
+
53
+ msg = "Type should be one of #{self.class.types}. Given: #{type}"
54
+ raise msg unless self.class.valid_type?(type)
55
+
56
+ msg = "Sets should be some of #{self.class.sets}. Given: #{sets}"
57
+ raise msg unless self.class.valid_sets?(sets)
58
+
59
+ msg = "usecase must be a Eco::API::UseCases::UseCase object. Given: #{usecase.class}"
60
+ raise msg if usecase && !usecase.is_a?(Eco::API::UseCases::UseCase)
61
+
62
+ super(ev)
48
63
 
49
64
  @name = name
50
65
  @type = type
@@ -69,12 +84,21 @@ module Eco
69
84
  # * mostly used for error_handlers
70
85
  # @return [Eco::API::Session::Batch::Job]
71
86
  def dup(name = "ad-hoc:job-from:#{self.name}", usecase: self.usecase)
72
- self.class.new(enviro, name: name, type: type, sets: sets, usecase: usecase)
87
+ self.class.new(
88
+ enviro,
89
+ name: name,
90
+ type: type,
91
+ sets: sets,
92
+ usecase: usecase
93
+ )
73
94
  end
74
95
 
75
96
  # @return [Eco::API::Session::Batch::Jobs] group of subjobs of this `Batch::Job`
76
97
  def subjobs
77
- @subjobs ||= Eco::API::Session::Batch::Jobs.new(enviro, name: "childs-of:#{self.name}")
98
+ @subjobs ||= Eco::API::Session::Batch::Jobs.new(
99
+ enviro,
100
+ name: "childs-of:#{name}"
101
+ )
78
102
  end
79
103
 
80
104
  # @return [Boolean] `true` if the current batch job is a result of an error_handler
@@ -93,24 +117,27 @@ module Eco
93
117
  end
94
118
 
95
119
  # Adds an entry(ies) to the job queue.
96
- # @param entry [Ecoportal::API::V1::Person, Enumerable<Person>] the person(s) we want to update, carrying the changes to be done.
120
+ # @param entry [Ecoportal::API::V1::Person, Enumerable<Person>]
121
+ # the person(s) we want to update, carrying the changes to be done.
97
122
  # @param unique [Boolean] specifies if repeated entries should be avoided in the queue.
98
- # @yield [person] callback before launching the batch job request against the server.
99
- # @yieldparam person [Person] current person object that that should be treated by the callback before launching the batch.
123
+ # @yield [person] callback before launching the batch job request
124
+ # against the server.
125
+ # @yieldparam person [Person] current person object that that should be
126
+ # treated by the callback before launching the batch.
100
127
  # @return [Eco::API::Session::Batch::Job] this `Batch::Job`.
101
128
  def add(entry, unique: true, &block)
102
129
  case entry
103
130
  when Enumerable
104
- entry.each {|e| add(e, unique: unique, &block)}
131
+ entry.each {|el| add(el, unique: unique, &block)}
105
132
  else
106
- unless !entry
107
- unless unique && @queue_hash.key?(entry)
108
- @queue_hash[entry] = true
109
- @queue.push(entry)
110
- @callbacks[entry] = block if block_given?
111
- end
112
- end
133
+ return self unless entry
134
+ return self if unique && @queue_hash.key?(entry)
135
+
136
+ @queue_hash[entry] = true
137
+ @queue.push(entry)
138
+ @callbacks[entry] = block if block_given?
113
139
  end
140
+
114
141
  self
115
142
  end
116
143
 
@@ -123,7 +150,9 @@ module Eco
123
150
  # @raise [Exception] if 'launch' has not firstly invoked
124
151
  # @return [Enumbrable<Hash>] the last requests that the queue will generate
125
152
  def requests
126
- raise "Method missuse. Firstly 'launch' should be invoked" unless instance_variable_defined?(:@requests)
153
+ msg = "Method missuse. Firstly 'launch' should be invoked"
154
+ raise msg unless instance_variable_defined?(:@requests)
155
+
127
156
  @requests
128
157
  end
129
158
 
@@ -135,7 +164,7 @@ module Eco
135
164
  # @see Eco::API::Session::Batch::Status#errors?
136
165
  # @return [Boolean] `true` if there were Server errors, `false` otherwise
137
166
  def errors?
138
- status && status.errors?
167
+ status&.errors?
139
168
  end
140
169
 
141
170
  # Helper/shortcut to obtain a people object out of `input`
@@ -148,27 +177,34 @@ module Eco
148
177
  # Processes the `queue` and, unless `simulate` is `true`, launches against the server:
149
178
  # 1. pre_processes the queue obtaining the `requests`:
150
179
  # - if the entries of `queue` got pending _callbacks_ (delayed changes), it processes them
151
- # - unless type == `:create`: if there's a defined `api_excluded` _callback_ it calls it (see {Eco::API::Session::Config::People#api_excluded})
180
+ # - unless type == `:create`: if there's a defined `api_excluded`
181
+ # _callback_ it calls it (see {Eco::API::Session::Config::People#api_excluded})
152
182
  # - transforms the result to a `Eco::API::Organization::People` object
153
- # - if there are `api policies` defined, it passes the entries through them in order (see {Eco::API::Session::Config#policies})
183
+ # - if there are `api policies` defined, it passes the entries through
184
+ # them in order (see {Eco::API::Session::Config#policies})
154
185
  # - this step is **skipped** if the option `-skip-api-policies` was used in the command line
155
186
  # - at this point all the transformations have taken place...
156
- # - only include the entries that, after all above, still hold pending changes (`!as_update.empty?`) to be launched as update
187
+ # - only include the entries that, after all above, still hold pending changes
188
+ # (`!as_update.empty?`) to be launched as update
157
189
  # 2. pre launch checks against the `requests`:
158
190
  # - it generates `stats` (`Eco::API::Session::Batch::RequestStats`) out of the requests
159
- # - if there is a batch policy declared for the current job `type`, it checks compliance against `stats` (see {Eco::API::Session::Batch::Policies}),
191
+ # - if there is a batch policy declared for the current job `type`, it
192
+ # checks compliance against `stats` (see {Eco::API::Session::Batch::Policies}),
160
193
  # - a non-compliant batch will stop the current session by raising an `Exception`
161
194
  # - this setp is **skipped** if the option `-skip-batch-policy` was used in the command line
162
195
  # 3. if we are **not** in `dry-run` (or `simulate`), it:
163
- # - backs up the raw queries (`requests`) launched to the Server, if we are **not** in `dry-run` (or `simulate`)
196
+ # - backs up the raw queries (`requests`) launched to the Server,
197
+ # if we are **not** in `dry-run` (or `simulate`)
164
198
  # - **launches the batch** request against the _Server_ (see {Eco::API::Session::Batch#launch})
165
199
  # - links the resulting batch `status` to this `Batch::Job` (see {Eco::API::Session::Batch::Status})
166
200
  # - prints any `errors` replied by the _Server_
167
201
  # 4. the post launch kicks in, and:
168
- # - for success requests, it consolidates the associated entries (see `Ecoportal::API::V1::Person#consolidate!`)
169
- # - launches specific error handlers, if there were **errors** from the Server as a result of the `batch.launch`, and there are `Error::Handlers` defined
202
+ # - for success requests, it consolidates the associated entries
203
+ # (see `Ecoportal::API::V1::Person#consolidate!`)
204
+ # - launches specific error handlers, if there were **errors** from the Server
205
+ # as a result of the `batch.launch`, and there are `Error::Handlers` defined
170
206
  # @return [Eco::API::Session::Batch::Status]
171
- def launch(simulate: false)
207
+ def launch(simulate: false) # rubocop:disable Metrics/AbcSize
172
208
  pqueue = processed_queue
173
209
  @requests = as_update(pqueue)
174
210
  pre_checks(requests, simulate: simulate)
@@ -178,26 +214,30 @@ module Eco
178
214
  req_backup = as_update(pqueue, add_feedback: false)
179
215
  backup_update(req_backup, simulate: simulate)
180
216
  end
181
- else
182
- if pqueue.length > 0
183
- req_backup = as_update(pqueue, add_feedback: false)
184
- backup_update(req_backup)
185
- logger.debug("Job ('#{name}':#{type}): going to launch batch against #{pqueue.count} entries")
186
- session.batch.launch(pqueue, method: type).tap do |job_status|
187
- @status = job_status
188
- status.root = self
189
- status.errors.print
190
- end
217
+ elsif !pqueue.empty?
218
+ req_backup = as_update(pqueue, add_feedback: false)
219
+ backup_update(req_backup)
220
+ log(:debug) {
221
+ "Job ('#{name}':#{type}): going to launch batch against #{pqueue.count} entries"
222
+ }
223
+
224
+ session.batch.launch(pqueue, method: type).tap do |job_status|
225
+ @status = job_status
226
+ status.root = self
227
+ status.errors.print
191
228
  end
192
229
  end
193
230
 
194
231
  unless requests.empty? || !simulate
195
- logger.info("--- simulate mode (dry-run) -- job '#{name}' -- this would have launched #{type.to_s.upcase}")
232
+ msg = "--- simulate mode (dry-run) -- job '#{name}' "
233
+ msg << "-- this would have launched #{type.to_s.upcase}"
234
+ log(:info) { msg }
196
235
  end
197
236
 
198
237
  post_launch(queue: pqueue, simulate: simulate)
199
238
  @pending = false
200
- return status
239
+
240
+ status
201
241
  end
202
242
 
203
243
  # Provides a text summary of the current status including:
@@ -206,18 +246,19 @@ module Eco
206
246
  # 3. error messages in case they were errors from the server
207
247
  # @note if `launch` was not invoked, it specifies so
208
248
  # @return [String] the summary
209
- def summary
249
+ def summary # rubocop:disable Metrics/AbcSize
210
250
  [].tap do |msg|
211
251
  if pending?
212
252
  msg << "PENDING - Batch #{type.to_s.upcase} - job '#{name}' - length: #{@queue.length}"
213
253
  else
214
- msg << feedback.generate(requests, only_stats: true)
254
+ msg << feedback.generate(requests, only_stats: true)
255
+
215
256
  if batch_policy && !batch_policy.compliant?(request_stats)
216
257
  msg << "Batch Policy Uncompliance:"
217
258
  msg << batch_policy.uncompliance(request_stats)
218
259
  end
219
260
 
220
- msg << status.errors.message unless !status
261
+ msg << status.errors.message if status
221
262
  msg << subjobs_summary
222
263
  end
223
264
  end.join("\n")
@@ -226,20 +267,19 @@ module Eco
226
267
  private
227
268
 
228
269
  def subjobs_summary
229
- return "" unless subjobs.count > 0
270
+ return "" unless subjobs.count.positive?
271
+
230
272
  [].tap do |msg|
231
273
  subjobs.map {|subjob| msg << subjob.summary}
232
274
  end.join("\n")
233
275
  end
234
276
 
235
277
  def as_update(data, **kargs)
236
- if data.is_a?(Array)
237
- data.map do |e|
238
- feedback.as_update(e, **kargs)
239
- end.compact.select {|e| e && !e.empty?}
240
- else
241
- feedback.as_update(data, **kargs)
242
- end
278
+ return feedback.as_update(data, **kargs) unless data.is_a?(Array)
279
+
280
+ data.map do |el|
281
+ feedback.as_update(el, **kargs)
282
+ end.compact.reject(&:empty?)
243
283
  end
244
284
 
245
285
  # Method to generate the base of people that will be present in the queue
@@ -249,29 +289,42 @@ module Eco
249
289
  # The entry won't be included.
250
290
  # - The contingency above wouldn't be necessary if the server worked perfectly.
251
291
  def processed_queue
252
- pre_filtered = @queue.select do |entry|
292
+ pre_filtered = pre_filtered_queue
293
+ pre_filtered.each do |el|
294
+ @callbacks[el].call(el) if @callbacks.key?(el)
295
+ end
296
+
297
+ apply_policies(api_included(pre_filtered)).reject do |el|
298
+ as_update(el).empty?
299
+ end.select do |el|
300
+ next true unless el.is_a?(Ecoportal::API::V1::Person)
301
+ next true unless el.new?
302
+
303
+ # new people should either have account or details
304
+ el.account || el.details
305
+ end
306
+ end
307
+
308
+ def pre_filtered_queue
309
+ @queue.select do |entry|
253
310
  by_pass_filter = false
254
- if unexisting = entry.new? && !entry.id && type != :create
311
+
312
+ if (unexisting = entry.new? && !entry.id && type != :create)
255
313
  ref = Eco::API::Session::Batch::Feedback.person_ref(entry)
314
+
256
315
  msg = "Job ('#{name}':#{type}): "
257
316
  if (by_pass_filter = entry.external_id && @accept_update_with_no_id)
258
- msg << "entry errored on creation (failed creation) but will try with person code: #{ref}"
317
+ msg << "entry errored on creation (failed creation)"
318
+ msg << " but will try with person code: #{ref}"
259
319
  else
260
320
  msg << "excluded unexisting entry (failed creation): #{ref}"
261
321
  end
262
- session.logger.warn(msg)
322
+
323
+ log(:warn) { msg }
263
324
  end
325
+
264
326
  !unexisting || by_pass_filter
265
327
  end
266
- pre_filtered.each {|e| @callbacks[e].call(e) if @callbacks.key?(e) }
267
- apply_policies(api_included(pre_filtered)).select do |e|
268
- !as_update(e).empty?
269
- end.select do |e|
270
- next true unless e.is_a?(Ecoportal::API::V1::Person)
271
- next true unless e.new?
272
- # new people should either have account or details
273
- e.account || e.details
274
- end
275
328
  end
276
329
 
277
330
  # if there is a config definition to exclude entries
@@ -279,48 +332,67 @@ module Eco
279
332
  # - filter out excluded entries from the api update
280
333
  def api_included(full_queue)
281
334
  return full_queue if type == :create
282
- return full_queue unless excluded_callback = session.config.people.api_excluded
335
+ return full_queue unless (excluded_callback = session.config.people.api_excluded)
283
336
 
284
337
  inc_excluded = options.dig(:include, :excluded)
285
338
  excluded_only = inc_excluded.is_a?(Hash) && excluded[:only]
286
- is_excluded = Proc.new do |entry|
339
+
340
+ is_excluded = proc do |entry|
287
341
  evaluate(entry, session, options, self, &excluded_callback)
288
342
  end
343
+
289
344
  return full_queue.select(&is_excluded) if excluded_only
290
345
  return full_queue if inc_excluded
346
+
291
347
  full_queue.reject(&is_excluded)
292
348
  end
293
349
 
294
350
  # Applies the changes introduced by api policies
295
351
  def apply_policies(pre_queue)
296
352
  people(pre_queue).tap do |entries|
353
+ next if options.dig(:skip, :api_policies)
354
+
297
355
  policies = session.policies
298
- unless policies.empty? || options.dig(:skip, :api_policies)
299
- policies.launch(people: entries, session: session, options: options, job: self)
300
- end
356
+ next if policies.empty?
357
+
358
+ policies.launch(
359
+ people: entries,
360
+ session: session,
361
+ options: options,
362
+ job: self
363
+ )
301
364
  end
302
365
  end
303
366
 
304
367
  # Shortcut to get the batch (belt) policy
305
368
  def batch_policy
306
- unless options.dig(:skip, :batch_policy)
307
- @batch_policy ||= session.config.batch_policies[self.type]
308
- end
369
+ return if options.dig(:skip, :batch_policy)
370
+
371
+ @batch_policy ||= session.config.batch_policies[type]
309
372
  end
310
373
 
311
374
  # Checks batch policy compliance and displays the feedback on request stats
312
375
  def pre_checks(requests, simulate: false)
313
376
  only_stats = options.dig(:feedback, :only_stats)
314
377
  max_chars = simulate ? 2500 : 800
315
- msg = feedback.generate(requests, max_chars: max_chars, only_stats: only_stats)
316
- logger.info(msg)
378
+
379
+ msg = feedback.generate(
380
+ requests,
381
+ max_chars: max_chars,
382
+ only_stats: only_stats
383
+ )
384
+ log(:info) { msg }
385
+
386
+ return unless batch_policy
317
387
 
318
388
  # batch_policy
319
- stats = request_stats(requests)
320
- if simulate && batch_policy && !batch_policy.compliant?(stats)
321
- logger.warn("Batch Policy Uncompliance: this and next batches will be aborted!")
322
- logger.warn(batch_policy.uncompliance(stats))
323
- elsif batch_policy
389
+ stats = request_stats(requests)
390
+
391
+ if simulate && !batch_policy.compliant?(stats)
392
+ msg = "Batch Policy Uncompliance: this and next batches will be aborted!\n"
393
+ msg << batch_policy.uncompliance(stats)
394
+ log(:warn) { msg }
395
+ else
324
396
  # will throw an Exception if the policy request_stats is not compliant
325
397
  batch_policy.validate!(stats)
326
398
  end
@@ -330,56 +402,99 @@ module Eco
330
402
  # 1. `consolidate!` person model if succeeded (person.doc -> person.original_doc)
331
403
  # 2. if there were errors: launch specific error handlers if they are defined for the type of error
332
404
  def post_launch(queue: [], simulate: false)
333
- if !simulate && status
334
- status.queue.map do |entry|
335
- if status.success?(entry)
336
- if type == :create && entry.respond_to?(:id=)
337
- entry.id = status[entry].body["id"].tap do |id|
338
- if id.to_s.strip.empty?
339
- ref = Eco::API::Session::Batch::Feedback.person_ref(entry)
340
- msg = "Entry has been created but API did not return its 'id': #{ref}"
341
- if response = status[entry]
342
- msg << " (Response - status: #{response.status.code}; body: #{response.body.pretty_inspect})"
343
- end
344
- logger.error(msg)
345
- end
346
- end
347
- end
348
- if entry.respond_to?(:consolidate!)
349
- entry.consolidate!
350
- if entry.respond_to?(:dirty?) && entry.dirty? && entry.respond_to?(:as_update)
351
- msg = "After consolidate there's still a dirty model:\n"
352
- msg << entry.as_update.pretty_inspect
353
- logger.debug(msg)
354
- end
355
- end
356
- #else # do not entry.reset! (keep track on changes still)
357
- end
405
+ return consolidate_changes_dry_run!(queue: queue) if simulate
406
+
407
+ consolidate_changes_actual_run!
408
+ run_error_handlers!
409
+ end
410
+
411
+ def consolidate_changes_dry_run!(queue: [])
412
+ fake_id = 111_111_111_111_111_111_111_111
413
+
414
+ queue.each do |entry|
415
+ if type == :create && entry.respond_to?(:id=)
416
+ entry.id = fake_id.to_s
417
+ fake_id += 1
358
418
  end
359
- # launch error_handlers
360
- handlers = session.config.error_handlers
361
- if status.errors.any? && !handlers.empty? && !error_handler?
362
- err_types = status.errors.by_type
363
- logger.debug("(#{self.name}) got these error types: #{err_types.keys}")
364
- handlers.each do |handler|
365
- if entries = err_types[handler.name]
366
- handler_job = subjobs_add("#{self.name} => #{handler.name}", usecase: handler)
367
- logger.debug("Running error handler #{handler.name} (against #{entries.count} entries)")
368
- handler.launch(people: people(entries), session: session, options: options, job: handler_job)
369
- logger.debug("Launching job of error handler: #{handler_job.name}")
370
- handler_job.launch(simulate: simulate)
419
+
420
+ entry.consolidate! if entry.respond_to?(:consolidate!)
421
+ end
422
+ end
423
+
424
+ def consolidate_changes_actual_run! # rubocop:disable Metrics/AbcSize
425
+ return unless status
426
+
427
+ status.queue.each do |entry|
428
+ next unless status.success?(entry)
429
+
430
+ if type == :create && entry.respond_to?(:id=)
431
+ entry.id = status[entry].body["id"].tap do |id|
432
+ next unless id.to_s.strip.empty?
433
+
434
+ ref = Eco::API::Session::Batch::Feedback.person_ref(entry)
435
+ msg = "Entry has been created but API did not return its 'id': #{ref}"
436
+
437
+ if (response = status[entry])
438
+ msg << " (Response - status: #{response.status.code}; "
439
+ msg << "body: #{response.body.pretty_inspect})"
371
440
  end
441
+
442
+ log(:error) { msg }
372
443
  end
373
444
  end
374
- elsif simulate
375
- fake_id = 111111111111111111111111
376
- queue.map do |entry|
377
- if type == :create && entry.respond_to?(:id=)
378
- entry.id = fake_id.to_s
379
- fake_id += 1
380
- end
381
- entry.consolidate! if entry.respond_to?(:consolidate!)
382
- end
445
+
446
+ next unless entry.respond_to?(:consolidate!)
447
+
448
+ entry.consolidate!
449
+
450
+ next unless entry.respond_to?(:dirty?)
451
+ next unless entry.dirty?
452
+ next unless entry.respond_to?(:as_update)
453
+
454
+ msg = "After consolidate there's still a dirty model:\n"
455
+ msg << entry.as_update.pretty_inspect
456
+ log(:debug) { msg }
457
+ end
458
+ end
459
+
460
+ def run_error_handlers! # rubocop:disable Metrics/AbcSize
461
+ return if error_handler?
462
+ return unless status
463
+ return unless status.errors.any?
464
+
465
+ handlers = session.config.error_handlers
466
+ return if handlers.empty?
467
+
468
+ # launch error_handlers
469
+ err_types = status.errors.by_type
470
+ log(:debug) {
471
+ "(#{name}) got these error types: #{err_types.keys}"
472
+ }
473
+
474
+ handlers.each do |handler|
475
+ next unless (entries = err_types[handler.name])
476
+
477
+ handler_job = subjobs_add(
478
+ "#{name} => #{handler.name}",
479
+ usecase: handler
480
+ )
481
+
482
+ msg = "Running error handler #{handler.name}"
483
+ msg << " (against #{entries.count} entries)"
484
+ log(:debug) { msg }
485
+
486
+ handler.launch(
487
+ people: people(entries),
488
+ session: session,
489
+ options: options,
490
+ job: handler_job
491
+ )
492
+
493
+ log(:debug) {
494
+ "Launching job of error handler: #{handler_job.name}"
495
+ }
496
+
497
+ handler_job.launch(simulate: false)
383
498
  end
384
499
  end
385
500
 
@@ -387,7 +502,7 @@ module Eco
387
502
  def backup_update(requests, simulate: false)
388
503
  dry_run = simulate ? "_dry_run" : ""
389
504
  dir = config.people.requests_folder
390
- filename = name.split(" ").join("-").gsub(/[=\\\/><,"-]+/,"_")
505
+ filename = name.split(" ").join("-").gsub(/[=\\\/><,"-]+/, "_") # rubocop:disable Style/RedundantArgument
391
506
  file = File.join(dir, "#{type}_data_#{filename}#{dry_run}.json")
392
507
  file_manager.save_json(requests, file, :timestamp)
393
508
  end
@@ -404,3 +519,5 @@ module Eco
404
519
  end
405
520
  end
406
521
  end
522
+
523
+ # rubocop:enable Naming/MethodParameterName