3scale_toolbox 0.15.0 → 0.18.2

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 (151) hide show
  1. checksums.yaml +4 -4
  2. data/3scale_toolbox.gemspec +2 -2
  3. data/README.md +15 -9
  4. data/lib/3scale_toolbox.rb +3 -1
  5. data/lib/3scale_toolbox/3scale_client_factory.rb +3 -4
  6. data/lib/3scale_toolbox/cli.rb +4 -0
  7. data/lib/3scale_toolbox/cli/custom_table_printer.rb +32 -0
  8. data/lib/3scale_toolbox/cli/error_handler.rb +17 -14
  9. data/lib/3scale_toolbox/cli/json_printer.rb +13 -0
  10. data/lib/3scale_toolbox/cli/output_flag.rb +20 -0
  11. data/lib/3scale_toolbox/cli/yaml_printer.rb +13 -0
  12. data/lib/3scale_toolbox/commands.rb +7 -1
  13. data/lib/3scale_toolbox/commands/activedocs_command/apply_command.rb +33 -10
  14. data/lib/3scale_toolbox/commands/activedocs_command/create_command.rb +22 -7
  15. data/lib/3scale_toolbox/commands/activedocs_command/list_command.rb +10 -17
  16. data/lib/3scale_toolbox/commands/application_command/apply_command.rb +27 -4
  17. data/lib/3scale_toolbox/commands/application_command/create_command.rb +16 -1
  18. data/lib/3scale_toolbox/commands/application_command/list_command.rb +10 -13
  19. data/lib/3scale_toolbox/commands/application_command/show_command.rb +8 -14
  20. data/lib/3scale_toolbox/commands/backend_command.rb +22 -0
  21. data/lib/3scale_toolbox/commands/backend_command/copy_command.rb +65 -0
  22. data/lib/3scale_toolbox/commands/backend_command/copy_command/copy_mapping_rules_task.rb +36 -0
  23. data/lib/3scale_toolbox/commands/backend_command/copy_command/copy_methods_task.rb +35 -0
  24. data/lib/3scale_toolbox/commands/backend_command/copy_command/copy_metrics_task.rb +30 -0
  25. data/lib/3scale_toolbox/commands/backend_command/copy_command/create_or_update_target_backend_task.rb +46 -0
  26. data/lib/3scale_toolbox/commands/backend_command/copy_command/task.rb +67 -0
  27. data/lib/3scale_toolbox/commands/copy_command.rb +2 -2
  28. data/lib/3scale_toolbox/commands/copy_command/service_command.rb +40 -0
  29. data/lib/3scale_toolbox/commands/import_command/issuer_type_transformer.rb +16 -0
  30. data/lib/3scale_toolbox/commands/import_command/openapi.rb +6 -2
  31. data/lib/3scale_toolbox/commands/import_command/openapi/create_mapping_rule_step.rb +2 -1
  32. data/lib/3scale_toolbox/commands/import_command/openapi/create_method_step.rb +5 -14
  33. data/lib/3scale_toolbox/commands/import_command/openapi/step.rb +4 -0
  34. data/lib/3scale_toolbox/commands/import_command/openapi/update_service_proxy_step.rb +1 -0
  35. data/lib/3scale_toolbox/commands/methods_command/apply_command.rb +28 -8
  36. data/lib/3scale_toolbox/commands/methods_command/create_command.rb +23 -3
  37. data/lib/3scale_toolbox/commands/methods_command/delete_command.rb +1 -1
  38. data/lib/3scale_toolbox/commands/methods_command/list_command.rb +7 -13
  39. data/lib/3scale_toolbox/commands/metrics_command/apply_command.rb +26 -4
  40. data/lib/3scale_toolbox/commands/metrics_command/create_command.rb +23 -1
  41. data/lib/3scale_toolbox/commands/metrics_command/list_command.rb +7 -12
  42. data/lib/3scale_toolbox/commands/plans_command/apply_command.rb +36 -7
  43. data/lib/3scale_toolbox/commands/plans_command/create_command.rb +23 -1
  44. data/lib/3scale_toolbox/commands/plans_command/export/read_plan_limits_step.rb +1 -1
  45. data/lib/3scale_toolbox/commands/plans_command/export/read_plan_methods_step.rb +2 -2
  46. data/lib/3scale_toolbox/commands/plans_command/export/read_plan_metrics_step.rb +2 -2
  47. data/lib/3scale_toolbox/commands/plans_command/export/read_plan_pricing_rules_step.rb +1 -2
  48. data/lib/3scale_toolbox/commands/plans_command/export/step.rb +8 -20
  49. data/lib/3scale_toolbox/commands/plans_command/import/import_plan_limits_step.rb +12 -14
  50. data/lib/3scale_toolbox/commands/plans_command/import/import_plan_metrics_step.rb +6 -13
  51. data/lib/3scale_toolbox/commands/plans_command/import/import_plan_pricing_rules_step.rb +12 -20
  52. data/lib/3scale_toolbox/commands/plans_command/import/step.rb +2 -22
  53. data/lib/3scale_toolbox/commands/plans_command/list_command.rb +8 -13
  54. data/lib/3scale_toolbox/commands/plans_command/show_command.rb +7 -15
  55. data/lib/3scale_toolbox/commands/policies_command.rb +24 -0
  56. data/lib/3scale_toolbox/commands/policies_command/export_command.rb +98 -0
  57. data/lib/3scale_toolbox/commands/policies_command/import_command.rb +61 -0
  58. data/lib/3scale_toolbox/commands/product_command.rb +26 -0
  59. data/lib/3scale_toolbox/commands/product_command/copy_command.rb +82 -0
  60. data/lib/3scale_toolbox/commands/product_command/copy_command/copy_backends_task.rb +88 -0
  61. data/lib/3scale_toolbox/commands/product_command/copy_command/delete_target_backend_usages_task.rb +48 -0
  62. data/lib/3scale_toolbox/commands/product_command/export_command.rb +81 -0
  63. data/lib/3scale_toolbox/commands/product_command/import_command.rb +125 -0
  64. data/lib/3scale_toolbox/commands/proxy_config_command.rb +5 -0
  65. data/lib/3scale_toolbox/commands/proxy_config_command/deploy_command.rb +54 -0
  66. data/lib/3scale_toolbox/commands/proxy_config_command/export_command.rb +74 -0
  67. data/lib/3scale_toolbox/commands/proxy_config_command/helper.rb +15 -0
  68. data/lib/3scale_toolbox/commands/proxy_config_command/list_command.rb +13 -29
  69. data/lib/3scale_toolbox/commands/proxy_config_command/show_command.rb +20 -23
  70. data/lib/3scale_toolbox/commands/service_command.rb +7 -5
  71. data/lib/3scale_toolbox/commands/service_command/apply_command.rb +69 -58
  72. data/lib/3scale_toolbox/commands/service_command/copy_command.rb +95 -0
  73. data/lib/3scale_toolbox/commands/service_command/copy_command/bump_proxy_version_task.rb +36 -0
  74. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_activedocs_task.rb +49 -0
  75. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_app_plans_task.rb +35 -0
  76. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_limits_task.rb +38 -0
  77. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_mapping_rules_task.rb +35 -0
  78. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_methods_task.rb +37 -0
  79. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_metrics_task.rb +37 -0
  80. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_policies_task.rb +17 -0
  81. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_pricingrules_task.rb +41 -0
  82. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_service_proxy_task.rb +32 -0
  83. data/lib/3scale_toolbox/commands/service_command/copy_command/create_or_update_service_task.rb +49 -0
  84. data/lib/3scale_toolbox/commands/service_command/copy_command/destroy_mapping_rules_task.rb +38 -0
  85. data/lib/3scale_toolbox/commands/service_command/copy_command/task.rb +85 -0
  86. data/lib/3scale_toolbox/commands/service_command/create_command.rb +58 -44
  87. data/lib/3scale_toolbox/commands/service_command/delete_command.rb +31 -33
  88. data/lib/3scale_toolbox/commands/service_command/list_command.rb +24 -34
  89. data/lib/3scale_toolbox/commands/service_command/show_command.rb +39 -44
  90. data/lib/3scale_toolbox/commands/update_command.rb +3 -3
  91. data/lib/3scale_toolbox/commands/update_command/{update_service.rb → service_command.rb} +22 -18
  92. data/lib/3scale_toolbox/commands/update_command/service_command/copy_service_settings_task.rb +35 -0
  93. data/lib/3scale_toolbox/commands/update_command/service_command/delete_activedocs_task.rb +24 -0
  94. data/lib/3scale_toolbox/crds.rb +16 -0
  95. data/lib/3scale_toolbox/crds/application_plan_dump.rb +19 -0
  96. data/lib/3scale_toolbox/crds/backend_dump.rb +39 -0
  97. data/lib/3scale_toolbox/crds/backend_mapping_rule_dump.rb +26 -0
  98. data/lib/3scale_toolbox/crds/backend_method_dump.rb +12 -0
  99. data/lib/3scale_toolbox/crds/backend_metric_dump.rb +13 -0
  100. data/lib/3scale_toolbox/crds/backend_parser.rb +55 -0
  101. data/lib/3scale_toolbox/crds/backend_usage_dump.rb +11 -0
  102. data/lib/3scale_toolbox/crds/limit_dump.rb +37 -0
  103. data/lib/3scale_toolbox/crds/mapping_rule_dump.rb +26 -0
  104. data/lib/3scale_toolbox/crds/method_dump.rb +12 -0
  105. data/lib/3scale_toolbox/crds/metric_dump.rb +13 -0
  106. data/lib/3scale_toolbox/crds/pricing_rule_dump.rb +38 -0
  107. data/lib/3scale_toolbox/crds/product_deployment_parser.rb +329 -0
  108. data/lib/3scale_toolbox/crds/product_dump.rb +157 -0
  109. data/lib/3scale_toolbox/crds/product_parser.rb +114 -0
  110. data/lib/3scale_toolbox/crds/remote.rb +682 -0
  111. data/lib/3scale_toolbox/entities.rb +8 -0
  112. data/lib/3scale_toolbox/entities/activedocs.rb +12 -0
  113. data/lib/3scale_toolbox/entities/application_plan.rb +74 -39
  114. data/lib/3scale_toolbox/entities/backend.rb +187 -0
  115. data/lib/3scale_toolbox/entities/backend_mapping_rule.rb +102 -0
  116. data/lib/3scale_toolbox/entities/backend_method.rb +99 -0
  117. data/lib/3scale_toolbox/entities/backend_metric.rb +98 -0
  118. data/lib/3scale_toolbox/entities/backend_usage.rb +105 -0
  119. data/lib/3scale_toolbox/entities/limit.rb +71 -0
  120. data/lib/3scale_toolbox/entities/mapping_rule.rb +90 -0
  121. data/lib/3scale_toolbox/entities/method.rb +33 -19
  122. data/lib/3scale_toolbox/entities/metric.rb +29 -18
  123. data/lib/3scale_toolbox/entities/pricing_rule.rb +63 -0
  124. data/lib/3scale_toolbox/entities/proxy_config.rb +0 -1
  125. data/lib/3scale_toolbox/entities/service.rb +166 -48
  126. data/lib/3scale_toolbox/error.rb +53 -0
  127. data/lib/3scale_toolbox/helper.rb +17 -0
  128. data/lib/3scale_toolbox/openapi/oas3.rb +1 -1
  129. data/lib/3scale_toolbox/proxy_logger.rb +5 -1
  130. data/lib/3scale_toolbox/remote_cache.rb +157 -0
  131. data/lib/3scale_toolbox/remotes.rb +2 -2
  132. data/lib/3scale_toolbox/version.rb +1 -1
  133. data/licenses.xml +113 -45
  134. metadata +75 -26
  135. data/lib/3scale_toolbox/commands/copy_command/copy_service.rb +0 -144
  136. data/lib/3scale_toolbox/tasks.rb +0 -15
  137. data/lib/3scale_toolbox/tasks/bump_proxy_version_task.rb +0 -32
  138. data/lib/3scale_toolbox/tasks/copy_activedocs_task.rb +0 -42
  139. data/lib/3scale_toolbox/tasks/copy_app_plans_task.rb +0 -31
  140. data/lib/3scale_toolbox/tasks/copy_limits_task.rb +0 -36
  141. data/lib/3scale_toolbox/tasks/copy_mapping_rules_task.rb +0 -32
  142. data/lib/3scale_toolbox/tasks/copy_methods_task.rb +0 -36
  143. data/lib/3scale_toolbox/tasks/copy_metrics_task.rb +0 -33
  144. data/lib/3scale_toolbox/tasks/copy_policies_task.rb +0 -13
  145. data/lib/3scale_toolbox/tasks/copy_pricingrules_task.rb +0 -41
  146. data/lib/3scale_toolbox/tasks/copy_service_proxy_task.rb +0 -13
  147. data/lib/3scale_toolbox/tasks/copy_service_settings_task.rb +0 -38
  148. data/lib/3scale_toolbox/tasks/copy_task.rb +0 -66
  149. data/lib/3scale_toolbox/tasks/delete_activedocs_task.rb +0 -22
  150. data/lib/3scale_toolbox/tasks/destroy_mapping_rules_task.rb +0 -22
  151. data/lib/3scale_toolbox/tasks/helper_task.rb +0 -25
@@ -1,38 +1,35 @@
1
1
  module ThreeScaleToolbox
2
2
  module Entities
3
3
  class Method
4
+ include CRD::MethodSerializer
5
+
4
6
  class << self
5
- def create(service:, parent_id:, attrs:)
6
- method = service.remote.create_method service.id, parent_id, attrs
7
- if (errors = method['errors'])
7
+ def create(service:, attrs:)
8
+ method_attrs = service.remote.create_method service.id, service.hits.id, attrs
9
+ if (errors = method_attrs['errors'])
8
10
  raise ThreeScaleToolbox::ThreeScaleApiError.new('Method has not been created', errors)
9
-
10
11
  end
11
12
 
12
- new(id: method.fetch('id'), parent_id: parent_id, service: service, attrs: method)
13
+ new(id: method_attrs.fetch('id'), service: service, attrs: method_attrs)
13
14
  end
14
15
 
15
16
  # ref can be system_name or method_id
16
- def find(service:, parent_id:, ref:)
17
- new(id: ref, parent_id: parent_id, service: service).tap(&:attrs)
17
+ def find(service:, ref:)
18
+ new(id: ref, service: service).tap(&:attrs)
18
19
  rescue ThreeScale::API::HttpClient::NotFoundError
19
- find_by_system_name(service: service, parent_id: parent_id, system_name: ref)
20
+ find_by_system_name(service: service, system_name: ref)
20
21
  end
21
22
 
22
- def find_by_system_name(service:, parent_id:, system_name:)
23
- method = service.methods(parent_id).find { |m| m['system_name'] == system_name }
24
- return if method.nil?
25
-
26
- new(id: method.fetch('id'), parent_id: parent_id, service: service, attrs: method)
23
+ def find_by_system_name(service:, system_name:)
24
+ service.methods.find { |m| m.system_name == system_name }
27
25
  end
28
26
  end
29
27
 
30
- attr_reader :id, :parent_id, :service, :remote
28
+ attr_reader :id, :service, :remote
31
29
 
32
- def initialize(id:, parent_id:, service:, attrs: nil)
30
+ def initialize(id:, service:, attrs: nil)
33
31
  @id = id.to_i
34
32
  @service = service
35
- @parent_id = parent_id
36
33
  @remote = service.remote
37
34
  @attrs = attrs
38
35
  end
@@ -41,6 +38,18 @@ module ThreeScaleToolbox
41
38
  @attrs ||= method_attrs
42
39
  end
43
40
 
41
+ def system_name
42
+ attrs['system_name']
43
+ end
44
+
45
+ def friendly_name
46
+ attrs['friendly_name']
47
+ end
48
+
49
+ def description
50
+ attrs['description']
51
+ end
52
+
44
53
  def disable
45
54
  Metric.new(id: id, service: service).disable
46
55
  end
@@ -50,7 +59,7 @@ module ThreeScaleToolbox
50
59
  end
51
60
 
52
61
  def update(m_attrs)
53
- new_attrs = remote.update_method(service.id, parent_id, id, m_attrs)
62
+ new_attrs = remote.update_method(service.id, hits_id, id, m_attrs)
54
63
  if (errors = new_attrs['errors'])
55
64
  raise ThreeScaleToolbox::ThreeScaleApiError.new('Method has not been updated', errors)
56
65
  end
@@ -62,13 +71,18 @@ module ThreeScaleToolbox
62
71
  end
63
72
 
64
73
  def delete
65
- remote.delete_method service.id, parent_id, id
74
+ remote.delete_method service.id, hits_id, id
66
75
  end
67
76
 
77
+
68
78
  private
69
79
 
80
+ def hits_id
81
+ service.hits.id
82
+ end
83
+
70
84
  def method_attrs
71
- method = remote.show_method service.id, parent_id, id
85
+ method = remote.show_method service.id, hits_id, id
72
86
  if (errors = method['errors'])
73
87
  raise ThreeScaleToolbox::ThreeScaleApiError.new('Method not read', errors)
74
88
  end
@@ -1,6 +1,8 @@
1
1
  module ThreeScaleToolbox
2
2
  module Entities
3
3
  class Metric
4
+ include CRD::MetricSerializer
5
+
4
6
  class << self
5
7
  def create(service:, attrs:)
6
8
  metric = service.remote.create_metric service.id, attrs
@@ -19,10 +21,7 @@ module ThreeScaleToolbox
19
21
  end
20
22
 
21
23
  def find_by_system_name(service:, system_name:)
22
- metric = service.metrics.find { |m| m['system_name'] == system_name }
23
- return if metric.nil?
24
-
25
- new(id: metric.fetch('id'), service: service, attrs: metric)
24
+ service.metrics.find { |m| m.system_name == system_name }
26
25
  end
27
26
  end
28
27
 
@@ -39,25 +38,41 @@ module ThreeScaleToolbox
39
38
  @attrs ||= metric_attrs
40
39
  end
41
40
 
41
+ def system_name
42
+ attrs['system_name']
43
+ end
44
+
45
+ def friendly_name
46
+ attrs['friendly_name']
47
+ end
48
+
49
+ def unit
50
+ attrs['unit']
51
+ end
52
+
53
+ def description
54
+ attrs['description']
55
+ end
56
+
42
57
  def disable
43
58
  # For each plan, get limits for the current metric
44
59
  # if already disabled -> NOOP
45
60
  # if non zero eternity limit exist, update
46
61
  # if non eternity limit exist, create
47
- service_plans.each do |plan|
62
+ service.plans.each do |plan|
48
63
  eternity_limit = plan_eternity_limit(plan)
49
64
  if eternity_limit.nil?
50
65
  plan.create_limit(id, zero_eternity_limit_attrs)
51
- elsif !eternity_limit.fetch('value').zero?
52
- plan.update_limit(id, eternity_limit.fetch('id'), zero_eternity_limit_attrs)
66
+ elsif !eternity_limit.value.zero?
67
+ eternity_limit.update(zero_eternity_limit_attrs)
53
68
  end
54
69
  end
55
70
  end
56
71
 
57
72
  def enable
58
- service_plans.each do |plan|
73
+ service.plans.each do |plan|
59
74
  limit = plan_zero_eternity_limit(plan)
60
- plan.delete_limit(id, limit.fetch('id')) unless limit.nil?
75
+ limit.delete unless limit.nil?
61
76
  end
62
77
  end
63
78
 
@@ -90,19 +105,15 @@ module ThreeScaleToolbox
90
105
 
91
106
  def plan_zero_eternity_limit(plan)
92
107
  # only one limit for eternity period is allowed per (plan_id, metric_id)
93
- plan.metric_limits(id).find { |limit| limit > zero_eternity_limit_attrs }
108
+ #plan.metric_limits(id).find { |limit| limit.attrs > zero_eternity_limit_attrs }
109
+ plan.metric_limits(id).find do |limit|
110
+ limit.attrs > zero_eternity_limit_attrs
111
+ end
94
112
  end
95
113
 
96
114
  def plan_eternity_limit(plan)
97
115
  # only one limit for eternity period is allowed per (plan_id, metric_id)
98
- plan.metric_limits(id).find { |limit| limit['period'] == 'eternity' }
99
- end
100
-
101
- def service_plans
102
- service.plans.map do |plan_attrs|
103
- ThreeScaleToolbox::Entities::ApplicationPlan.new(id: plan_attrs.fetch('id'),
104
- service: service)
105
- end
116
+ plan.metric_limits(id).find { |limit| limit.period == 'eternity' }
106
117
  end
107
118
 
108
119
  def zero_eternity_limit_attrs
@@ -0,0 +1,63 @@
1
+ module ThreeScaleToolbox
2
+ module Entities
3
+ class PricingRule
4
+ include CRD::PricingRuleSerializer
5
+
6
+ class << self
7
+ def create(plan:, metric_id:, attrs:)
8
+ resp_attrs = plan.remote.create_pricingrule plan.id, metric_id, attrs
9
+ if (errors = resp_attrs['errors'])
10
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Pricing rule has not been created', errors)
11
+ end
12
+
13
+ new(id: resp_attrs.fetch('id'), plan: plan, metric_id: metric_id, attrs: resp_attrs)
14
+ end
15
+ end
16
+
17
+ attr_reader :id, :plan, :remote, :attrs, :metric_id
18
+
19
+ def initialize(id:, plan:, metric_id:, attrs:)
20
+ @id = id.to_i
21
+ @plan = plan
22
+ @remote = plan.remote
23
+ @metric_id = metric_id
24
+ @attrs = attrs
25
+ end
26
+
27
+ def cost_per_unit
28
+ attrs['cost_per_unit'].to_f
29
+ end
30
+
31
+ def min
32
+ attrs['min']
33
+ end
34
+
35
+ def max
36
+ attrs['max']
37
+ end
38
+
39
+ def links
40
+ attrs['links'] || []
41
+ end
42
+
43
+ def metric_link
44
+ links.find { |link| link['rel'] == 'metric' }
45
+ end
46
+
47
+ def delete
48
+ remote.delete_application_plan_pricingrule plan.id, metric_id, id
49
+ end
50
+
51
+ private
52
+
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?
58
+
59
+ Backend.new(id: backend_id.to_i, remote: remote)
60
+ end
61
+ end
62
+ end
63
+ end
@@ -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
@@ -24,21 +26,17 @@ module ThreeScaleToolbox
24
26
  # ref can be system_name or service_id
25
27
  def find(remote:, ref:)
26
28
  new(id: ref, remote: remote).tap(&:attrs)
27
- rescue ThreeScale::API::HttpClient::NotFoundError
29
+ rescue ThreeScaleToolbox::InvalidIdError, ThreeScale::API::HttpClient::NotFoundError
28
30
  find_by_system_name(remote: remote, system_name: ref)
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
@@ -72,7 +100,27 @@ module ThreeScaleToolbox
72
100
  end
73
101
 
74
102
  def attrs
75
- @attrs ||= service_attrs
103
+ @attrs ||= fetch_attrs
104
+ end
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']
76
124
  end
77
125
 
78
126
  def update_proxy(proxy)
@@ -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
 
@@ -249,20 +320,58 @@ module ThreeScaleToolbox
249
320
  end
250
321
  end
251
322
 
323
+ def backend_usage_list
324
+ resp = remote.list_backend_usages id
325
+ if resp.respond_to?(:has_key?) && (errors = resp['errors'])
326
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Product backend usage not read', errors)
327
+ end
328
+
329
+ resp.map do |backend_usage_attrs|
330
+ Entities::BackendUsage.new(id: backend_usage_attrs.fetch('id'),
331
+ product: self,
332
+ attrs: backend_usage_attrs)
333
+ end
334
+ end
335
+
336
+ def create_mapping_rule(mr_attrs)
337
+ Entities::MappingRule.create(service: self, attrs: mr_attrs)
338
+ end
339
+
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
354
+
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
362
+
363
+ mapping
364
+ end
365
+
252
366
  def ==(other)
253
367
  remote.http_client.endpoint == other.remote.http_client.endpoint && id == other.id
254
368
  end
255
369
 
256
370
  private
257
371
 
258
- def hits_metric(metric_list)
259
- hits_metric = metric_list.find { |metric| metric['system_name'] == 'hits' }
260
- raise ThreeScaleToolbox::Error, 'missing hits metric' if hits_metric.nil?
261
-
262
- hits_metric
263
- end
372
+ def fetch_attrs
373
+ raise ThreeScaleToolbox::InvalidIdError if id.zero?
264
374
 
265
- def service_attrs
266
375
  svc = remote.show_service id
267
376
  if (errors = svc['errors'])
268
377
  raise ThreeScaleToolbox::ThreeScaleApiError.new('Service attrs not read', errors)
@@ -285,6 +394,15 @@ module ThreeScaleToolbox
285
394
 
286
395
  new_attrs
287
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
288
406
  end
289
407
  end
290
408
  end