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