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
@@ -0,0 +1,76 @@
1
+ module ThreeScaleToolbox
2
+ module Entities
3
+ class BackendMappingRule
4
+ VALID_PARAMS = %w[metric_id pattern http_method delta position last].freeze
5
+ public_constant :VALID_PARAMS
6
+
7
+ class << self
8
+ def create(backend:, attrs:)
9
+ mapping_rule = backend.remote.create_backend_mapping_rule(
10
+ backend.id,
11
+ Helper.filter_params(VALID_PARAMS, attrs)
12
+ )
13
+ if (errors = mapping_rule['errors'])
14
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Backend mapping rule has not been created',
15
+ errors)
16
+ end
17
+
18
+ new(id: mapping_rule.fetch('id'), backend: backend, attrs: mapping_rule)
19
+ end
20
+ end
21
+
22
+ attr_reader :id, :backend, :remote
23
+
24
+ def initialize(id:, backend:, attrs: nil)
25
+ @id = id.to_i
26
+ @backend = backend
27
+ @remote = backend.remote
28
+ @attrs = attrs
29
+ end
30
+
31
+ def attrs
32
+ @attrs ||= mapping_rule_attrs
33
+ end
34
+
35
+ def metric_id
36
+ @attrs['metric_id']
37
+ end
38
+
39
+ def metric_id=(metric_id)
40
+ @attrs['metric_id'] = metric_id
41
+ end
42
+
43
+ def update(mr_attrs)
44
+ new_attrs = remote.update_backend_mapping_rule(
45
+ backend.id, id,
46
+ Helper.filter_params(VALID_PARAMS, mr_attrs)
47
+ )
48
+ if (errors = new_attrs['errors'])
49
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Backend mapping rule has not been updated', errors)
50
+ end
51
+
52
+ # update current attrs
53
+ @attrs = new_attrs
54
+
55
+ new_attrs
56
+ end
57
+
58
+ def delete
59
+ remote.delete_backend_mapping_rule backend.id, id
60
+ end
61
+
62
+ private
63
+
64
+ def mapping_rule_attrs
65
+ raise ThreeScaleToolbox::InvalidIdError if id.zero?
66
+
67
+ mapping_rule = remote.backend_mapping_rule backend.id, id
68
+ if (errors = mapping_rule['errors'])
69
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Backend mapping rule not read', errors)
70
+ end
71
+
72
+ mapping_rule
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,90 @@
1
+ module ThreeScaleToolbox
2
+ module Entities
3
+ class BackendMethod
4
+ VALID_PARAMS = %w[friendly_name system_name description].freeze
5
+ public_constant :VALID_PARAMS
6
+
7
+ class << self
8
+ def create(backend:, parent_id:, attrs:)
9
+ method = backend.remote.create_backend_method(backend.id, parent_id,
10
+ Helper.filter_params(VALID_PARAMS, attrs))
11
+ if (errors = method['errors'])
12
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Backend Method has not been created',
13
+ errors)
14
+ end
15
+
16
+ new(id: method.fetch('id'), parent_id: parent_id, backend: backend, attrs: method)
17
+ end
18
+
19
+ # ref can be system_name or method_id
20
+ def find(backend:, parent_id:, ref:)
21
+ new(id: ref, parent_id: parent_id, backend: backend).tap(&:attrs)
22
+ rescue ThreeScaleToolbox::InvalidIdError, ThreeScale::API::HttpClient::NotFoundError
23
+ find_by_system_name(backend: backend, parent_id: parent_id, system_name: ref)
24
+ end
25
+
26
+ def find_by_system_name(backend:, parent_id:, system_name:)
27
+ backend.methods(parent_id).find { |m| m.system_name == system_name }
28
+ end
29
+ end
30
+
31
+ attr_reader :id, :parent_id, :backend, :remote
32
+
33
+ def initialize(id:, parent_id:, backend:, attrs: nil)
34
+ @id = id.to_i
35
+ @backend = backend
36
+ @parent_id = parent_id
37
+ @remote = backend.remote
38
+ @attrs = process_attrs(attrs)
39
+ end
40
+
41
+ def attrs
42
+ @attrs ||= process_attrs(method_attrs)
43
+ end
44
+
45
+ def system_name
46
+ @attrs['system_name']
47
+ end
48
+
49
+ def friendly_name
50
+ @attrs['friendly_name']
51
+ end
52
+
53
+ def update(m_attrs)
54
+ new_attrs = remote.update_backend_method(backend.id, parent_id, id,
55
+ Helper.filter_params(VALID_PARAMS, m_attrs))
56
+ if (errors = new_attrs['errors'])
57
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Backend Method has not been updated',
58
+ errors)
59
+ end
60
+
61
+ # update current attrs
62
+ @attrs = process_attrs(new_attrs)
63
+ end
64
+
65
+ def delete
66
+ remote.delete_backend_method backend.id, parent_id, id
67
+ end
68
+
69
+ private
70
+
71
+ def process_attrs(metric_attrs)
72
+ return if metric_attrs.nil?
73
+
74
+ # system_name: my_metric_02.45498 -> system_name: my_metric_02
75
+ metric_attrs.merge('system_name' => metric_attrs.fetch('system_name', '').partition('.').first)
76
+ end
77
+
78
+ def method_attrs
79
+ raise ThreeScaleToolbox::InvalidIdError if id.zero?
80
+
81
+ method = remote.backend_method backend.id, parent_id, id
82
+ if (errors = method['errors'])
83
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Backend method not read', errors)
84
+ end
85
+
86
+ method
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,88 @@
1
+ module ThreeScaleToolbox
2
+ module Entities
3
+ class BackendMetric
4
+ VALID_PARAMS = %w[friendly_name system_name unit description].freeze
5
+ public_constant :VALID_PARAMS
6
+
7
+ class << self
8
+ def create(backend:, attrs:)
9
+ metric = backend.remote.create_backend_metric(backend.id,
10
+ Helper.filter_params(VALID_PARAMS, attrs))
11
+ if (errors = metric['errors'])
12
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Backend metric has not been created',
13
+ errors)
14
+ end
15
+
16
+ new(id: metric.fetch('id'), backend: backend, attrs: metric)
17
+ end
18
+
19
+ # ref can be system_name or metric_id
20
+ def find(backend:, ref:)
21
+ new(id: ref, backend: backend).tap(&:attrs)
22
+ rescue ThreeScaleToolbox::InvalidIdError, ThreeScale::API::HttpClient::NotFoundError
23
+ find_by_system_name(backend: backend, system_name: ref)
24
+ end
25
+
26
+ def find_by_system_name(backend:, system_name:)
27
+ backend.metrics.find { |m| m.system_name == system_name }
28
+ end
29
+ end
30
+
31
+ attr_reader :id, :backend, :remote
32
+
33
+ def initialize(id:, backend:, attrs: nil)
34
+ @id = id.to_i
35
+ @backend = backend
36
+ @remote = backend.remote
37
+ @attrs = process_attrs(attrs)
38
+ end
39
+
40
+ def attrs
41
+ @attrs ||= process_attrs(metric_attrs)
42
+ end
43
+
44
+ def system_name
45
+ @attrs['system_name']
46
+ end
47
+
48
+ def friendly_name
49
+ @attrs['friendly_name']
50
+ end
51
+
52
+ def update(m_attrs)
53
+ new_attrs = remote.update_backend_metric(backend.id, id,
54
+ Helper.filter_params(VALID_PARAMS, m_attrs))
55
+ if (errors = new_attrs['errors'])
56
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Backend metric has not been updated', errors)
57
+ end
58
+
59
+ # update current attrs
60
+ @attrs = process_attrs(new_attrs)
61
+ end
62
+
63
+ def delete
64
+ remote.delete_backend_metric backend.id, id
65
+ end
66
+
67
+ private
68
+
69
+ def process_attrs(metric_attrs)
70
+ return if metric_attrs.nil?
71
+
72
+ # system_name: my_metric_02.45498 -> system_name: my_metric_02
73
+ metric_attrs.merge('system_name' => metric_attrs.fetch('system_name', '').partition('.').first)
74
+ end
75
+
76
+ def metric_attrs
77
+ raise ThreeScaleToolbox::InvalidIdError if id.zero?
78
+
79
+ metric = remote.backend_metric backend.id, id
80
+ if (errors = metric['errors'])
81
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Backend metric not read', errors)
82
+ end
83
+
84
+ metric
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,99 @@
1
+ module ThreeScaleToolbox
2
+ module Entities
3
+ ##
4
+ # BackendUsage represents Product - Backend mapping entry
5
+ class BackendUsage
6
+ CREATE_PARAMS = %w[path backend_api_id].freeze
7
+ public_constant :CREATE_PARAMS
8
+ UPDATE_PARAMS = %w[path].freeze
9
+ public_constant :UPDATE_PARAMS
10
+
11
+ class << self
12
+ def create(product:, attrs:)
13
+ resp = product.remote.create_backend_usage(
14
+ product.id,
15
+ Helper.filter_params(CREATE_PARAMS, attrs)
16
+ )
17
+ if (errors = resp['errors'])
18
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Backend usage has not been created',
19
+ errors)
20
+ end
21
+
22
+ new(id: resp.fetch('id'), product: product, attrs: resp)
23
+ end
24
+
25
+ def find_by_path(product:, path:)
26
+ resp = product.remote.list_backend_usages product.id
27
+ if resp.respond_to?(:has_key?) && (errors = resp['errors'])
28
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Backend usage list error', errors)
29
+ end
30
+
31
+ backend_usage_attrs = resp.find { |bus| bus['path'] == path }
32
+ return if backend_usage_attrs.nil?
33
+
34
+ new(id: backend_usage_attrs.fetch('id'), product: product, attrs: backend_usage_attrs)
35
+ end
36
+ end
37
+
38
+ attr_reader :id, :product, :remote
39
+
40
+ def initialize(id:, product:, attrs: nil)
41
+ @id = id.to_i
42
+ @product = product
43
+ @remote = product.remote
44
+ @attrs = attrs
45
+ end
46
+
47
+ def attrs
48
+ @attrs ||= fetch_attrs
49
+ end
50
+
51
+ def path
52
+ attrs['path']
53
+ end
54
+
55
+ def backend_id
56
+ # 3scale API returns 'backend_id'
57
+ # 3scale API only accepts 'backend_api_id' as params
58
+ # good job
59
+ attrs['backend_id']
60
+ end
61
+
62
+ def update(usage_attrs)
63
+ new_attrs = remote.update_backend_usage(
64
+ product.id, id,
65
+ Helper.filter_params(UPDATE_PARAMS, usage_attrs)
66
+ )
67
+ if (errors = new_attrs['errors'])
68
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Backend usage not been updated', errors)
69
+ end
70
+
71
+ if new_attrs['service_id'] != product.id
72
+ raise ThreeScaleToolbox::Error, 'Backend usage product updated'
73
+ end
74
+
75
+ # update current attrs
76
+ @attrs = new_attrs
77
+
78
+ new_attrs
79
+ end
80
+
81
+ def delete
82
+ remote.delete_backend_usage product.id, id
83
+ end
84
+
85
+ private
86
+
87
+ def fetch_attrs
88
+ raise ThreeScaleToolbox::InvalidIdError if id.zero?
89
+
90
+ resp = remote.backend_usage product.id, id
91
+ if (errors = resp['errors'])
92
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Product backend usage not read', errors)
93
+ end
94
+
95
+ resp
96
+ end
97
+ end
98
+ end
99
+ end
@@ -24,7 +24,7 @@ module ThreeScaleToolbox
24
24
  # ref can be system_name or service_id
25
25
  def find(remote:, ref:)
26
26
  new(id: ref, remote: remote).tap(&:attrs)
27
- rescue ThreeScale::API::HttpClient::NotFoundError
27
+ rescue ThreeScaleToolbox::InvalidIdError, ThreeScale::API::HttpClient::NotFoundError
28
28
  find_by_system_name(remote: remote, system_name: ref)
29
29
  end
30
30
 
@@ -72,7 +72,7 @@ module ThreeScaleToolbox
72
72
  end
73
73
 
74
74
  def attrs
75
- @attrs ||= service_attrs
75
+ @attrs ||= fetch_attrs
76
76
  end
77
77
 
78
78
  def update_proxy(proxy)
@@ -249,6 +249,19 @@ module ThreeScaleToolbox
249
249
  end
250
250
  end
251
251
 
252
+ def backend_usage_list
253
+ resp = remote.list_backend_usages id
254
+ if resp.respond_to?(:has_key?) && (errors = resp['errors'])
255
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Product backend usage not read', errors)
256
+ end
257
+
258
+ resp.map do |backend_usage_attrs|
259
+ Entities::BackendUsage.new(id: backend_usage_attrs.fetch('id'),
260
+ product: self,
261
+ attrs: backend_usage_attrs)
262
+ end
263
+ end
264
+
252
265
  def ==(other)
253
266
  remote.http_client.endpoint == other.remote.http_client.endpoint && id == other.id
254
267
  end
@@ -262,7 +275,9 @@ module ThreeScaleToolbox
262
275
  hits_metric
263
276
  end
264
277
 
265
- def service_attrs
278
+ def fetch_attrs
279
+ raise ThreeScaleToolbox::InvalidIdError if id.zero?
280
+
266
281
  svc = remote.show_service id
267
282
  if (errors = svc['errors'])
268
283
  raise ThreeScaleToolbox::ThreeScaleApiError.new('Service attrs not read', errors)
@@ -1,9 +1,24 @@
1
1
  module ThreeScaleToolbox
2
2
  # Generic error. Superclass for all specific errors.
3
3
  class Error < ::StandardError
4
+ def code
5
+ 'E_3SCALE'
6
+ end
7
+
8
+ def kind
9
+ self.class
10
+ end
11
+
12
+ def stacktrace
13
+ # For managed errors, stacktrace should not be necessary
14
+ nil
15
+ end
4
16
  end
5
17
 
6
18
  class InvalidUrlError < Error
19
+ def code
20
+ 'E_INVALID_URL'
21
+ end
7
22
  end
8
23
 
9
24
  class ActiveDocsNotFoundError < Error
@@ -12,6 +27,10 @@ module ThreeScaleToolbox
12
27
  def initialize(id)
13
28
  super("ActiveDocs with ID #{id} not found")
14
29
  end
30
+
31
+ def code
32
+ 'E_ACTIVEDOCS_NOT_FOUND'
33
+ end
15
34
  end
16
35
 
17
36
  class ThreeScaleApiError < Error
@@ -25,5 +44,39 @@ module ThreeScaleToolbox
25
44
  def message
26
45
  "#{super}. Errors: #{apierrors}"
27
46
  end
47
+
48
+ def code
49
+ 'E_3SCALE_API'
50
+ end
51
+ end
52
+
53
+ class InvalidIdError < Error
54
+ def code
55
+ 'E_INVALID_ID'
56
+ end
57
+ end
58
+
59
+ class UnexpectedError < ::StandardError
60
+ attr_reader :unexpectederror
61
+
62
+ def initialize(err)
63
+ @unexpectederror = err
64
+ end
65
+
66
+ def message
67
+ unexpectederror.message
68
+ end
69
+
70
+ def kind
71
+ unexpectederror.class
72
+ end
73
+
74
+ def code
75
+ 'E_UNKNOWN'
76
+ end
77
+
78
+ def stacktrace
79
+ unexpectederror.backtrace
80
+ end
28
81
  end
29
82
  end