3scale_toolbox 0.13.0 → 0.17.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. checksums.yaml +4 -4
  2. data/3scale_toolbox.gemspec +4 -3
  3. data/README.md +31 -10
  4. data/lib/3scale_toolbox.rb +5 -2
  5. data/lib/3scale_toolbox/attribute_filters.rb +2 -0
  6. data/lib/3scale_toolbox/attribute_filters/attribute_filter.rb +9 -0
  7. data/lib/3scale_toolbox/attribute_filters/service_id_from_ref_filter.rb +30 -0
  8. data/lib/3scale_toolbox/cli.rb +4 -0
  9. data/lib/3scale_toolbox/cli/custom_table_printer.rb +32 -0
  10. data/lib/3scale_toolbox/cli/error_handler.rb +17 -14
  11. data/lib/3scale_toolbox/cli/json_printer.rb +13 -0
  12. data/lib/3scale_toolbox/cli/output_flag.rb +20 -0
  13. data/lib/3scale_toolbox/cli/yaml_printer.rb +13 -0
  14. data/lib/3scale_toolbox/commands.rb +5 -1
  15. data/lib/3scale_toolbox/commands/activedocs_command/apply_command.rb +34 -11
  16. data/lib/3scale_toolbox/commands/activedocs_command/create_command.rb +22 -7
  17. data/lib/3scale_toolbox/commands/activedocs_command/list_command.rb +21 -11
  18. data/lib/3scale_toolbox/commands/application_command/apply_command.rb +27 -4
  19. data/lib/3scale_toolbox/commands/application_command/create_command.rb +16 -1
  20. data/lib/3scale_toolbox/commands/application_command/list_command.rb +10 -13
  21. data/lib/3scale_toolbox/commands/application_command/show_command.rb +8 -14
  22. data/lib/3scale_toolbox/commands/backend_command.rb +22 -0
  23. data/lib/3scale_toolbox/commands/backend_command/copy_command.rb +65 -0
  24. data/lib/3scale_toolbox/commands/backend_command/copy_command/copy_mapping_rules_task.rb +52 -0
  25. data/lib/3scale_toolbox/commands/backend_command/copy_command/copy_methods_task.rb +40 -0
  26. data/lib/3scale_toolbox/commands/backend_command/copy_command/copy_metrics_task.rb +30 -0
  27. data/lib/3scale_toolbox/commands/backend_command/copy_command/create_or_update_target_backend_task.rb +45 -0
  28. data/lib/3scale_toolbox/commands/backend_command/copy_command/task.rb +89 -0
  29. data/lib/3scale_toolbox/commands/copy_command.rb +2 -2
  30. data/lib/3scale_toolbox/commands/copy_command/service_command.rb +40 -0
  31. data/lib/3scale_toolbox/commands/import_command/openapi.rb +29 -7
  32. data/lib/3scale_toolbox/commands/import_command/openapi/create_activedocs_step.rb +4 -17
  33. data/lib/3scale_toolbox/commands/import_command/openapi/create_service_step.rb +1 -5
  34. data/lib/3scale_toolbox/commands/import_command/openapi/mapping_rule.rb +3 -2
  35. data/lib/3scale_toolbox/commands/import_command/openapi/step.rb +43 -5
  36. data/lib/3scale_toolbox/commands/import_command/openapi/update_policies_step.rb +9 -10
  37. data/lib/3scale_toolbox/commands/import_command/openapi/update_service_oidc_conf_step.rb +2 -17
  38. data/lib/3scale_toolbox/commands/import_command/openapi/update_service_proxy_step.rb +10 -10
  39. data/lib/3scale_toolbox/commands/methods_command/apply_command.rb +26 -4
  40. data/lib/3scale_toolbox/commands/methods_command/create_command.rb +23 -1
  41. data/lib/3scale_toolbox/commands/methods_command/list_command.rb +11 -9
  42. data/lib/3scale_toolbox/commands/metrics_command/apply_command.rb +26 -4
  43. data/lib/3scale_toolbox/commands/metrics_command/create_command.rb +23 -1
  44. data/lib/3scale_toolbox/commands/metrics_command/list_command.rb +7 -12
  45. data/lib/3scale_toolbox/commands/plans_command/apply_command.rb +36 -7
  46. data/lib/3scale_toolbox/commands/plans_command/create_command.rb +23 -1
  47. data/lib/3scale_toolbox/commands/plans_command/import/import_plan_limits_step.rb +11 -12
  48. data/lib/3scale_toolbox/commands/plans_command/import/import_plan_pricing_rules_step.rb +11 -12
  49. data/lib/3scale_toolbox/commands/plans_command/list_command.rb +8 -13
  50. data/lib/3scale_toolbox/commands/plans_command/show_command.rb +6 -14
  51. data/lib/3scale_toolbox/commands/product_command.rb +22 -0
  52. data/lib/3scale_toolbox/commands/product_command/copy_command.rb +78 -0
  53. data/lib/3scale_toolbox/commands/product_command/copy_command/copy_backends_task.rb +71 -0
  54. data/lib/3scale_toolbox/commands/product_command/copy_command/delete_target_backend_usages_task.rb +48 -0
  55. data/lib/3scale_toolbox/commands/proxy_config_command.rb +3 -0
  56. data/lib/3scale_toolbox/commands/proxy_config_command/export_command.rb +74 -0
  57. data/lib/3scale_toolbox/commands/proxy_config_command/helper.rb +15 -0
  58. data/lib/3scale_toolbox/commands/proxy_config_command/list_command.rb +13 -29
  59. data/lib/3scale_toolbox/commands/proxy_config_command/show_command.rb +20 -23
  60. data/lib/3scale_toolbox/commands/service_command.rb +7 -5
  61. data/lib/3scale_toolbox/commands/service_command/apply_command.rb +69 -58
  62. data/lib/3scale_toolbox/commands/service_command/copy_command.rb +95 -0
  63. data/lib/3scale_toolbox/commands/service_command/copy_command/bump_proxy_version_task.rb +36 -0
  64. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_activedocs_task.rb +46 -0
  65. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_app_plans_task.rb +35 -0
  66. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_limits_task.rb +39 -0
  67. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_mapping_rules_task.rb +35 -0
  68. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_methods_task.rb +40 -0
  69. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_metrics_task.rb +37 -0
  70. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_policies_task.rb +17 -0
  71. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_pricingrules_task.rb +44 -0
  72. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_service_proxy_task.rb +32 -0
  73. data/lib/3scale_toolbox/commands/service_command/copy_command/create_or_update_service_task.rb +48 -0
  74. data/lib/3scale_toolbox/commands/service_command/copy_command/destroy_mapping_rules_task.rb +34 -0
  75. data/lib/3scale_toolbox/commands/service_command/copy_command/task.rb +99 -0
  76. data/lib/3scale_toolbox/commands/service_command/create_command.rb +58 -44
  77. data/lib/3scale_toolbox/commands/service_command/delete_command.rb +31 -33
  78. data/lib/3scale_toolbox/commands/service_command/list_command.rb +24 -34
  79. data/lib/3scale_toolbox/commands/service_command/show_command.rb +39 -44
  80. data/lib/3scale_toolbox/commands/update_command.rb +3 -3
  81. data/lib/3scale_toolbox/commands/update_command/{update_service.rb → service_command.rb} +22 -18
  82. data/lib/3scale_toolbox/commands/update_command/service_command/copy_service_settings_task.rb +35 -0
  83. data/lib/3scale_toolbox/commands/update_command/service_command/delete_activedocs_task.rb +26 -0
  84. data/lib/3scale_toolbox/entities.rb +5 -0
  85. data/lib/3scale_toolbox/entities/application_plan.rb +31 -4
  86. data/lib/3scale_toolbox/entities/backend.rb +152 -0
  87. data/lib/3scale_toolbox/entities/backend_mapping_rule.rb +76 -0
  88. data/lib/3scale_toolbox/entities/backend_method.rb +90 -0
  89. data/lib/3scale_toolbox/entities/backend_metric.rb +88 -0
  90. data/lib/3scale_toolbox/entities/backend_usage.rb +99 -0
  91. data/lib/3scale_toolbox/entities/service.rb +18 -3
  92. data/lib/3scale_toolbox/error.rb +53 -0
  93. data/lib/3scale_toolbox/helper.rb +20 -0
  94. data/lib/3scale_toolbox/openapi.rb +2 -0
  95. data/lib/3scale_toolbox/openapi/oas3.rb +232 -0
  96. data/lib/3scale_toolbox/openapi/swagger.rb +192 -0
  97. data/lib/3scale_toolbox/proxy_logger.rb +1 -1
  98. data/lib/3scale_toolbox/version.rb +1 -1
  99. data/licenses.xml +188 -18
  100. data/resources/oas3_meta_schema.json +1654 -0
  101. metadata +68 -28
  102. data/lib/3scale_toolbox/commands/copy_command/copy_service.rb +0 -144
  103. data/lib/3scale_toolbox/commands/import_command/openapi/threescale_api_spec.rb +0 -80
  104. data/lib/3scale_toolbox/swagger.rb +0 -1
  105. data/lib/3scale_toolbox/swagger/swagger.rb +0 -123
  106. data/lib/3scale_toolbox/tasks.rb +0 -15
  107. data/lib/3scale_toolbox/tasks/bump_proxy_version_task.rb +0 -32
  108. data/lib/3scale_toolbox/tasks/copy_activedocs_task.rb +0 -42
  109. data/lib/3scale_toolbox/tasks/copy_app_plans_task.rb +0 -31
  110. data/lib/3scale_toolbox/tasks/copy_limits_task.rb +0 -36
  111. data/lib/3scale_toolbox/tasks/copy_mapping_rules_task.rb +0 -32
  112. data/lib/3scale_toolbox/tasks/copy_methods_task.rb +0 -36
  113. data/lib/3scale_toolbox/tasks/copy_metrics_task.rb +0 -33
  114. data/lib/3scale_toolbox/tasks/copy_policies_task.rb +0 -13
  115. data/lib/3scale_toolbox/tasks/copy_pricingrules_task.rb +0 -41
  116. data/lib/3scale_toolbox/tasks/copy_service_proxy_task.rb +0 -12
  117. data/lib/3scale_toolbox/tasks/copy_service_settings_task.rb +0 -38
  118. data/lib/3scale_toolbox/tasks/copy_task.rb +0 -66
  119. data/lib/3scale_toolbox/tasks/delete_activedocs_task.rb +0 -22
  120. data/lib/3scale_toolbox/tasks/destroy_mapping_rules_task.rb +0 -22
  121. data/lib/3scale_toolbox/tasks/helper_task.rb +0 -25
@@ -1,62 +1,57 @@
1
1
  module ThreeScaleToolbox
2
2
  module Commands
3
3
  module ServiceCommand
4
- module Show
5
- class ShowSubcommand < Cri::CommandRunner
6
- include ThreeScaleToolbox::Command
7
-
8
- def self.command
9
- Cri::Command.define do
10
- name 'show'
11
- usage 'show <remote> <service-id_or_system-name>'
12
- summary 'Show the information of a service'
13
- description "Show the information of a service"
14
- runner ShowSubcommand
15
-
16
- param :remote
17
- param :service_id_or_system_name
18
- end
19
- end
4
+ class ShowSubcommand < Cri::CommandRunner
5
+ include ThreeScaleToolbox::Command
20
6
 
21
- def run
22
- print_header
23
- print_data
24
- end
7
+ FIELDS = %w[
8
+ id name state system_name end_user_registration_required
9
+ backend_version deployment_option support_email description
10
+ created_at updated_at
11
+ ]
25
12
 
26
- private
13
+ def self.command
14
+ Cri::Command.define do
15
+ name 'show'
16
+ usage 'show <remote> <service-id_or_system-name>'
17
+ summary 'Show the information of a service'
18
+ description "Show the information of a service"
27
19
 
28
- SERVICE_FIELDS_TO_SHOW = %w[
29
- id name state system_name end_user_registration_required
30
- backend_version deployment_option support_email description
31
- created_at updated_at
32
- ]
20
+ ThreeScaleToolbox::CLI.output_flag(self)
21
+ param :remote
22
+ param :service_id_or_system_name
33
23
 
34
- def remote
35
- @remote ||= threescale_client(arguments[:remote])
24
+ runner ShowSubcommand
36
25
  end
26
+ end
37
27
 
38
- def ref
39
- @ref ||= arguments[:service_id_or_system_name]
40
- end
28
+ def run
29
+ printer.print_record service.attrs
30
+ end
41
31
 
42
- def service
43
- @service ||= find_service
44
- end
32
+ private
45
33
 
46
- def find_service
47
- Entities::Service::find(remote: remote, ref: ref).tap do |svc|
48
- raise ThreeScaleToolbox::Error, "Service #{ref} does not exist" if svc.nil?
49
- end
50
- end
34
+ def remote
35
+ @remote ||= threescale_client(arguments[:remote])
36
+ end
51
37
 
52
- def print_header
53
- puts SERVICE_FIELDS_TO_SHOW.map { |e| e.upcase }.join("\t")
54
- end
38
+ def ref
39
+ @ref ||= arguments[:service_id_or_system_name]
40
+ end
55
41
 
56
- def print_data
57
- puts SERVICE_FIELDS_TO_SHOW.map { |field| service.attrs.fetch(field, '(empty)') }.join("\t")
42
+ def service
43
+ @service ||= find_service
44
+ end
45
+
46
+ def find_service
47
+ Entities::Service::find(remote: remote, ref: ref).tap do |svc|
48
+ raise ThreeScaleToolbox::Error, "Service #{ref} does not exist" if svc.nil?
58
49
  end
59
50
  end
51
+
52
+ def printer
53
+ options.fetch(:output, CLI::CustomTablePrinter.new(FIELDS))
54
+ end
60
55
  end
61
56
  end
62
57
  end
@@ -1,4 +1,4 @@
1
- require '3scale_toolbox/commands/update_command/update_service'
1
+ require '3scale_toolbox/commands/update_command/service_command'
2
2
 
3
3
  module ThreeScaleToolbox
4
4
  module Commands
@@ -8,7 +8,7 @@ module ThreeScaleToolbox
8
8
  Cri::Command.define do
9
9
  name 'update'
10
10
  usage 'update <sub-command> [options]'
11
- summary '[DEPRECTATED] update super command'
11
+ summary '[DEPRECATED] update super command'
12
12
  description 'Update 3scale entities between tenants'
13
13
 
14
14
  run do |_opts, _args, cmd|
@@ -16,7 +16,7 @@ module ThreeScaleToolbox
16
16
  end
17
17
  end
18
18
  end
19
- add_subcommand(UpdateServiceSubcommand)
19
+ add_subcommand(ServiceSubcommand)
20
20
  end
21
21
  end
22
22
  end
@@ -1,16 +1,19 @@
1
+ require '3scale_toolbox/commands/update_command/service_command/delete_activedocs_task'
2
+ require '3scale_toolbox/commands/update_command/service_command/copy_service_settings_task'
3
+
1
4
  module ThreeScaleToolbox
2
5
  module Commands
3
6
  module UpdateCommand
4
- class UpdateServiceSubcommand < Cri::CommandRunner
7
+ class ServiceSubcommand < Cri::CommandRunner
5
8
  include ThreeScaleToolbox::Command
6
9
 
7
10
  def self.command
8
11
  Cri::Command.define do
9
12
  name 'service'
10
13
  usage 'service [opts] -s <src> -d <dst> <src_service_id> <dst_service_id>'
11
- summary '[DEPRECTATED] update service'
14
+ summary '[DEPRECATED] update service'
12
15
  description <<-HEREDOC
13
- This command has been deprecated. Use '3scale copy service' instead.
16
+ This command has been deprecated. Use '3scale service copy' instead.
14
17
  \n Update existing service, update proxy settings, metrics, methods, application plans and mapping rules.'
15
18
  HEREDOC
16
19
 
@@ -22,11 +25,12 @@ module ThreeScaleToolbox
22
25
  param :src_service_id
23
26
  param :dst_service_id
24
27
 
25
- runner UpdateServiceSubcommand
28
+ runner ServiceSubcommand
26
29
  end
27
30
  end
28
31
 
29
32
  def run
33
+ warn "\e[1m\e[31mThis command has been deprecated. Use '3scale service copy' instead\e[0m"
30
34
  source_service = Entities::Service.new(
31
35
  id: arguments[:src_service_id],
32
36
  remote: threescale_client(fetch_required_option(:source))
@@ -35,28 +39,27 @@ module ThreeScaleToolbox
35
39
  id: arguments[:dst_service_id],
36
40
  remote: threescale_client(fetch_required_option(:destination))
37
41
  )
38
- system_name = options[:target_system_name]
39
42
  context = create_context(source_service, update_service)
40
43
 
41
44
  tasks = []
42
45
  unless options[:'rules-only']
43
- tasks << Tasks::CopyServiceSettingsTask.new(context)
44
- tasks << Tasks::CopyMethodsTask.new(context)
45
- tasks << Tasks::CopyMetricsTask.new(context)
46
- tasks << Tasks::CopyApplicationPlansTask.new(context)
47
- tasks << Tasks::CopyLimitsTask.new(context)
48
- tasks << Tasks::CopyPoliciesTask.new(context)
49
- tasks << Tasks::CopyPricingRulesTask.new(context)
50
- tasks << Tasks::DeleteActiveDocsTask.new(context)
51
- tasks << Tasks::CopyActiveDocsTask.new(context)
46
+ tasks << ServiceCommand::CopyServiceSettingsTask.new(context)
47
+ tasks << ThreeScaleToolbox::Commands::ServiceCommand::CopyCommand::CopyMethodsTask.new(context)
48
+ tasks << ThreeScaleToolbox::Commands::ServiceCommand::CopyCommand::CopyMetricsTask.new(context)
49
+ tasks << ThreeScaleToolbox::Commands::ServiceCommand::CopyCommand::CopyApplicationPlansTask.new(context)
50
+ tasks << ThreeScaleToolbox::Commands::ServiceCommand::CopyCommand::CopyLimitsTask.new(context)
51
+ tasks << ThreeScaleToolbox::Commands::ServiceCommand::CopyCommand::CopyPoliciesTask.new(context)
52
+ tasks << ThreeScaleToolbox::Commands::ServiceCommand::CopyCommand::CopyPricingRulesTask.new(context)
53
+ tasks << ServiceCommand::DeleteActiveDocsTask.new(context)
54
+ tasks << ThreeScaleToolbox::Commands::ServiceCommand::CopyCommand::CopyActiveDocsTask.new(context)
52
55
  # Copy proxy must be the last task
53
56
  # Proxy update is the mechanism to increase version of the proxy,
54
57
  # Hence propagating (mapping rules, poicies, oidc, auth) update to
55
58
  # latest proxy config, making available to gateway.
56
- tasks << Tasks::CopyServiceProxyTask.new(context)
59
+ tasks << ThreeScaleToolbox::Commands::ServiceCommand::CopyCommand::CopyServiceProxyTask.new(context)
57
60
  end
58
- tasks << Tasks::DestroyMappingRulesTask.new(context) if options[:force]
59
- tasks << Tasks::CopyMappingRulesTask.new(context)
61
+ tasks << ThreeScaleToolbox::Commands::ServiceCommand::CopyCommand::DestroyMappingRulesTask.new(context)
62
+ tasks << ThreeScaleToolbox::Commands::ServiceCommand::CopyCommand::CopyMappingRulesTask.new(context)
60
63
 
61
64
  # run tasks
62
65
  tasks.each(&:call)
@@ -67,7 +70,8 @@ module ThreeScaleToolbox
67
70
  def create_context(source, target)
68
71
  {
69
72
  source: source,
70
- target: target
73
+ target: target,
74
+ delete_mapping_rules: options[:force]
71
75
  }
72
76
  end
73
77
  end
@@ -0,0 +1,35 @@
1
+ module ThreeScaleToolbox
2
+ module Commands
3
+ module UpdateCommand
4
+ module ServiceCommand
5
+ class CopyServiceSettingsTask
6
+ attr_reader :context
7
+
8
+ def initialize(context)
9
+ @context = context
10
+ end
11
+
12
+ def call
13
+ target.update source_attrs
14
+
15
+ puts "updated service settings for service id #{source.id}..."
16
+ end
17
+
18
+ private
19
+
20
+ def source
21
+ context[:source]
22
+ end
23
+
24
+ def target
25
+ context[:target]
26
+ end
27
+
28
+ def source_attrs
29
+ source.attrs.reject { |k, _| %w[system_name id links].include? k }
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,26 @@
1
+ module ThreeScaleToolbox
2
+ module Commands
3
+ module UpdateCommand
4
+ module ServiceCommand
5
+ class DeleteActiveDocsTask
6
+ attr_reader :context
7
+
8
+ def initialize(context)
9
+ @context = context
10
+ end
11
+
12
+ def call
13
+ puts 'deleting all target service ActiveDocs'
14
+ target.activedocs.each do |activedoc|
15
+ target.remote.delete_activedocs(activedoc['id'])
16
+ end
17
+ end
18
+
19
+ def target
20
+ context[:target]
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -6,3 +6,8 @@ require '3scale_toolbox/entities/activedocs'
6
6
  require '3scale_toolbox/entities/account'
7
7
  require '3scale_toolbox/entities/proxy_config'
8
8
  require '3scale_toolbox/entities/application'
9
+ require '3scale_toolbox/entities/backend'
10
+ require '3scale_toolbox/entities/backend_method'
11
+ require '3scale_toolbox/entities/backend_metric'
12
+ require '3scale_toolbox/entities/backend_mapping_rule'
13
+ require '3scale_toolbox/entities/backend_usage'
@@ -142,19 +142,46 @@ module ThreeScaleToolbox
142
142
  end
143
143
 
144
144
  def create_pricing_rule(metric_id, pr_attrs)
145
- remote.create_pricingrule id, metric_id, pr_attrs
145
+ pricing_rule_attrs = remote.create_pricingrule id, metric_id, pr_attrs
146
+ if (errors = pricing_rule_attrs['errors'])
147
+ raise ThreeScaleToolbox::Error, "Pricing rule has not been created. #{errors}"
148
+ end
149
+
150
+ pricing_rule_attrs
151
+ end
152
+
153
+ def delete_pricing_rule(metric_id, rule_id)
154
+ remote.delete_application_plan_pricingrule(id, metric_id, rule_id)
146
155
  end
147
156
 
148
157
  def pricing_rules
149
- remote.list_pricingrules_per_application_plan id
158
+ pr_list = remote.list_pricingrules_per_application_plan id
159
+
160
+ if pr_list.respond_to?(:has_key?) && (errors = pr_list['errors'])
161
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('pricing rules not read', errors)
162
+ end
163
+
164
+ pr_list
150
165
  end
151
166
 
152
167
  def features
153
- remote.list_features_per_application_plan id
168
+ feature_list = remote.list_features_per_application_plan id
169
+
170
+ if feature_list.respond_to?(:has_key?) && (errors = feature_list['errors'])
171
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('features not read', errors)
172
+ end
173
+
174
+ feature_list
154
175
  end
155
176
 
156
177
  def create_feature(feature_id)
157
- remote.create_application_plan_feature id, feature_id
178
+ feature = remote.create_application_plan_feature id, feature_id
179
+
180
+ if (errors = feature['errors'])
181
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('feature not created', errors)
182
+ end
183
+
184
+ feature
158
185
  end
159
186
 
160
187
  def delete
@@ -0,0 +1,152 @@
1
+ module ThreeScaleToolbox
2
+ module Entities
3
+ class Backend
4
+ VALID_PARAMS = %w[name description system_name private_endpoint].freeze
5
+ public_constant :VALID_PARAMS
6
+
7
+ class << self
8
+ def create(remote:, attrs:)
9
+ b_attrs = remote.create_backend Helper.filter_params(VALID_PARAMS, attrs)
10
+ if (errors = b_attrs['errors'])
11
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Backend has not been created', errors)
12
+ end
13
+
14
+ new(id: b_attrs.fetch('id'), remote: remote, attrs: b_attrs)
15
+ end
16
+
17
+ # ref can be system_name or backend_id
18
+ def find(remote:, ref:)
19
+ new(id: ref, remote: remote).tap(&:attrs)
20
+ rescue ThreeScaleToolbox::InvalidIdError, ThreeScale::API::HttpClient::NotFoundError
21
+ find_by_system_name(remote: remote, system_name: ref)
22
+ end
23
+
24
+ def find_by_system_name(remote:, system_name:)
25
+ list = remote.list_backends
26
+
27
+ if list.respond_to?(:has_key?) && (errors = list['errors'])
28
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Backend list not read', errors)
29
+ end
30
+
31
+ attrs = list.find { |backend| backend['system_name'] == system_name }
32
+ return if attrs.nil?
33
+
34
+ new(id: attrs.fetch('id'), remote: remote, attrs: attrs)
35
+ end
36
+ end
37
+
38
+ attr_reader :id, :remote
39
+
40
+ def initialize(id:, remote:, attrs: nil)
41
+ @id = id.to_i
42
+ @remote = remote
43
+ @attrs = attrs
44
+ end
45
+
46
+ def attrs
47
+ @attrs ||= fetch_backend_attrs
48
+ end
49
+
50
+ def system_name
51
+ attrs['system_name']
52
+ end
53
+
54
+ def metrics
55
+ # cache result to reuse
56
+ metric_and_method_list = metrics_and_methods
57
+ hits_metric_obj = hits_metric(metric_and_method_list)
58
+
59
+ metric_attr_list = ThreeScaleToolbox::Helper.array_difference(metric_and_method_list, methods(hits_metric_obj)) do |item, method|
60
+ method.id == item.fetch('id', nil)
61
+ end
62
+
63
+ metric_attr_list.map do |metric_attrs|
64
+ BackendMetric.new(id: metric_attrs.fetch('id'), backend: self, attrs: metric_attrs)
65
+ end
66
+ end
67
+
68
+ def hits
69
+ hits_metric(metrics_and_methods)
70
+ end
71
+
72
+ # @api public
73
+ # @param [Object] parent_metric_id BackendMetric hits object
74
+ # @return [List]
75
+ def methods(parent_metric_id)
76
+ return [] if parent_metric_id.nil?
77
+
78
+ method_attr_list = remote.list_backend_methods id, parent_metric_id.id
79
+ if method_attr_list.respond_to?(:has_key?) && (errors = method_attr_list['errors'])
80
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Backend methods not read', errors)
81
+ end
82
+
83
+ method_attr_list.map do |method_attrs|
84
+ BackendMethod.new(id: method_attrs.fetch('id'),
85
+ backend: self,
86
+ parent_id: parent_metric_id.id,
87
+ attrs: method_attrs)
88
+ end
89
+ end
90
+
91
+ def mapping_rules
92
+ m_r = remote.list_backend_mapping_rules id
93
+ if m_r.respond_to?(:has_key?) && (errors = m_r['errors'])
94
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Backend mapping rules not read', errors)
95
+ end
96
+
97
+ m_r.map do |mr_attrs|
98
+ BackendMappingRule.new(id: mr_attrs.fetch('id'), backend: self, attrs: mr_attrs)
99
+ end
100
+ end
101
+
102
+ def update(b_attrs)
103
+ new_attrs = remote.update_backend id, Helper.filter_params(VALID_PARAMS, b_attrs)
104
+ if (errors = new_attrs['errors'])
105
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Backend not updated', errors)
106
+ end
107
+
108
+ # update current attrs
109
+ @attrs = new_attrs
110
+
111
+ new_attrs
112
+ end
113
+
114
+ def delete
115
+ remote.delete_backend id
116
+ end
117
+
118
+ def ==(other)
119
+ remote.http_client.endpoint == other.remote.http_client.endpoint && id == other.id
120
+ end
121
+
122
+ private
123
+
124
+ def metrics_and_methods
125
+ m_m = remote.list_backend_metrics id
126
+ if m_m.respond_to?(:has_key?) && (errors = m_m['errors'])
127
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Backend metrics not read', errors)
128
+ end
129
+
130
+ m_m
131
+ end
132
+
133
+ def hits_metric(metric_attr_list)
134
+ metric_list = metric_attr_list.map do |metric_attrs|
135
+ BackendMetric.new(id: metric_attrs.fetch('id'), backend: self, attrs: metric_attrs)
136
+ end
137
+ metric_list.find { |metric| metric.system_name == 'hits' }
138
+ end
139
+
140
+ def fetch_backend_attrs
141
+ raise ThreeScaleToolbox::InvalidIdError if id.zero?
142
+
143
+ backend = remote.backend id
144
+ if (errors = backend['errors'])
145
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Backend attrs not read', errors)
146
+ end
147
+
148
+ backend
149
+ end
150
+ end
151
+ end
152
+ end