3scale_toolbox 0.18.3 → 0.19.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/3scale_toolbox.gemspec +3 -3
  3. data/README.md +1 -2
  4. data/lib/3scale_toolbox/commands/backend_command/copy_command/delete_mapping_rules_task.rb +18 -0
  5. data/lib/3scale_toolbox/commands/backend_command/copy_command/task.rb +4 -0
  6. data/lib/3scale_toolbox/commands/backend_command/copy_command.rb +4 -1
  7. data/lib/3scale_toolbox/commands/import_command/import_csv.rb +8 -8
  8. data/lib/3scale_toolbox/commands/import_command/openapi/create_activedocs_step.rb +1 -1
  9. data/lib/3scale_toolbox/commands/import_command/openapi/update_policies_step.rb +23 -10
  10. data/lib/3scale_toolbox/commands/import_command/openapi.rb +2 -0
  11. data/lib/3scale_toolbox/commands/plans_command/export_command.rb +52 -29
  12. data/lib/3scale_toolbox/commands/plans_command/import/import_backend_metrics_step.rb +37 -0
  13. data/lib/3scale_toolbox/commands/plans_command/import/import_plan_limits_step.rb +11 -2
  14. data/lib/3scale_toolbox/commands/plans_command/import/import_plan_metrics_step.rb +2 -2
  15. data/lib/3scale_toolbox/commands/plans_command/import/import_plan_pricing_rules_step.rb +12 -1
  16. data/lib/3scale_toolbox/commands/plans_command/import/step.rb +23 -8
  17. data/lib/3scale_toolbox/commands/plans_command/import/validate_plan_step.rb +126 -0
  18. data/lib/3scale_toolbox/commands/plans_command/import_command.rb +5 -1
  19. data/lib/3scale_toolbox/commands/product_command/copy_command/copy_backends_task.rb +6 -0
  20. data/lib/3scale_toolbox/commands/product_command/copy_command.rb +3 -2
  21. data/lib/3scale_toolbox/commands/product_command/import_command.rb +1 -0
  22. data/lib/3scale_toolbox/crds/limit_dump.rb +1 -1
  23. data/lib/3scale_toolbox/crds/pricing_rule_dump.rb +1 -1
  24. data/lib/3scale_toolbox/entities/application_plan.rb +64 -0
  25. data/lib/3scale_toolbox/entities/backend.rb +4 -0
  26. data/lib/3scale_toolbox/entities/backend_method.rb +16 -0
  27. data/lib/3scale_toolbox/entities/backend_metric.rb +16 -0
  28. data/lib/3scale_toolbox/entities/limit.rb +52 -7
  29. data/lib/3scale_toolbox/entities/method.rb +11 -0
  30. data/lib/3scale_toolbox/entities/metric.rb +12 -0
  31. data/lib/3scale_toolbox/entities/pricing_rule.rb +52 -7
  32. data/lib/3scale_toolbox/entities/service.rb +4 -0
  33. data/lib/3scale_toolbox/proxy_logger.rb +2 -0
  34. data/lib/3scale_toolbox/remote_cache.rb +49 -2
  35. data/lib/3scale_toolbox/version.rb +1 -1
  36. data/licenses.xml +15 -25
  37. metadata +8 -13
  38. data/lib/3scale_toolbox/commands/plans_command/export/read_app_plan_step.rb +0 -16
  39. data/lib/3scale_toolbox/commands/plans_command/export/read_plan_features_step.rb +0 -16
  40. data/lib/3scale_toolbox/commands/plans_command/export/read_plan_limits_step.rb +0 -19
  41. data/lib/3scale_toolbox/commands/plans_command/export/read_plan_methods_step.rb +0 -47
  42. data/lib/3scale_toolbox/commands/plans_command/export/read_plan_metrics_step.rb +0 -47
  43. data/lib/3scale_toolbox/commands/plans_command/export/read_plan_pricing_rules_step.rb +0 -19
  44. data/lib/3scale_toolbox/commands/plans_command/export/step.rb +0 -85
  45. data/lib/3scale_toolbox/commands/plans_command/export/write_artifacts_file_step.rb +0 -84
@@ -14,13 +14,13 @@ module ThreeScaleToolbox
14
14
  summary 'Copy product'
15
15
  description <<-HEREDOC
16
16
  This command makes a copy of the referenced product.
17
- Target product will be searched by source product system name. System name can be overriden with `--target-system-name` option.
17
+ Target product will be searched by the source product system name. System name can be overridden with `--target-system-name` option.
18
18
  If a product with the selected `system_name` is not found, it will be created.
19
19
  \n Components of the product being copied:
20
20
  \nproduct configuration
21
21
  \nproduct settings
22
22
  \nproduct methods&metrics: Only missing metrics&methods will be created.
23
- \nproduct mapping rules: Only missing mapping rules will be created.
23
+ \nproduct mapping rules: mapping rules will be replaced. Existing mapping rules will be removed.
24
24
  \nproduct application plans & pricing rules & limits: Only missing application plans & pricing rules & limits will be created.
25
25
  \nproduct application usage rules
26
26
  \nproduct policies
@@ -73,6 +73,7 @@ module ThreeScaleToolbox
73
73
  source_remote: threescale_client(fetch_required_option(:source)),
74
74
  target_remote: threescale_client(fetch_required_option(:destination)),
75
75
  source_service_ref: arguments[:source_product],
76
+ delete_mapping_rules: true,
76
77
  option_target_system_name: options[:'target-system-name']
77
78
  }
78
79
  end
@@ -28,6 +28,7 @@ module ThreeScaleToolbox
28
28
  target_remote: remote,
29
29
  source_remote: crd_remote,
30
30
  source_service_ref: product.system_name,
31
+ delete_mapping_rules: true,
31
32
  logger: Logger.new(File::NULL)
32
33
  }
33
34
 
@@ -18,7 +18,7 @@ module ThreeScaleToolbox
18
18
  { 'systemName' => method.system_name }
19
19
  elsif (metric = plan.service.metrics.find { |m| m.id == metric_id })
20
20
  { 'systemName' => metric.system_name }
21
- elsif (backend = backend_from_metric)
21
+ elsif (backend = backend_from_metric_link)
22
22
  if (backend_metric = backend.metrics.find { |m| m.id == metric_id })
23
23
  { 'systemName' => backend_metric.system_name, 'backend' => backend.system_name }
24
24
  elsif (backend_method = backend.methods.find { |m| m.id == metric_id })
@@ -19,7 +19,7 @@ module ThreeScaleToolbox
19
19
  { 'systemName' => method.system_name }
20
20
  elsif (metric = plan.service.metrics.find { |m| m.id == metric_id })
21
21
  { 'systemName' => metric.system_name }
22
- elsif (backend = backend_from_metric)
22
+ elsif (backend = backend_from_metric_link)
23
23
  if (backend_metric = backend.metrics.find { |m| m.id == metric_id })
24
24
  { 'systemName' => backend_metric.system_name, 'backend' => backend.system_name }
25
25
  elsif (backend_method = backend.methods.find { |m| m.id == metric_id })
@@ -3,6 +3,9 @@ module ThreeScaleToolbox
3
3
  class ApplicationPlan
4
4
  include CRD::ApplicationPlanSerializer
5
5
 
6
+ APP_PLANS_BLACKLIST = %w[id links default custom created_at updated_at].freeze
7
+ PLAN_FEATURE_BLACKLIST = %w[id links created_at updated_at].freeze
8
+
6
9
  class << self
7
10
  def create(service:, plan_attrs:)
8
11
  plan = service.remote.create_application_plan service.id, create_plan_attrs(plan_attrs)
@@ -209,8 +212,69 @@ module ThreeScaleToolbox
209
212
  attrs.fetch('cost_per_month', 0.0)
210
213
  end
211
214
 
215
+ def to_hash
216
+ {
217
+ 'plan' => attrs.reject { |key, _| APP_PLANS_BLACKLIST.include? key },
218
+ 'limits' => limits.map(&:to_hash),
219
+ 'pricingrules' => pricing_rules.map(&:to_hash),
220
+ 'plan_features' => features.map do |feature|
221
+ feature.reject { |key, _| PLAN_FEATURE_BLACKLIST.include? key }
222
+ end,
223
+ 'metrics' => uniq_metrics_to_hash,
224
+ 'methods' => uniq_methods_to_hash,
225
+ }
226
+ end
227
+
212
228
  private
213
229
 
230
+ def uniq_metrics_to_hash
231
+ limit_metrics = limits.flat_map do |limit|
232
+ # one of them (or both) could be nil
233
+ [
234
+ limit.product_metric, limit.backend_metric
235
+ ]
236
+ end.compact
237
+
238
+ pr_metrics = pricing_rules.flat_map do |pr|
239
+ # one of them (or both) could be nil
240
+ [
241
+ pr.product_metric, pr.backend_metric
242
+ ]
243
+ end.compact
244
+
245
+ # multiple limits can reference the same metric
246
+ # multiple pricing rules can reference the same metric
247
+ uniq_metrics = limit_metrics.concat(pr_metrics).each_with_object({}) do |metric, acc|
248
+ acc[metric.enriched_key] = metric
249
+ end.values
250
+
251
+ uniq_metrics.map { |metric| metric.to_hash }
252
+ end
253
+
254
+ def uniq_methods_to_hash
255
+ limit_methods = limits.flat_map do |limit|
256
+ # one of them (or both) could be nil
257
+ [
258
+ limit.product_method, limit.backend_method
259
+ ]
260
+ end.compact
261
+
262
+ pr_methods = pricing_rules.flat_map do |pr|
263
+ # one of them (or both) could be nil
264
+ [
265
+ pr.product_method, pr.backend_method
266
+ ]
267
+ end.compact
268
+
269
+ # multiple limits can reference the same method
270
+ # multiple pricing rules can reference the same method
271
+ uniq_methods = limit_methods.concat(pr_methods).each_with_object({}) do |method, acc|
272
+ acc[method.enriched_key] = method
273
+ end.values
274
+
275
+ uniq_methods.map { |method| method.to_hash }
276
+ end
277
+
214
278
  def read_plan_attrs
215
279
  raise ThreeScaleToolbox::InvalidIdError if id.zero?
216
280
 
@@ -161,6 +161,10 @@ module ThreeScaleToolbox
161
161
  remote.http_client.endpoint == other.remote.http_client.endpoint && id == other.id
162
162
  end
163
163
 
164
+ def find_metric_or_method(system_name)
165
+ (metrics + methods).find { |m| m.system_name == system_name }
166
+ end
167
+
164
168
  private
165
169
 
166
170
  def metrics_and_methods
@@ -6,6 +6,8 @@ module ThreeScaleToolbox
6
6
  VALID_PARAMS = %w[friendly_name system_name description].freeze
7
7
  public_constant :VALID_PARAMS
8
8
 
9
+ METHOD_BLACKLIST = %w[id links created_at updated_at parent_id].freeze
10
+
9
11
  class << self
10
12
  def create(backend:, attrs:)
11
13
  method = backend.remote.create_backend_method(backend.id, backend.hits.id,
@@ -71,6 +73,20 @@ module ThreeScaleToolbox
71
73
  remote.delete_backend_method backend.id, hits_id, id
72
74
  end
73
75
 
76
+ # enriched_key returns a metric key that will be unique for all
77
+ # metrics/methods from products and backends
78
+ def enriched_key
79
+ "backend.#{backend.id}.#{id}"
80
+ end
81
+
82
+ def to_hash
83
+ extra_attrs = {
84
+ 'backend_system_name' => backend.system_name
85
+ }
86
+
87
+ attrs.merge(extra_attrs).reject { |key, _| METHOD_BLACKLIST.include? key }
88
+ end
89
+
74
90
  private
75
91
 
76
92
  def hits_id
@@ -6,6 +6,8 @@ module ThreeScaleToolbox
6
6
  VALID_PARAMS = %w[friendly_name system_name unit description].freeze
7
7
  public_constant :VALID_PARAMS
8
8
 
9
+ METRIC_BLACKLIST = %w[id links created_at updated_at].freeze
10
+
9
11
  class << self
10
12
  def create(backend:, attrs:)
11
13
  metric = backend.remote.create_backend_metric(backend.id,
@@ -74,6 +76,20 @@ module ThreeScaleToolbox
74
76
  remote.delete_backend_metric backend.id, id
75
77
  end
76
78
 
79
+ # enriched_key returns a metric key that will be unique for all
80
+ # metrics from products and backends
81
+ def enriched_key
82
+ "backend.#{backend.id}.#{id}"
83
+ end
84
+
85
+ def to_hash
86
+ extra_attrs = {
87
+ 'backend_system_name' => backend.system_name
88
+ }
89
+
90
+ attrs.merge(extra_attrs).reject { |key, _| METRIC_BLACKLIST.include? key }
91
+ end
92
+
77
93
  private
78
94
 
79
95
  def process_attrs(metric_attrs)
@@ -3,6 +3,8 @@ module ThreeScaleToolbox
3
3
  class Limit
4
4
  include CRD::Limit
5
5
 
6
+ LIMITS_BLACKLIST = %w[id metric_id plan_id links created_at updated_at].freeze
7
+
6
8
  class << self
7
9
  def create(plan:, metric_id:, attrs:)
8
10
  resp_attrs = plan.remote.create_application_plan_limit plan.id, metric_id, attrs
@@ -37,7 +39,7 @@ module ThreeScaleToolbox
37
39
  end
38
40
 
39
41
  def metric_link
40
- links.find { |link| link['rel'] == 'metric' }
42
+ links.find { |link| link['rel'] == 'metric' } || {}
41
43
  end
42
44
 
43
45
  def update(new_limit_attrs)
@@ -56,15 +58,58 @@ module ThreeScaleToolbox
56
58
  remote.delete_application_plan_limit plan.id, metric_id, id
57
59
  end
58
60
 
61
+ def product_metric
62
+ plan.service.metrics.find { |m| m.id == metric_id }
63
+ end
64
+
65
+ def product_method
66
+ plan.service.methods.find { |m| m.id == metric_id }
67
+ end
68
+
69
+ def backend_metric
70
+ if (backend = backend_from_metric_link)
71
+ return backend.metrics.find { |m| m.id == metric_id }
72
+ end
73
+ end
74
+
75
+ def backend_method
76
+ if (backend = backend_from_metric_link)
77
+ return backend.methods.find { |m| m.id == metric_id }
78
+ end
79
+ end
80
+
81
+ def to_hash
82
+ extra_attrs = {}
83
+
84
+ if (metric = product_metric)
85
+ extra_attrs['metric_system_name'] = metric.system_name
86
+ elsif (method = product_method)
87
+ extra_attrs['metric_system_name'] = method.system_name
88
+ elsif (metric = backend_metric)
89
+ extra_attrs['metric_system_name'] = metric.system_name
90
+ extra_attrs['metric_backend_system_name'] = metric.backend.system_name
91
+ elsif (method = backend_method)
92
+ extra_attrs['metric_system_name'] = method.system_name
93
+ extra_attrs['metric_backend_system_name'] = method.backend.system_name
94
+ else
95
+ raise_metric_not_found
96
+ end
97
+
98
+ attrs.merge(extra_attrs).reject { |key, _| LIMITS_BLACKLIST.include? key }
99
+ end
100
+
59
101
  private
60
102
 
61
- # Used by CRD::Limit
62
- # Returns the backend hosting the metric
63
- def backend_from_metric
64
- backend_id = Helper.backend_metric_link_parser(metric_link['href'] || '')
65
- return if backend_id.nil?
103
+ def raise_metric_not_found
104
+ raise ThreeScaleToolbox::Error, "Unexpected error. Limit #{id} " \
105
+ "referencing to metric id #{metric_id} which has not been found"
106
+ end
66
107
 
67
- Backend.new(id: backend_id.to_i, remote: remote)
108
+ # Returns the backend hosting the metric
109
+ def backend_from_metric_link
110
+ if (backend_id = Helper.backend_metric_link_parser(metric_link['href'] || ''))
111
+ return Backend.new(id: backend_id.to_i, remote: remote)
112
+ end
68
113
  end
69
114
  end
70
115
  end
@@ -3,6 +3,8 @@ module ThreeScaleToolbox
3
3
  class Method
4
4
  include CRD::MethodSerializer
5
5
 
6
+ METHOD_BLACKLIST = %w[id links created_at updated_at parent_id].freeze
7
+
6
8
  class << self
7
9
  def create(service:, attrs:)
8
10
  method_attrs = service.remote.create_method service.id, service.hits.id, attrs
@@ -74,6 +76,15 @@ module ThreeScaleToolbox
74
76
  remote.delete_method service.id, hits_id, id
75
77
  end
76
78
 
79
+ # enriched_key returns a metric key that will be unique for all
80
+ # metrics/methods from products and backends
81
+ def enriched_key
82
+ "product.#{service.id}.#{id}"
83
+ end
84
+
85
+ def to_hash
86
+ attrs.reject { |key, _| METHOD_BLACKLIST.include? key }
87
+ end
77
88
 
78
89
  private
79
90
 
@@ -3,6 +3,8 @@ module ThreeScaleToolbox
3
3
  class Metric
4
4
  include CRD::MetricSerializer
5
5
 
6
+ METRIC_BLACKLIST = %w[id links created_at updated_at].freeze
7
+
6
8
  class << self
7
9
  def create(service:, attrs:)
8
10
  metric = service.remote.create_metric service.id, attrs
@@ -92,6 +94,16 @@ module ThreeScaleToolbox
92
94
  remote.delete_metric service.id, id
93
95
  end
94
96
 
97
+ # enriched_key returns a metric key that will be unique for all
98
+ # metrics from products and backends
99
+ def enriched_key
100
+ "product.#{service.id}.#{id}"
101
+ end
102
+
103
+ def to_hash
104
+ attrs.reject { |key, _| METRIC_BLACKLIST.include? key }
105
+ end
106
+
95
107
  private
96
108
 
97
109
  def metric_attrs
@@ -3,6 +3,8 @@ module ThreeScaleToolbox
3
3
  class PricingRule
4
4
  include CRD::PricingRuleSerializer
5
5
 
6
+ PRICINGRULES_BLACKLIST = %w[id metric_id plan_id links created_at updated_at].freeze
7
+
6
8
  class << self
7
9
  def create(plan:, metric_id:, attrs:)
8
10
  resp_attrs = plan.remote.create_pricingrule plan.id, metric_id, attrs
@@ -41,22 +43,65 @@ module ThreeScaleToolbox
41
43
  end
42
44
 
43
45
  def metric_link
44
- links.find { |link| link['rel'] == 'metric' }
46
+ links.find { |link| link['rel'] == 'metric' } || {}
45
47
  end
46
48
 
47
49
  def delete
48
50
  remote.delete_application_plan_pricingrule plan.id, metric_id, id
49
51
  end
50
52
 
53
+ def product_metric
54
+ plan.service.metrics.find { |m| m.id == metric_id }
55
+ end
56
+
57
+ def product_method
58
+ plan.service.methods.find { |m| m.id == metric_id }
59
+ end
60
+
61
+ def backend_metric
62
+ if (backend = backend_from_metric_link)
63
+ return backend.metrics.find { |m| m.id == metric_id }
64
+ end
65
+ end
66
+
67
+ def backend_method
68
+ if (backend = backend_from_metric_link)
69
+ return backend.methods.find { |m| m.id == metric_id }
70
+ end
71
+ end
72
+
73
+ def to_hash
74
+ extra_attrs = {}
75
+
76
+ if (metric = product_metric)
77
+ extra_attrs['metric_system_name'] = metric.system_name
78
+ elsif (method = product_method)
79
+ extra_attrs['metric_system_name'] = method.system_name
80
+ elsif (metric = backend_metric)
81
+ extra_attrs['metric_system_name'] = metric.system_name
82
+ extra_attrs['metric_backend_system_name'] = metric.backend.system_name
83
+ elsif (method = backend_method)
84
+ extra_attrs['metric_system_name'] = method.system_name
85
+ extra_attrs['metric_backend_system_name'] = method.backend.system_name
86
+ else
87
+ raise_method_not_found
88
+ end
89
+
90
+ attrs.merge(extra_attrs).reject { |key, _| PRICINGRULES_BLACKLIST.include? key }
91
+ end
92
+
51
93
  private
52
94
 
53
- # Used by CRD::PricingRule
54
- # Returns the backend hosting the metric
55
- def backend_from_metric
56
- backend_id = Helper.backend_metric_link_parser(metric_link['href'] || '')
57
- return if backend_id.nil?
95
+ def raise_method_not_found
96
+ raise ThreeScaleToolbox::Error, "Unexpected error. Pricing Rule #{id} " \
97
+ "referencing to metric id #{metric_id} which has not been found"
98
+ end
58
99
 
59
- Backend.new(id: backend_id.to_i, remote: remote)
100
+ # Returns the backend hosting the metric
101
+ def backend_from_metric_link
102
+ if (backend_id = Helper.backend_metric_link_parser(metric_link['href'] || ''))
103
+ return Backend.new(id: backend_id.to_i, remote: remote)
104
+ end
60
105
  end
61
106
  end
62
107
  end
@@ -367,6 +367,10 @@ module ThreeScaleToolbox
367
367
  remote.http_client.endpoint == other.remote.http_client.endpoint && id == other.id
368
368
  end
369
369
 
370
+ def find_metric_or_method(system_name)
371
+ (metrics + methods).find { |m| m.system_name == system_name }
372
+ end
373
+
370
374
  private
371
375
 
372
376
  def fetch_attrs
@@ -5,6 +5,7 @@ module ThreeScaleToolbox
5
5
  end
6
6
 
7
7
  def method_missing(name, *args)
8
+ # Correct delegation https://eregon.me/blog/2021/02/13/correct-delegation-in-ruby-2-27-3.html
8
9
  start_time = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
9
10
  result = @subject.public_send(name, *args)
10
11
  ensure
@@ -12,6 +13,7 @@ module ThreeScaleToolbox
12
13
  ::Kernel.warn "-- call #{name} args |#{args.inspect[0..2000]}| response |#{result.inspect[0..2000]}| - (#{end_time}s)"
13
14
  result
14
15
  end
16
+ ruby2_keywords :method_missing if respond_to?(:ruby2_keywords, true)
15
17
 
16
18
  def public_send(name, *args)
17
19
  method_missing(name, *args)
@@ -1,7 +1,10 @@
1
1
  module ThreeScaleToolbox
2
2
  class RemoteCache < BasicObject
3
3
 
4
- attr_reader :metrics_cache, :methods_cache, :backend_metrics_cache, :backend_methods_cache, :subject
4
+ attr_reader :metrics_cache, :methods_cache,
5
+ :backend_metrics_cache, :backend_methods_cache,
6
+ :backends_cache,
7
+ :subject
5
8
 
6
9
  def initialize(subject)
7
10
  @subject = subject
@@ -13,6 +16,8 @@ module ThreeScaleToolbox
13
16
  @backend_metrics_cache = {}
14
17
  # Backend methods cache data
15
18
  @backend_methods_cache = {}
19
+ # Backends cache data
20
+ @backends_cache = {}
16
21
  end
17
22
 
18
23
  def list_metrics(service_id)
@@ -136,12 +141,54 @@ module ThreeScaleToolbox
136
141
  end
137
142
  end
138
143
 
144
+ def list_backends(params = nil)
145
+ return backends_cache[params] if backends_cache.has_key? params
146
+
147
+ subject.list_backends(params).tap do |backends|
148
+ backends_cache[params] = backends unless backends.respond_to?(:has_key?) && !backends['errors'].nil?
149
+ end
150
+ end
151
+
152
+ def create_backend(attributes)
153
+ subject.create_backend(attributes).tap do |backend_attrs|
154
+ backends_cache.clear unless backend_attrs.respond_to?(:has_key?) && !backend_attrs['errors'].nil?
155
+ end
156
+ end
157
+
158
+ def update_backend(id, attributes)
159
+ subject.update_backend(id, attributes).tap do |backend_attrs|
160
+ backends_cache.clear unless backend_attrs.respond_to?(:has_key?) && !backend_attrs['errors'].nil?
161
+ end
162
+ end
163
+
164
+ def delete_backend(id)
165
+ subject.delete_backend(id).tap do |resp|
166
+ backends_cache.clear unless resp.respond_to?(:has_key?) && !resp['errors'].nil?
167
+ end
168
+ end
169
+
170
+ def backend(id)
171
+ # if exist in the cache, return it.
172
+ # But if not, it is not populated because cache is paginated and page is unknown.
173
+ if (backend_attrs = backends_cache.values.reduce([], :concat).find { |attrs| attrs['id'] == id })
174
+ return backend_attrs
175
+ end
176
+
177
+ subject.backend(id)
178
+ end
179
+
139
180
  ###
140
181
  # Generic methods
141
182
  ###
142
183
 
143
184
  def method_missing(name, *args)
144
- subject.public_send(name, *args)
185
+ # Correct delegation https://eregon.me/blog/2021/02/13/correct-delegation-in-ruby-2-27-3.html
186
+ @subject.public_send(name, *args)
187
+ end
188
+ ruby2_keywords :method_missing if respond_to?(:ruby2_keywords, true)
189
+
190
+ def public_send(name, *args)
191
+ method_missing(name, *args)
145
192
  end
146
193
 
147
194
  def respond_to_missing?(method_name, include_private = false)
@@ -1,3 +1,3 @@
1
1
  module ThreeScaleToolbox
2
- VERSION = '0.18.3'
2
+ VERSION = '0.19.3'
3
3
  end
data/licenses.xml CHANGED
@@ -13,7 +13,7 @@
13
13
  </dependency>
14
14
  <dependency>
15
15
  <packageName>3scale_toolbox</packageName>
16
- <version>0.18.3</version>
16
+ <version>0.19.3</version>
17
17
  <licenses>
18
18
  <license>
19
19
  <name>MIT</name>
@@ -23,7 +23,7 @@
23
23
  </dependency>
24
24
  <dependency>
25
25
  <packageName>activesupport</packageName>
26
- <version>6.1.3.2</version>
26
+ <version>6.1.4.1</version>
27
27
  <licenses>
28
28
  <license>
29
29
  <name>MIT</name>
@@ -33,7 +33,7 @@
33
33
  </dependency>
34
34
  <dependency>
35
35
  <packageName>addressable</packageName>
36
- <version>2.7.0</version>
36
+ <version>2.8.0</version>
37
37
  <licenses>
38
38
  <license>
39
39
  <name>Apache 2.0</name>
@@ -53,7 +53,7 @@
53
53
  </dependency>
54
54
  <dependency>
55
55
  <packageName>bundler</packageName>
56
- <version>2.1.4</version>
56
+ <version>2.2.21</version>
57
57
  <licenses>
58
58
  <license>
59
59
  <name>MIT</name>
@@ -63,7 +63,7 @@
63
63
  </dependency>
64
64
  <dependency>
65
65
  <packageName>codecov</packageName>
66
- <version>0.5.1</version>
66
+ <version>0.5.2</version>
67
67
  <licenses>
68
68
  <license>
69
69
  <name>MIT</name>
@@ -141,7 +141,7 @@
141
141
  </dependency>
142
142
  <dependency>
143
143
  <packageName>docile</packageName>
144
- <version>1.3.5</version>
144
+ <version>1.4.0</version>
145
145
  <licenses>
146
146
  <license>
147
147
  <name>MIT</name>
@@ -228,16 +228,6 @@
228
228
  <url>http://opensource.org/licenses/mit-license</url>
229
229
  </license>
230
230
  </licenses>
231
- </dependency>
232
- <dependency>
233
- <packageName>mini_portile2</packageName>
234
- <version>2.5.3</version>
235
- <licenses>
236
- <license>
237
- <name>MIT</name>
238
- <url>http://opensource.org/licenses/mit-license</url>
239
- </license>
240
- </licenses>
241
231
  </dependency>
242
232
  <dependency>
243
233
  <packageName>minitest</packageName>
@@ -271,7 +261,7 @@
271
261
  </dependency>
272
262
  <dependency>
273
263
  <packageName>nokogiri</packageName>
274
- <version>1.11.7</version>
264
+ <version>1.12.5</version>
275
265
  <licenses>
276
266
  <license>
277
267
  <name>MIT</name>
@@ -301,7 +291,7 @@
301
291
  </dependency>
302
292
  <dependency>
303
293
  <packageName>pry</packageName>
304
- <version>0.13.1</version>
294
+ <version>0.14.1</version>
305
295
  <licenses>
306
296
  <license>
307
297
  <name>MIT</name>
@@ -321,7 +311,7 @@
321
311
  </dependency>
322
312
  <dependency>
323
313
  <packageName>racc</packageName>
324
- <version>1.5.2</version>
314
+ <version>1.6.0</version>
325
315
  <licenses>
326
316
  <license>
327
317
  <name>ruby</name>
@@ -385,7 +375,7 @@
385
375
  </dependency>
386
376
  <dependency>
387
377
  <packageName>rspec-mocks</packageName>
388
- <version>3.10.1</version>
378
+ <version>3.10.2</version>
389
379
  <licenses>
390
380
  <license>
391
381
  <name>MIT</name>
@@ -395,7 +385,7 @@
395
385
  </dependency>
396
386
  <dependency>
397
387
  <packageName>rspec-support</packageName>
398
- <version>3.10.1</version>
388
+ <version>3.10.2</version>
399
389
  <licenses>
400
390
  <license>
401
391
  <name>MIT</name>
@@ -405,7 +395,7 @@
405
395
  </dependency>
406
396
  <dependency>
407
397
  <packageName>ruby2_keywords</packageName>
408
- <version>0.0.4</version>
398
+ <version>0.0.5</version>
409
399
  <licenses>
410
400
  <license>
411
401
  <name>ruby</name>
@@ -449,7 +439,7 @@
449
439
  </dependency>
450
440
  <dependency>
451
441
  <packageName>simplecov_json_formatter</packageName>
452
- <version>0.1.2</version>
442
+ <version>0.1.3</version>
453
443
  <licenses>
454
444
  <license>
455
445
  <name>MIT</name>
@@ -489,7 +479,7 @@
489
479
  </dependency>
490
480
  <dependency>
491
481
  <packageName>webmock</packageName>
492
- <version>3.11.1</version>
482
+ <version>3.13.0</version>
493
483
  <licenses>
494
484
  <license>
495
485
  <name>MIT</name>
@@ -519,7 +509,7 @@
519
509
  </dependency>
520
510
  <dependency>
521
511
  <packageName>zeitwerk</packageName>
522
- <version>2.4.2</version>
512
+ <version>2.5.1</version>
523
513
  <licenses>
524
514
  <license>
525
515
  <name>MIT</name>