3scale_toolbox 0.17.1 → 0.18.0

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.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/3scale_toolbox.gemspec +1 -1
  3. data/README.md +6 -3
  4. data/lib/3scale_toolbox.rb +3 -0
  5. data/lib/3scale_toolbox/3scale_client_factory.rb +3 -4
  6. data/lib/3scale_toolbox/commands.rb +2 -0
  7. data/lib/3scale_toolbox/commands/backend_command/copy_command/copy_mapping_rules_task.rb +11 -27
  8. data/lib/3scale_toolbox/commands/backend_command/copy_command/copy_methods_task.rb +5 -10
  9. data/lib/3scale_toolbox/commands/backend_command/copy_command/copy_metrics_task.rb +4 -4
  10. data/lib/3scale_toolbox/commands/backend_command/copy_command/create_or_update_target_backend_task.rb +3 -2
  11. data/lib/3scale_toolbox/commands/backend_command/copy_command/task.rb +10 -32
  12. data/lib/3scale_toolbox/commands/import_command/issuer_type_transformer.rb +16 -0
  13. data/lib/3scale_toolbox/commands/import_command/openapi.rb +3 -0
  14. data/lib/3scale_toolbox/commands/import_command/openapi/create_mapping_rule_step.rb +2 -1
  15. data/lib/3scale_toolbox/commands/import_command/openapi/create_method_step.rb +3 -12
  16. data/lib/3scale_toolbox/commands/import_command/openapi/step.rb +4 -0
  17. data/lib/3scale_toolbox/commands/import_command/openapi/update_service_proxy_step.rb +1 -0
  18. data/lib/3scale_toolbox/commands/methods_command/apply_command.rb +2 -4
  19. data/lib/3scale_toolbox/commands/methods_command/create_command.rb +0 -2
  20. data/lib/3scale_toolbox/commands/methods_command/delete_command.rb +1 -1
  21. data/lib/3scale_toolbox/commands/methods_command/list_command.rb +1 -9
  22. data/lib/3scale_toolbox/commands/metrics_command/list_command.rb +1 -1
  23. data/lib/3scale_toolbox/commands/plans_command/export/read_plan_limits_step.rb +1 -1
  24. data/lib/3scale_toolbox/commands/plans_command/export/read_plan_methods_step.rb +2 -2
  25. data/lib/3scale_toolbox/commands/plans_command/export/read_plan_metrics_step.rb +2 -2
  26. data/lib/3scale_toolbox/commands/plans_command/export/read_plan_pricing_rules_step.rb +1 -2
  27. data/lib/3scale_toolbox/commands/plans_command/export/step.rb +8 -20
  28. data/lib/3scale_toolbox/commands/plans_command/import/import_plan_limits_step.rb +7 -8
  29. data/lib/3scale_toolbox/commands/plans_command/import/import_plan_metrics_step.rb +6 -13
  30. data/lib/3scale_toolbox/commands/plans_command/import/import_plan_pricing_rules_step.rb +8 -15
  31. data/lib/3scale_toolbox/commands/plans_command/import/step.rb +2 -22
  32. data/lib/3scale_toolbox/commands/plans_command/list_command.rb +1 -1
  33. data/lib/3scale_toolbox/commands/plans_command/show_command.rb +1 -1
  34. data/lib/3scale_toolbox/commands/policies_command.rb +24 -0
  35. data/lib/3scale_toolbox/commands/policies_command/export_command.rb +98 -0
  36. data/lib/3scale_toolbox/commands/policies_command/import_command.rb +61 -0
  37. data/lib/3scale_toolbox/commands/product_command.rb +4 -0
  38. data/lib/3scale_toolbox/commands/product_command/copy_command.rb +7 -3
  39. data/lib/3scale_toolbox/commands/product_command/copy_command/copy_backends_task.rb +22 -5
  40. data/lib/3scale_toolbox/commands/product_command/export_command.rb +81 -0
  41. data/lib/3scale_toolbox/commands/product_command/import_command.rb +125 -0
  42. data/lib/3scale_toolbox/commands/proxy_config_command.rb +2 -0
  43. data/lib/3scale_toolbox/commands/proxy_config_command/deploy_command.rb +54 -0
  44. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_activedocs_task.rb +15 -12
  45. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_app_plans_task.rb +15 -15
  46. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_limits_task.rb +12 -13
  47. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_mapping_rules_task.rb +11 -11
  48. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_methods_task.rb +8 -9
  49. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_metrics_task.rb +8 -8
  50. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_policies_task.rb +1 -1
  51. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_pricingrules_task.rb +15 -18
  52. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_service_proxy_task.rb +2 -2
  53. data/lib/3scale_toolbox/commands/service_command/copy_command/create_or_update_service_task.rb +2 -1
  54. data/lib/3scale_toolbox/commands/service_command/copy_command/destroy_mapping_rules_task.rb +9 -5
  55. data/lib/3scale_toolbox/commands/service_command/copy_command/task.rb +20 -34
  56. data/lib/3scale_toolbox/commands/update_command/service_command/delete_activedocs_task.rb +1 -3
  57. data/lib/3scale_toolbox/crds.rb +16 -0
  58. data/lib/3scale_toolbox/crds/application_plan_dump.rb +19 -0
  59. data/lib/3scale_toolbox/crds/backend_dump.rb +39 -0
  60. data/lib/3scale_toolbox/crds/backend_mapping_rule_dump.rb +26 -0
  61. data/lib/3scale_toolbox/crds/backend_method_dump.rb +12 -0
  62. data/lib/3scale_toolbox/crds/backend_metric_dump.rb +13 -0
  63. data/lib/3scale_toolbox/crds/backend_parser.rb +55 -0
  64. data/lib/3scale_toolbox/crds/backend_usage_dump.rb +11 -0
  65. data/lib/3scale_toolbox/crds/limit_dump.rb +37 -0
  66. data/lib/3scale_toolbox/crds/mapping_rule_dump.rb +26 -0
  67. data/lib/3scale_toolbox/crds/method_dump.rb +12 -0
  68. data/lib/3scale_toolbox/crds/metric_dump.rb +13 -0
  69. data/lib/3scale_toolbox/crds/pricing_rule_dump.rb +38 -0
  70. data/lib/3scale_toolbox/crds/product_deployment_parser.rb +329 -0
  71. data/lib/3scale_toolbox/crds/product_dump.rb +157 -0
  72. data/lib/3scale_toolbox/crds/product_parser.rb +114 -0
  73. data/lib/3scale_toolbox/crds/remote.rb +682 -0
  74. data/lib/3scale_toolbox/entities.rb +3 -0
  75. data/lib/3scale_toolbox/entities/activedocs.rb +12 -0
  76. data/lib/3scale_toolbox/entities/application_plan.rb +54 -46
  77. data/lib/3scale_toolbox/entities/backend.rb +65 -30
  78. data/lib/3scale_toolbox/entities/backend_mapping_rule.rb +29 -3
  79. data/lib/3scale_toolbox/entities/backend_method.rb +25 -16
  80. data/lib/3scale_toolbox/entities/backend_metric.rb +12 -2
  81. data/lib/3scale_toolbox/entities/backend_usage.rb +7 -1
  82. data/lib/3scale_toolbox/entities/limit.rb +71 -0
  83. data/lib/3scale_toolbox/entities/mapping_rule.rb +90 -0
  84. data/lib/3scale_toolbox/entities/method.rb +33 -19
  85. data/lib/3scale_toolbox/entities/metric.rb +29 -18
  86. data/lib/3scale_toolbox/entities/pricing_rule.rb +63 -0
  87. data/lib/3scale_toolbox/entities/proxy_config.rb +0 -1
  88. data/lib/3scale_toolbox/entities/service.rb +149 -46
  89. data/lib/3scale_toolbox/helper.rb +13 -16
  90. data/lib/3scale_toolbox/proxy_logger.rb +4 -0
  91. data/lib/3scale_toolbox/remote_cache.rb +157 -0
  92. data/lib/3scale_toolbox/remotes.rb +2 -2
  93. data/lib/3scale_toolbox/version.rb +1 -1
  94. data/licenses.xml +58 -50
  95. metadata +33 -6
@@ -52,7 +52,6 @@ module ThreeScaleToolbox
52
52
  end
53
53
  proxy_cfg
54
54
  end
55
-
56
55
  end
57
56
  end
58
57
  end
@@ -1,6 +1,8 @@
1
1
  module ThreeScaleToolbox
2
2
  module Entities
3
3
  class Service
4
+ include CRD::ProductSerializer
5
+
4
6
  VALID_PARAMS = %w[
5
7
  name backend_version deployment_option description
6
8
  system_name end_user_registration_required
@@ -29,16 +31,12 @@ module ThreeScaleToolbox
29
31
  end
30
32
 
31
33
  def find_by_system_name(remote:, system_name:)
32
- service_list = remote.list_services
33
-
34
- if service_list.respond_to?(:has_key?) && (errors = service_list['errors'])
35
- raise ThreeScaleToolbox::ThreeScaleApiError.new('Service list not read', errors)
34
+ attrs = list_services(remote: remote).find do |svc|
35
+ svc['system_name'] == system_name
36
36
  end
37
+ return if attrs.nil?
37
38
 
38
- service_attrs = service_list.find { |svc| svc['system_name'] == system_name }
39
- return if service_attrs.nil?
40
-
41
- new(id: service_attrs.fetch('id'), remote: remote, attrs: service_attrs)
39
+ new(id: attrs.fetch('id'), remote: remote, attrs: attrs)
42
40
  end
43
41
 
44
42
  private
@@ -61,6 +59,36 @@ module ThreeScaleToolbox
61
59
  def filtered_service_params(original_params)
62
60
  Helper.filter_params(VALID_PARAMS, original_params)
63
61
  end
62
+
63
+ def list_services(remote:)
64
+ services_enum(remote: remote).reduce([], :concat)
65
+ end
66
+
67
+ def services_enum(remote:)
68
+ Enumerator.new do |yielder|
69
+ page = 1
70
+ loop do
71
+ list = remote.list_services(
72
+ page: page,
73
+ per_page: ThreeScale::API::MAX_SERVICES_PER_PAGE
74
+ )
75
+
76
+ if list.respond_to?(:has_key?) && (errors = list['errors'])
77
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Service list not read', errors)
78
+ end
79
+
80
+ break if list.nil?
81
+
82
+ yielder << list
83
+
84
+ # The API response does not tell how many pages there are available
85
+ # If one page is not fully filled, it means that it is the last page.
86
+ break if list.length < ThreeScale::API::MAX_SERVICES_PER_PAGE
87
+
88
+ page += 1
89
+ end
90
+ end
91
+ end
64
92
  end
65
93
 
66
94
  attr_reader :id, :remote
@@ -75,6 +103,26 @@ module ThreeScaleToolbox
75
103
  @attrs ||= fetch_attrs
76
104
  end
77
105
 
106
+ def system_name
107
+ attrs['system_name']
108
+ end
109
+
110
+ def name
111
+ attrs['name']
112
+ end
113
+
114
+ def description
115
+ attrs['description']
116
+ end
117
+
118
+ def deployment_option
119
+ attrs['deployment_option']
120
+ end
121
+
122
+ def backend_version
123
+ attrs['backend_version']
124
+ end
125
+
78
126
  def update_proxy(proxy)
79
127
  new_proxy_attrs = remote.update_proxy id, proxy
80
128
 
@@ -94,37 +142,42 @@ module ThreeScaleToolbox
94
142
  proxy_attrs
95
143
  end
96
144
 
145
+ def cached_proxy
146
+ @cached_proxy ||= proxy
147
+ end
148
+
149
+ # @api public
150
+ # @return [List]
97
151
  def metrics
98
- # cache result to reuse
99
- metric_and_method_list = metrics_and_methods
100
- hits_metric_obj = hits_metric(metric_and_method_list)
101
- hits_id = hits_metric_obj.fetch('id')
152
+ metric_attr_list = metrics_and_methods.select { |metric_attrs| metric_attrs['parent_id'].nil? }
102
153
 
103
- ThreeScaleToolbox::Helper.array_difference(metric_and_method_list, methods(hits_id)) do |metric, method|
104
- ThreeScaleToolbox::Helper.compare_hashes(metric, method, %w[id])
154
+ metric_attr_list.map do |metric_attrs|
155
+ Metric.new(id: metric_attrs.fetch('id'), service: self, attrs: metric_attrs)
105
156
  end
106
157
  end
107
158
 
108
159
  def hits
109
- hits_metric(metrics_and_methods)
160
+ metric_list = metrics_and_methods.map do |metric_attrs|
161
+ Metric.new(id: metric_attrs.fetch('id'), service: self, attrs: metric_attrs)
162
+ end
163
+ metric_list.find { |metric| metric.system_name == 'hits' }.tap do |hits_metric|
164
+ raise ThreeScaleToolbox::Error, 'missing hits metric' if hits_metric.nil?
165
+ end
110
166
  end
111
167
 
112
- def methods(parent_metric_id)
113
- service_methods = remote.list_methods id, parent_metric_id
114
- if service_methods.respond_to?(:has_key?) && (errors = service_methods['errors'])
168
+ # @api public
169
+ # @return [List]
170
+ def methods
171
+ method_attr_list = remote.list_methods id, hits.id
172
+ if method_attr_list.respond_to?(:has_key?) && (errors = method_attr_list['errors'])
115
173
  raise ThreeScaleToolbox::ThreeScaleApiError.new('Service methods not read', errors)
116
174
  end
117
175
 
118
- service_methods
119
- end
120
-
121
- def metrics_and_methods
122
- m_m = remote.list_metrics id
123
- if m_m.respond_to?(:has_key?) && (errors = m_m['errors'])
124
- raise ThreeScaleToolbox::ThreeScaleApiError.new('Service metrics not read', errors)
176
+ method_attr_list.map do |method_attrs|
177
+ Method.new(id: method_attrs.fetch('id'),
178
+ service: self,
179
+ attrs: method_attrs)
125
180
  end
126
-
127
- m_m
128
181
  end
129
182
 
130
183
  def plans
@@ -133,19 +186,24 @@ module ThreeScaleToolbox
133
186
  raise ThreeScaleToolbox::ThreeScaleApiError.new('Service plans not read', errors)
134
187
  end
135
188
 
136
- service_plans
189
+ service_plans.map do |plan_attrs|
190
+ ApplicationPlan.new(id: plan_attrs.fetch('id'),
191
+ service: self,
192
+ attrs: plan_attrs)
193
+ end
137
194
  end
138
195
 
139
196
  def mapping_rules
140
- remote.list_mapping_rules id
141
- end
142
-
143
- def delete_mapping_rule(rule_id)
144
- remote.delete_mapping_rule(id, rule_id)
145
- end
197
+ mr_list = remote.list_mapping_rules id
198
+ if mr_list.respond_to?(:has_key?) && (errors = mr_list['errors'])
199
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Service mapping rules not read', errors)
200
+ end
146
201
 
147
- def create_mapping_rule(mapping_rule)
148
- remote.create_mapping_rule id, mapping_rule
202
+ mr_list.map do |mr_attrs|
203
+ MappingRule.new(id: mr_attrs.fetch('id'),
204
+ service: self,
205
+ attrs: mr_attrs)
206
+ end
149
207
  end
150
208
 
151
209
  def update(svc_attrs)
@@ -165,7 +223,12 @@ module ThreeScaleToolbox
165
223
  end
166
224
 
167
225
  def policies
168
- remote.show_policies id
226
+ policy_chain = remote.show_policies id
227
+ if policy_chain.respond_to?(:has_key?) && (errors = policy_chain['errors'])
228
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Service policies not read', errors)
229
+ end
230
+
231
+ policy_chain
169
232
  end
170
233
 
171
234
  def update_policies(params)
@@ -179,8 +242,12 @@ module ThreeScaleToolbox
179
242
  raise ThreeScaleToolbox::ThreeScaleApiError.new('Service activedocs not read', errors)
180
243
  end
181
244
 
182
- tenant_activedocs.select do |activedoc|
183
- activedoc['service_id'] == id
245
+ service_activedocs = tenant_activedocs.select do |activedoc_attrs|
246
+ activedoc_attrs['service_id'] == id
247
+ end
248
+
249
+ service_activedocs.map do |activedoc_attrs|
250
+ Entities::ActiveDocs.new(id: activedoc_attrs.fetch('id'), remote: remote, attrs: activedoc_attrs)
184
251
  end
185
252
  end
186
253
 
@@ -194,6 +261,10 @@ module ThreeScaleToolbox
194
261
  service_oidc
195
262
  end
196
263
 
264
+ def cached_oidc
265
+ @cached_oidc ||= oidc
266
+ end
267
+
197
268
  def update_oidc(oidc_settings)
198
269
  new_oidc = remote.update_oidc(id, oidc_settings)
199
270
 
@@ -262,19 +333,42 @@ module ThreeScaleToolbox
262
333
  end
263
334
  end
264
335
 
265
- def ==(other)
266
- remote.http_client.endpoint == other.remote.http_client.endpoint && id == other.id
336
+ def create_mapping_rule(mr_attrs)
337
+ Entities::MappingRule.create(service: self, attrs: mr_attrs)
267
338
  end
268
339
 
269
- private
340
+ def proxy_deploy
341
+ proxy_attrs = remote.proxy_deploy id
342
+ if proxy_attrs.respond_to?(:has_key?) && (errors = proxy_attrs['errors'])
343
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Proxy configuration not deployed', errors)
344
+ end
345
+
346
+ proxy_attrs
347
+ end
348
+
349
+ # Compute matrics mapping between products, including related backend metrics as well
350
+ def metrics_mapping(other)
351
+ mapping = (metrics + methods).product(other.metrics + other.methods).select do |m_a, m_b|
352
+ m_a.system_name == m_b.system_name
353
+ end.map { |m_a, m_b| [m_a.id, m_b.id] }.to_h
270
354
 
271
- def hits_metric(metric_list)
272
- hits_metric = metric_list.find { |metric| metric['system_name'] == 'hits' }
273
- raise ThreeScaleToolbox::Error, 'missing hits metric' if hits_metric.nil?
355
+ backend_pairs = backend_usage_list.map(&:backend).product(other.backend_usage_list.map(&:backend)).select do |b_a, b_b|
356
+ b_a.system_name == b_b.system_name
357
+ end
358
+
359
+ backend_pairs.each do |b_a, b_b|
360
+ mapping.merge!(b_a.metrics_mapping(b_b))
361
+ end
274
362
 
275
- hits_metric
363
+ mapping
276
364
  end
277
365
 
366
+ def ==(other)
367
+ remote.http_client.endpoint == other.remote.http_client.endpoint && id == other.id
368
+ end
369
+
370
+ private
371
+
278
372
  def fetch_attrs
279
373
  raise ThreeScaleToolbox::InvalidIdError if id.zero?
280
374
 
@@ -300,6 +394,15 @@ module ThreeScaleToolbox
300
394
 
301
395
  new_attrs
302
396
  end
397
+
398
+ def metrics_and_methods
399
+ m_m = remote.list_metrics id
400
+ if m_m.respond_to?(:has_key?) && (errors = m_m['errors'])
401
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Service metrics not read', errors)
402
+ end
403
+
404
+ m_m
405
+ end
303
406
  end
304
407
  end
305
408
  end
@@ -51,24 +51,21 @@ module ThreeScaleToolbox
51
51
  Array(Hash(error)['period']).any? { |msg| msg.match(/has already been taken/) }
52
52
  end
53
53
 
54
- def metrics_mapping(source_metrics, target_metrics)
55
- target_metrics.map do |target|
56
- source = source_metrics.find do |m|
57
- compare_hashes(m, target, ['system_name'])
58
- end || {}
59
-
60
- [source['id'], target['id']]
61
- end.to_h
54
+ def application_plan_mapping(source_app_plans, target_app_plans)
55
+ target_app_plans.map do |target|
56
+ source = source_app_plans.find { |app_plan| app_plan.system_name == target.system_name }
57
+ [source, target]
58
+ end.reject { |key, _| key.nil? }
62
59
  end
63
60
 
64
- def application_plan_mapping(source_app_plans, target_app_plans)
65
- mapping = target_app_plans.map do |target|
66
- source = source_app_plans.find do |app_plan|
67
- compare_hashes(app_plan, target, ['system_name'])
68
- end || {}
69
- [source['id'], target]
70
- end
71
- mapping.reject { |key, _| key.nil? }
61
+ def random_lowercase_name(length=8)
62
+ [*('a'..'z')].sample(length).join
63
+ end
64
+
65
+ def backend_metric_link_parser(link)
66
+ return if link.nil?
67
+
68
+ link.match(/admin\/api\/backend_apis\/(\d+)\/metrics/) { |m| m.captures[0] }
72
69
  end
73
70
  end
74
71
 
@@ -13,6 +13,10 @@ module ThreeScaleToolbox
13
13
  result
14
14
  end
15
15
 
16
+ def public_send(name, *args)
17
+ method_missing(name, *args)
18
+ end
19
+
16
20
  def respond_to_missing?(method_name, include_private = false)
17
21
  super
18
22
  end
@@ -0,0 +1,157 @@
1
+ module ThreeScaleToolbox
2
+ class RemoteCache < BasicObject
3
+
4
+ attr_reader :metrics_cache, :methods_cache, :backend_metrics_cache, :backend_methods_cache, :subject
5
+
6
+ def initialize(subject)
7
+ @subject = subject
8
+ # Metrics and methods cache data
9
+ @metrics_cache = {}
10
+ # methods cache data
11
+ @methods_cache = {}
12
+ # Backend Metrics and methods cache data
13
+ @backend_metrics_cache = {}
14
+ # Backend methods cache data
15
+ @backend_methods_cache = {}
16
+ end
17
+
18
+ def list_metrics(service_id)
19
+ return metrics_cache[service_id] if metrics_cache.has_key? service_id
20
+
21
+ subject.list_metrics(service_id).tap do |metrics|
22
+ metrics_cache[service_id] = metrics unless metrics.respond_to?(:has_key?) && !metrics['errors'].nil?
23
+ end
24
+ end
25
+
26
+ def list_methods(service_id, metric_id)
27
+ key = method_cache_key(service_id, metric_id)
28
+ return methods_cache[key] if methods_cache.has_key? key
29
+
30
+ subject.list_methods(service_id, metric_id).tap do |methods|
31
+ methods_cache[key] = methods unless methods.respond_to?(:has_key?) && !methods['errors'].nil?
32
+ end
33
+ end
34
+
35
+ def create_metric(service_id, attributes)
36
+ subject.create_metric(service_id, attributes).tap do |metric_attrs|
37
+ metrics_cache.delete(service_id) unless metric_attrs.respond_to?(:has_key?) && !metric_attrs['errors'].nil?
38
+ end
39
+ end
40
+
41
+ def update_metric(service_id, metric_id, attributes)
42
+ subject.update_metric(service_id, metric_id, attributes).tap do |metric_attrs|
43
+ metrics_cache.delete(service_id) unless metric_attrs.respond_to?(:has_key?) && !metric_attrs['errors'].nil?
44
+ end
45
+ end
46
+
47
+ def delete_metric(service_id, metric_id)
48
+ subject.delete_metric(service_id, metric_id).tap do |_|
49
+ metrics_cache.delete(service_id)
50
+ end
51
+ end
52
+
53
+ def update_method(service_id, parent_id, id, attributes)
54
+ subject.update_method(service_id, parent_id, id, attributes).tap do |method_attrs|
55
+ metrics_cache.delete(service_id) unless method_attrs.respond_to?(:has_key?) && !method_attrs['errors'].nil?
56
+ methods_cache.delete(method_cache_key(service_id, parent_id)) unless method_attrs.respond_to?(:has_key?) && !method_attrs['errors'].nil?
57
+ end
58
+ end
59
+
60
+
61
+ def create_method(service_id, metric_id, attributes)
62
+ subject.create_method(service_id, metric_id, attributes).tap do |method_attrs|
63
+ metrics_cache.delete(service_id) unless method_attrs.respond_to?(:has_key?) && !method_attrs['errors'].nil?
64
+ methods_cache.delete(method_cache_key(service_id, metric_id)) unless method_attrs.respond_to?(:has_key?) && !method_attrs['errors'].nil?
65
+ end
66
+ end
67
+
68
+ def delete_method(service_id, parent_id, id)
69
+ subject.delete_method(service_id, parent_id, id).tap do |_|
70
+ metrics_cache.delete(service_id)
71
+ methods_cache.delete(method_cache_key(service_id, parent_id))
72
+ end
73
+ end
74
+
75
+ ###
76
+ # Backends
77
+ ###
78
+
79
+ def list_backend_metrics(backend_id)
80
+ return backend_metrics_cache[backend_id] if backend_metrics_cache.has_key? backend_id
81
+
82
+ subject.list_backend_metrics(backend_id).tap do |metrics|
83
+ backend_metrics_cache[backend_id] = metrics unless metrics.respond_to?(:has_key?) && !metrics['errors'].nil?
84
+ end
85
+ end
86
+
87
+ def list_backend_methods(backend_id, metric_id)
88
+ key = method_cache_key(backend_id, metric_id)
89
+ return backend_methods_cache[key] if backend_methods_cache.has_key? key
90
+
91
+ subject.list_backend_methods(backend_id, metric_id).tap do |methods|
92
+ backend_methods_cache[key] = methods unless methods.respond_to?(:has_key?) && !methods['errors'].nil?
93
+ end
94
+ end
95
+
96
+ def create_backend_metric(backend_id, attributes)
97
+ subject.create_backend_metric(backend_id, attributes).tap do |metric_attrs|
98
+ backend_metrics_cache.delete(backend_id) unless metric_attrs.respond_to?(:has_key?) && !metric_attrs['errors'].nil?
99
+ end
100
+ end
101
+
102
+ def update_backend_metric(backend_id, metric_id, attributes)
103
+ subject.update_backend_metric(backend_id, metric_id, attributes).tap do |metric_attrs|
104
+ backend_metrics_cache.delete(backend_id) unless metric_attrs.respond_to?(:has_key?) && !metric_attrs['errors'].nil?
105
+ end
106
+ end
107
+
108
+ def delete_backend_metric(backend_id, metric_id)
109
+ subject.delete_backend_metric(backend_id, metric_id).tap do |_|
110
+ backend_metrics_cache.delete(backend_id)
111
+ end
112
+ end
113
+
114
+ def create_backend_method(backend_id, metric_id, attributes)
115
+ subject.create_backend_method(backend_id, metric_id, attributes).tap do |method_attrs|
116
+ unless method_attrs.respond_to?(:has_key?) && !method_attrs['errors'].nil?
117
+ backend_metrics_cache.delete(backend_id)
118
+ backend_methods_cache.delete(method_cache_key(backend_id, metric_id))
119
+ end
120
+ end
121
+ end
122
+
123
+ def delete_backend_method(backend_id, metric_id, method_id)
124
+ subject.delete_backend_method(backend_id, metric_id, method_id).tap do |_|
125
+ backend_metrics_cache.delete(backend_id)
126
+ backend_methods_cache.delete(method_cache_key(backend_id, metric_id))
127
+ end
128
+ end
129
+
130
+ def update_backend_method(backend_id, metric_id, method_id, attributes)
131
+ subject.update_backend_method(backend_id, metric_id, method_id, attributes).tap do |method_attrs|
132
+ unless method_attrs.respond_to?(:has_key?) && !method_attrs['errors'].nil?
133
+ backend_metrics_cache.delete(backend_id)
134
+ backend_methods_cache.delete(method_cache_key(backend_id, metric_id))
135
+ end
136
+ end
137
+ end
138
+
139
+ ###
140
+ # Generic methods
141
+ ###
142
+
143
+ def method_missing(name, *args)
144
+ subject.public_send(name, *args)
145
+ end
146
+
147
+ def respond_to_missing?(method_name, include_private = false)
148
+ super
149
+ end
150
+
151
+ private
152
+
153
+ def method_cache_key(id, metric_id)
154
+ "#{id}#{metric_id}"
155
+ end
156
+ end
157
+ end