lib/3scale_toolbox/entities/service.rb in 3scale_toolbox-0.17.1 vs lib/3scale_toolbox/entities/service.rb in 3scale_toolbox-0.18.0
- old
+ new
@@ -1,8 +1,10 @@
module ThreeScaleToolbox
module Entities
class Service
+ include CRD::ProductSerializer
+
VALID_PARAMS = %w[
name backend_version deployment_option description
system_name end_user_registration_required
support_email tech_support_email admin_support_email
].freeze
@@ -27,20 +29,16 @@
rescue ThreeScaleToolbox::InvalidIdError, ThreeScale::API::HttpClient::NotFoundError
find_by_system_name(remote: remote, system_name: ref)
end
def find_by_system_name(remote:, system_name:)
- service_list = remote.list_services
-
- if service_list.respond_to?(:has_key?) && (errors = service_list['errors'])
- raise ThreeScaleToolbox::ThreeScaleApiError.new('Service list not read', errors)
+ attrs = list_services(remote: remote).find do |svc|
+ svc['system_name'] == system_name
end
+ return if attrs.nil?
- service_attrs = service_list.find { |svc| svc['system_name'] == system_name }
- return if service_attrs.nil?
-
- new(id: service_attrs.fetch('id'), remote: remote, attrs: service_attrs)
+ new(id: attrs.fetch('id'), remote: remote, attrs: attrs)
end
private
def create_service(remote:, service:)
@@ -59,10 +57,40 @@
end
def filtered_service_params(original_params)
Helper.filter_params(VALID_PARAMS, original_params)
end
+
+ def list_services(remote:)
+ services_enum(remote: remote).reduce([], :concat)
+ end
+
+ def services_enum(remote:)
+ Enumerator.new do |yielder|
+ page = 1
+ loop do
+ list = remote.list_services(
+ page: page,
+ per_page: ThreeScale::API::MAX_SERVICES_PER_PAGE
+ )
+
+ if list.respond_to?(:has_key?) && (errors = list['errors'])
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Service list not read', errors)
+ end
+
+ break if list.nil?
+
+ yielder << list
+
+ # The API response does not tell how many pages there are available
+ # If one page is not fully filled, it means that it is the last page.
+ break if list.length < ThreeScale::API::MAX_SERVICES_PER_PAGE
+
+ page += 1
+ end
+ end
+ end
end
attr_reader :id, :remote
def initialize(id:, remote:, attrs: nil)
@@ -73,10 +101,30 @@
def attrs
@attrs ||= fetch_attrs
end
+ def system_name
+ attrs['system_name']
+ end
+
+ def name
+ attrs['name']
+ end
+
+ def description
+ attrs['description']
+ end
+
+ def deployment_option
+ attrs['deployment_option']
+ end
+
+ def backend_version
+ attrs['backend_version']
+ end
+
def update_proxy(proxy)
new_proxy_attrs = remote.update_proxy id, proxy
if (errors = new_proxy_attrs['errors'])
raise ThreeScaleToolbox::ThreeScaleApiError.new('Service proxy not updated', errors)
@@ -92,64 +140,74 @@
end
proxy_attrs
end
+ def cached_proxy
+ @cached_proxy ||= proxy
+ end
+
+ # @api public
+ # @return [List]
def metrics
- # cache result to reuse
- metric_and_method_list = metrics_and_methods
- hits_metric_obj = hits_metric(metric_and_method_list)
- hits_id = hits_metric_obj.fetch('id')
+ metric_attr_list = metrics_and_methods.select { |metric_attrs| metric_attrs['parent_id'].nil? }
- ThreeScaleToolbox::Helper.array_difference(metric_and_method_list, methods(hits_id)) do |metric, method|
- ThreeScaleToolbox::Helper.compare_hashes(metric, method, %w[id])
+ metric_attr_list.map do |metric_attrs|
+ Metric.new(id: metric_attrs.fetch('id'), service: self, attrs: metric_attrs)
end
end
def hits
- hits_metric(metrics_and_methods)
+ metric_list = metrics_and_methods.map do |metric_attrs|
+ Metric.new(id: metric_attrs.fetch('id'), service: self, attrs: metric_attrs)
+ end
+ metric_list.find { |metric| metric.system_name == 'hits' }.tap do |hits_metric|
+ raise ThreeScaleToolbox::Error, 'missing hits metric' if hits_metric.nil?
+ end
end
- def methods(parent_metric_id)
- service_methods = remote.list_methods id, parent_metric_id
- if service_methods.respond_to?(:has_key?) && (errors = service_methods['errors'])
+ # @api public
+ # @return [List]
+ def methods
+ method_attr_list = remote.list_methods id, hits.id
+ if method_attr_list.respond_to?(:has_key?) && (errors = method_attr_list['errors'])
raise ThreeScaleToolbox::ThreeScaleApiError.new('Service methods not read', errors)
end
- service_methods
- end
-
- def metrics_and_methods
- m_m = remote.list_metrics id
- if m_m.respond_to?(:has_key?) && (errors = m_m['errors'])
- raise ThreeScaleToolbox::ThreeScaleApiError.new('Service metrics not read', errors)
+ method_attr_list.map do |method_attrs|
+ Method.new(id: method_attrs.fetch('id'),
+ service: self,
+ attrs: method_attrs)
end
-
- m_m
end
def plans
service_plans = remote.list_service_application_plans id
if service_plans.respond_to?(:has_key?) && (errors = service_plans['errors'])
raise ThreeScaleToolbox::ThreeScaleApiError.new('Service plans not read', errors)
end
- service_plans
+ service_plans.map do |plan_attrs|
+ ApplicationPlan.new(id: plan_attrs.fetch('id'),
+ service: self,
+ attrs: plan_attrs)
+ end
end
def mapping_rules
- remote.list_mapping_rules id
- end
+ mr_list = remote.list_mapping_rules id
+ if mr_list.respond_to?(:has_key?) && (errors = mr_list['errors'])
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Service mapping rules not read', errors)
+ end
- def delete_mapping_rule(rule_id)
- remote.delete_mapping_rule(id, rule_id)
+ mr_list.map do |mr_attrs|
+ MappingRule.new(id: mr_attrs.fetch('id'),
+ service: self,
+ attrs: mr_attrs)
+ end
end
- def create_mapping_rule(mapping_rule)
- remote.create_mapping_rule id, mapping_rule
- end
-
def update(svc_attrs)
new_attrs = safe_update(svc_attrs)
if (errors = new_attrs['errors'])
raise ThreeScaleToolbox::ThreeScaleApiError.new('Service not updated', errors)
end
@@ -163,11 +221,16 @@
def delete
remote.delete_service id
end
def policies
- remote.show_policies id
+ policy_chain = remote.show_policies id
+ if policy_chain.respond_to?(:has_key?) && (errors = policy_chain['errors'])
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Service policies not read', errors)
+ end
+
+ policy_chain
end
def update_policies(params)
remote.update_policies(id, params)
end
@@ -177,13 +240,17 @@
if tenant_activedocs.respond_to?(:has_key?) && (errors = tenant_activedocs['errors'])
raise ThreeScaleToolbox::ThreeScaleApiError.new('Service activedocs not read', errors)
end
- tenant_activedocs.select do |activedoc|
- activedoc['service_id'] == id
+ service_activedocs = tenant_activedocs.select do |activedoc_attrs|
+ activedoc_attrs['service_id'] == id
end
+
+ service_activedocs.map do |activedoc_attrs|
+ Entities::ActiveDocs.new(id: activedoc_attrs.fetch('id'), remote: remote, attrs: activedoc_attrs)
+ end
end
def oidc
service_oidc = remote.show_oidc id
@@ -192,10 +259,14 @@
end
service_oidc
end
+ def cached_oidc
+ @cached_oidc ||= oidc
+ end
+
def update_oidc(oidc_settings)
new_oidc = remote.update_oidc(id, oidc_settings)
if (errors = new_oidc['errors'])
raise ThreeScaleToolbox::ThreeScaleApiError.new('Service oicdc not updated', errors)
@@ -260,23 +331,46 @@
product: self,
attrs: backend_usage_attrs)
end
end
- def ==(other)
- remote.http_client.endpoint == other.remote.http_client.endpoint && id == other.id
+ def create_mapping_rule(mr_attrs)
+ Entities::MappingRule.create(service: self, attrs: mr_attrs)
end
- private
+ def proxy_deploy
+ proxy_attrs = remote.proxy_deploy id
+ if proxy_attrs.respond_to?(:has_key?) && (errors = proxy_attrs['errors'])
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Proxy configuration not deployed', errors)
+ end
- def hits_metric(metric_list)
- hits_metric = metric_list.find { |metric| metric['system_name'] == 'hits' }
- raise ThreeScaleToolbox::Error, 'missing hits metric' if hits_metric.nil?
+ proxy_attrs
+ end
- hits_metric
+ # Compute matrics mapping between products, including related backend metrics as well
+ def metrics_mapping(other)
+ mapping = (metrics + methods).product(other.metrics + other.methods).select do |m_a, m_b|
+ m_a.system_name == m_b.system_name
+ end.map { |m_a, m_b| [m_a.id, m_b.id] }.to_h
+
+ backend_pairs = backend_usage_list.map(&:backend).product(other.backend_usage_list.map(&:backend)).select do |b_a, b_b|
+ b_a.system_name == b_b.system_name
+ end
+
+ backend_pairs.each do |b_a, b_b|
+ mapping.merge!(b_a.metrics_mapping(b_b))
+ end
+
+ mapping
end
+ def ==(other)
+ remote.http_client.endpoint == other.remote.http_client.endpoint && id == other.id
+ end
+
+ private
+
def fetch_attrs
raise ThreeScaleToolbox::InvalidIdError if id.zero?
svc = remote.show_service id
if (errors = svc['errors'])
@@ -297,9 +391,18 @@
svc_attrs.delete('deployment_option')
new_attrs = remote.update_service id, svc_attrs
end
new_attrs
+ end
+
+ def metrics_and_methods
+ m_m = remote.list_metrics id
+ if m_m.respond_to?(:has_key?) && (errors = m_m['errors'])
+ raise ThreeScaleToolbox::ThreeScaleApiError.new('Service metrics not read', errors)
+ end
+
+ m_m
end
end
end
end