3scale_toolbox 0.15.0 → 0.16.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 (97) hide show
  1. checksums.yaml +4 -4
  2. data/3scale_toolbox.gemspec +1 -1
  3. data/README.md +4 -1
  4. data/lib/3scale_toolbox.rb +0 -1
  5. data/lib/3scale_toolbox/cli.rb +4 -0
  6. data/lib/3scale_toolbox/cli/custom_table_printer.rb +32 -0
  7. data/lib/3scale_toolbox/cli/json_printer.rb +13 -0
  8. data/lib/3scale_toolbox/cli/output_flag.rb +20 -0
  9. data/lib/3scale_toolbox/cli/yaml_printer.rb +13 -0
  10. data/lib/3scale_toolbox/commands.rb +5 -1
  11. data/lib/3scale_toolbox/commands/activedocs_command/apply_command.rb +33 -10
  12. data/lib/3scale_toolbox/commands/activedocs_command/create_command.rb +22 -7
  13. data/lib/3scale_toolbox/commands/activedocs_command/list_command.rb +10 -17
  14. data/lib/3scale_toolbox/commands/application_command/apply_command.rb +27 -4
  15. data/lib/3scale_toolbox/commands/application_command/create_command.rb +16 -1
  16. data/lib/3scale_toolbox/commands/application_command/list_command.rb +10 -13
  17. data/lib/3scale_toolbox/commands/application_command/show_command.rb +8 -14
  18. data/lib/3scale_toolbox/commands/backend_command.rb +22 -0
  19. data/lib/3scale_toolbox/commands/backend_command/copy_command.rb +65 -0
  20. data/lib/3scale_toolbox/commands/backend_command/copy_command/copy_mapping_rules_task.rb +52 -0
  21. data/lib/3scale_toolbox/commands/backend_command/copy_command/copy_methods_task.rb +40 -0
  22. data/lib/3scale_toolbox/commands/backend_command/copy_command/copy_metrics_task.rb +30 -0
  23. data/lib/3scale_toolbox/commands/backend_command/copy_command/create_or_update_target_backend_task.rb +45 -0
  24. data/lib/3scale_toolbox/commands/backend_command/copy_command/task.rb +89 -0
  25. data/lib/3scale_toolbox/commands/copy_command.rb +2 -2
  26. data/lib/3scale_toolbox/commands/copy_command/service_command.rb +40 -0
  27. data/lib/3scale_toolbox/commands/import_command/openapi.rb +3 -2
  28. data/lib/3scale_toolbox/commands/methods_command/apply_command.rb +26 -4
  29. data/lib/3scale_toolbox/commands/methods_command/create_command.rb +23 -1
  30. data/lib/3scale_toolbox/commands/methods_command/list_command.rb +11 -9
  31. data/lib/3scale_toolbox/commands/metrics_command/apply_command.rb +26 -4
  32. data/lib/3scale_toolbox/commands/metrics_command/create_command.rb +23 -1
  33. data/lib/3scale_toolbox/commands/metrics_command/list_command.rb +7 -12
  34. data/lib/3scale_toolbox/commands/plans_command/apply_command.rb +36 -7
  35. data/lib/3scale_toolbox/commands/plans_command/create_command.rb +23 -1
  36. data/lib/3scale_toolbox/commands/plans_command/list_command.rb +8 -13
  37. data/lib/3scale_toolbox/commands/plans_command/show_command.rb +6 -14
  38. data/lib/3scale_toolbox/commands/product_command.rb +22 -0
  39. data/lib/3scale_toolbox/commands/product_command/copy_command.rb +78 -0
  40. data/lib/3scale_toolbox/commands/product_command/copy_command/copy_backends_task.rb +71 -0
  41. data/lib/3scale_toolbox/commands/product_command/copy_command/delete_target_backend_usages_task.rb +48 -0
  42. data/lib/3scale_toolbox/commands/proxy_config_command/list_command.rb +13 -29
  43. data/lib/3scale_toolbox/commands/proxy_config_command/show_command.rb +20 -23
  44. data/lib/3scale_toolbox/commands/service_command.rb +7 -5
  45. data/lib/3scale_toolbox/commands/service_command/apply_command.rb +69 -58
  46. data/lib/3scale_toolbox/commands/service_command/copy_command.rb +95 -0
  47. data/lib/3scale_toolbox/commands/service_command/copy_command/bump_proxy_version_task.rb +36 -0
  48. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_activedocs_task.rb +46 -0
  49. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_app_plans_task.rb +35 -0
  50. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_limits_task.rb +39 -0
  51. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_mapping_rules_task.rb +35 -0
  52. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_methods_task.rb +40 -0
  53. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_metrics_task.rb +37 -0
  54. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_policies_task.rb +17 -0
  55. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_pricingrules_task.rb +44 -0
  56. data/lib/3scale_toolbox/commands/service_command/copy_command/copy_service_proxy_task.rb +17 -0
  57. data/lib/3scale_toolbox/commands/service_command/copy_command/create_or_update_service_task.rb +48 -0
  58. data/lib/3scale_toolbox/commands/service_command/copy_command/destroy_mapping_rules_task.rb +34 -0
  59. data/lib/3scale_toolbox/commands/service_command/copy_command/task.rb +99 -0
  60. data/lib/3scale_toolbox/commands/service_command/create_command.rb +58 -44
  61. data/lib/3scale_toolbox/commands/service_command/delete_command.rb +31 -33
  62. data/lib/3scale_toolbox/commands/service_command/list_command.rb +24 -34
  63. data/lib/3scale_toolbox/commands/service_command/show_command.rb +39 -44
  64. data/lib/3scale_toolbox/commands/update_command.rb +2 -2
  65. data/lib/3scale_toolbox/commands/update_command/{update_service.rb → service_command.rb} +19 -16
  66. data/lib/3scale_toolbox/commands/update_command/service_command/copy_service_settings_task.rb +35 -0
  67. data/lib/3scale_toolbox/commands/update_command/service_command/delete_activedocs_task.rb +26 -0
  68. data/lib/3scale_toolbox/entities.rb +5 -0
  69. data/lib/3scale_toolbox/entities/backend.rb +152 -0
  70. data/lib/3scale_toolbox/entities/backend_mapping_rule.rb +76 -0
  71. data/lib/3scale_toolbox/entities/backend_method.rb +90 -0
  72. data/lib/3scale_toolbox/entities/backend_metric.rb +88 -0
  73. data/lib/3scale_toolbox/entities/backend_usage.rb +99 -0
  74. data/lib/3scale_toolbox/entities/service.rb +18 -3
  75. data/lib/3scale_toolbox/error.rb +3 -0
  76. data/lib/3scale_toolbox/helper.rb +20 -0
  77. data/lib/3scale_toolbox/proxy_logger.rb +1 -1
  78. data/lib/3scale_toolbox/version.rb +1 -1
  79. data/licenses.xml +3 -3
  80. metadata +42 -22
  81. data/lib/3scale_toolbox/commands/copy_command/copy_service.rb +0 -144
  82. data/lib/3scale_toolbox/tasks.rb +0 -15
  83. data/lib/3scale_toolbox/tasks/bump_proxy_version_task.rb +0 -32
  84. data/lib/3scale_toolbox/tasks/copy_activedocs_task.rb +0 -42
  85. data/lib/3scale_toolbox/tasks/copy_app_plans_task.rb +0 -31
  86. data/lib/3scale_toolbox/tasks/copy_limits_task.rb +0 -36
  87. data/lib/3scale_toolbox/tasks/copy_mapping_rules_task.rb +0 -32
  88. data/lib/3scale_toolbox/tasks/copy_methods_task.rb +0 -36
  89. data/lib/3scale_toolbox/tasks/copy_metrics_task.rb +0 -33
  90. data/lib/3scale_toolbox/tasks/copy_policies_task.rb +0 -13
  91. data/lib/3scale_toolbox/tasks/copy_pricingrules_task.rb +0 -41
  92. data/lib/3scale_toolbox/tasks/copy_service_proxy_task.rb +0 -13
  93. data/lib/3scale_toolbox/tasks/copy_service_settings_task.rb +0 -38
  94. data/lib/3scale_toolbox/tasks/copy_task.rb +0 -66
  95. data/lib/3scale_toolbox/tasks/delete_activedocs_task.rb +0 -22
  96. data/lib/3scale_toolbox/tasks/destroy_mapping_rules_task.rb +0 -22
  97. data/lib/3scale_toolbox/tasks/helper_task.rb +0 -25
@@ -1,46 +1,44 @@
1
1
  module ThreeScaleToolbox
2
2
  module Commands
3
3
  module ServiceCommand
4
- module Delete
5
- class DeleteSubcommand < Cri::CommandRunner
6
- include ThreeScaleToolbox::Command
7
-
8
- def self.command
9
- Cri::Command.define do
10
- name 'delete'
11
- usage 'delete <remote> <service-id_or_system-name>'
12
- summary 'Delete a service'
13
- description 'Delete a service'
14
- runner DeleteSubcommand
15
-
16
- param :remote
17
- param :service_id_or_system_name
18
- end
4
+ class DeleteSubcommand < Cri::CommandRunner
5
+ include ThreeScaleToolbox::Command
6
+
7
+ def self.command
8
+ Cri::Command.define do
9
+ name 'delete'
10
+ usage 'delete <remote> <service-id_or_system-name>'
11
+ summary 'Delete a service'
12
+ description 'Delete a service'
13
+ runner DeleteSubcommand
14
+
15
+ param :remote
16
+ param :service_id_or_system_name
19
17
  end
18
+ end
20
19
 
21
- def run
22
- service.delete
23
- puts "Service with id: #{service.id} deleted"
24
- end
20
+ def run
21
+ service.delete
22
+ puts "Service with id: #{service.id} deleted"
23
+ end
25
24
 
26
- private
25
+ private
27
26
 
28
- def remote
29
- @remote ||= threescale_client(arguments[:remote])
30
- end
27
+ def remote
28
+ @remote ||= threescale_client(arguments[:remote])
29
+ end
31
30
 
32
- def ref
33
- @ref ||= arguments[:service_id_or_system_name]
34
- end
31
+ def ref
32
+ @ref ||= arguments[:service_id_or_system_name]
33
+ end
35
34
 
36
- def service
37
- @service ||= find_service
38
- end
35
+ def service
36
+ @service ||= find_service
37
+ end
39
38
 
40
- def find_service
41
- Entities::Service::find(remote: remote, ref: ref).tap do |svc|
42
- raise ThreeScaleToolbox::Error, "Service #{ref} does not exist" if svc.nil?
43
- end
39
+ def find_service
40
+ Entities::Service::find(remote: remote, ref: ref).tap do |svc|
41
+ raise ThreeScaleToolbox::Error, "Service #{ref} does not exist" if svc.nil?
44
42
  end
45
43
  end
46
44
  end
@@ -1,48 +1,38 @@
1
1
  module ThreeScaleToolbox
2
2
  module Commands
3
3
  module ServiceCommand
4
- module List
5
- class ListSubcommand < Cri::CommandRunner
6
- include ThreeScaleToolbox::Command
7
-
8
- def self.command
9
- Cri::Command.define do
10
- name 'list'
11
- usage 'list <remote>'
12
- summary 'List all services'
13
- description 'List all services'
14
- runner ListSubcommand
15
-
16
- param :remote
17
- end
18
- end
4
+ class ListSubcommand < Cri::CommandRunner
5
+ include ThreeScaleToolbox::Command
19
6
 
20
- def run
21
- print_header
22
- print_data
23
- end
7
+ FIELDS = %w[id name system_name]
24
8
 
25
- private
9
+ def self.command
10
+ Cri::Command.define do
11
+ name 'list'
12
+ usage 'list <remote>'
13
+ summary 'List all services'
14
+ description 'List all services'
26
15
 
27
- SERVICE_FIELDS_TO_SHOW = %w[id name system_name]
16
+ ThreeScaleToolbox::CLI.output_flag(self)
17
+ param :remote
28
18
 
29
- def services
30
- @services ||= remote.list_services()
19
+ runner ListSubcommand
31
20
  end
21
+ end
32
22
 
33
- def remote
34
- @remote ||= threescale_client(arguments[:remote])
35
- end
23
+ def run
24
+ printer.print_collection remote.list_services
25
+ end
36
26
 
37
- def print_header
38
- puts SERVICE_FIELDS_TO_SHOW.map { |e| e.upcase }.join("\t")
39
- end
27
+ private
40
28
 
41
- def print_data
42
- services.each do |service|
43
- puts SERVICE_FIELDS_TO_SHOW.map { |field| service.fetch(field, '(empty)') }.join("\t")
44
- end
45
- end
29
+ def remote
30
+ @remote ||= threescale_client(arguments[:remote])
31
+ end
32
+
33
+ def printer
34
+ # keep backwards compatibility
35
+ options.fetch(:output, CLI::CustomTablePrinter.new(FIELDS))
46
36
  end
47
37
  end
48
38
  end
@@ -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
@@ -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,7 +1,10 @@
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
@@ -22,7 +25,7 @@ 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
 
@@ -35,28 +38,27 @@ module ThreeScaleToolbox
35
38
  id: arguments[:dst_service_id],
36
39
  remote: threescale_client(fetch_required_option(:destination))
37
40
  )
38
- system_name = options[:target_system_name]
39
41
  context = create_context(source_service, update_service)
40
42
 
41
43
  tasks = []
42
44
  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)
45
+ tasks << ServiceCommand::CopyServiceSettingsTask.new(context)
46
+ tasks << ThreeScaleToolbox::Commands::ServiceCommand::CopyCommand::CopyMethodsTask.new(context)
47
+ tasks << ThreeScaleToolbox::Commands::ServiceCommand::CopyCommand::CopyMetricsTask.new(context)
48
+ tasks << ThreeScaleToolbox::Commands::ServiceCommand::CopyCommand::CopyApplicationPlansTask.new(context)
49
+ tasks << ThreeScaleToolbox::Commands::ServiceCommand::CopyCommand::CopyLimitsTask.new(context)
50
+ tasks << ThreeScaleToolbox::Commands::ServiceCommand::CopyCommand::CopyPoliciesTask.new(context)
51
+ tasks << ThreeScaleToolbox::Commands::ServiceCommand::CopyCommand::CopyPricingRulesTask.new(context)
52
+ tasks << ServiceCommand::DeleteActiveDocsTask.new(context)
53
+ tasks << ThreeScaleToolbox::Commands::ServiceCommand::CopyCommand::CopyActiveDocsTask.new(context)
52
54
  # Copy proxy must be the last task
53
55
  # Proxy update is the mechanism to increase version of the proxy,
54
56
  # Hence propagating (mapping rules, poicies, oidc, auth) update to
55
57
  # latest proxy config, making available to gateway.
56
- tasks << Tasks::CopyServiceProxyTask.new(context)
58
+ tasks << ThreeScaleToolbox::Commands::ServiceCommand::CopyCommand::CopyServiceProxyTask.new(context)
57
59
  end
58
- tasks << Tasks::DestroyMappingRulesTask.new(context) if options[:force]
59
- tasks << Tasks::CopyMappingRulesTask.new(context)
60
+ tasks << ThreeScaleToolbox::Commands::ServiceCommand::CopyCommand::DestroyMappingRulesTask.new(context)
61
+ tasks << ThreeScaleToolbox::Commands::ServiceCommand::CopyCommand::CopyMappingRulesTask.new(context)
60
62
 
61
63
  # run tasks
62
64
  tasks.each(&:call)
@@ -67,7 +69,8 @@ module ThreeScaleToolbox
67
69
  def create_context(source, target)
68
70
  {
69
71
  source: source,
70
- target: target
72
+ target: target,
73
+ delete_mapping_rules: options[:force]
71
74
  }
72
75
  end
73
76
  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'
@@ -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