Class: ThreeScaleToolbox::Entities::ApplicationPlan

Inherits:
Object
  • Object
show all
Includes:
CRD::ApplicationPlanSerializer
Defined in:
lib/3scale_toolbox/entities/application_plan.rb

Constant Summary collapse

APP_PLANS_BLACKLIST =
%w[id links default custom created_at updated_at].freeze
PLAN_FEATURE_BLACKLIST =
%w[id links created_at updated_at].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from CRD::ApplicationPlanSerializer

#to_cr

Constructor Details

#initialize(id:, service:, attrs: nil) ⇒ ApplicationPlan

Returns a new instance of ApplicationPlan.



43
44
45
46
47
48
# File 'lib/3scale_toolbox/entities/application_plan.rb', line 43

def initialize(id:, service:, attrs: nil)
  @id = id.to_i
  @service = service
  @remote = service.remote
  @attrs = attrs
end

Instance Attribute Details

#idObject (readonly)

Returns the value of attribute id.



41
42
43
# File 'lib/3scale_toolbox/entities/application_plan.rb', line 41

def id
  @id
end

#remoteObject (readonly)

Returns the value of attribute remote.



41
42
43
# File 'lib/3scale_toolbox/entities/application_plan.rb', line 41

def remote
  @remote
end

#serviceObject (readonly)

Returns the value of attribute service.



41
42
43
# File 'lib/3scale_toolbox/entities/application_plan.rb', line 41

def service
  @service
end

Class Method Details

.create(service:, plan_attrs:) ⇒ Object



10
11
12
13
14
15
16
17
# File 'lib/3scale_toolbox/entities/application_plan.rb', line 10

def create(service:, plan_attrs:)
  plan = service.remote.create_application_plan service.id, create_plan_attrs(plan_attrs)
  if (errors = plan['errors'])
    raise ThreeScaleToolbox::ThreeScaleApiError.new('Application plan has not been created', errors)
  end

  new(id: plan.fetch('id'), service: service, attrs: plan)
end

.create_plan_attrs(source_attrs) ⇒ Object



30
31
32
33
34
35
36
37
38
# File 'lib/3scale_toolbox/entities/application_plan.rb', line 30

def create_plan_attrs(source_attrs)
  # shallow copy is enough
  source_attrs.clone.tap do |new_plan_attrs|
    # plans are created by default in hidden state
    # If published is required, 'state_event' attr has to be added
    state = new_plan_attrs.delete('state')
    new_plan_attrs['state_event'] = 'publish' if state == 'published'
  end
end

.find(service:, ref:) ⇒ Object

ref can be system_name or service_id



20
21
22
23
24
# File 'lib/3scale_toolbox/entities/application_plan.rb', line 20

def find(service:, ref:)
  new(id: ref, service: service).tap(&:attrs)
rescue ThreeScaleToolbox::InvalidIdError, ThreeScale::API::HttpClient::NotFoundError
  find_by_system_name(service: service, system_name: ref)
end

.find_by_system_name(service:, system_name:) ⇒ Object



26
27
28
# File 'lib/3scale_toolbox/entities/application_plan.rb', line 26

def find_by_system_name(service:, system_name:)
  service.plans.find { |p| p.system_name == system_name }
end

Instance Method Details

#applicationsObject



184
185
186
187
188
189
190
191
192
193
# File 'lib/3scale_toolbox/entities/application_plan.rb', line 184

def applications
  app_attrs_list = remote.list_applications(service_id: service.id, plan_id: id)
  if app_attrs_list.respond_to?(:has_key?) && (errors = app_attrs_list['errors'])
    raise ThreeScaleToolbox::ThreeScaleApiError.new('Plan applications not read', errors)
  end

  app_attrs_list.map do |app_attrs|
    Entities::Application.new(id: app_attrs.fetch('id'), remote: remote, attrs: app_attrs)
  end
end

#approval_required?Boolean

Returns:

  • (Boolean)


199
200
201
# File 'lib/3scale_toolbox/entities/application_plan.rb', line 199

def approval_required?
  attrs.fetch('approval_required', true)
end

#attrsObject



50
51
52
# File 'lib/3scale_toolbox/entities/application_plan.rb', line 50

def attrs
  @attrs ||= read_plan_attrs
end

#cost_per_monthObject



211
212
213
# File 'lib/3scale_toolbox/entities/application_plan.rb', line 211

def cost_per_month
  attrs.fetch('cost_per_month', 0.0)
end

#create_feature(feature_id) ⇒ Object



170
171
172
173
174
175
176
177
178
# File 'lib/3scale_toolbox/entities/application_plan.rb', line 170

def create_feature(feature_id)
  feature = remote.create_application_plan_feature id, feature_id

  if (errors = feature['errors'])
    raise ThreeScaleToolbox::ThreeScaleApiError.new('feature not created', errors)
  end

  feature
end

#create_limit(metric_id, limit_attrs) ⇒ Object



140
141
142
# File 'lib/3scale_toolbox/entities/application_plan.rb', line 140

def create_limit(metric_id, limit_attrs)
  Limit.create(plan: self, metric_id: metric_id, attrs: limit_attrs)
end

#create_pricing_rule(metric_id, pr_attrs) ⇒ Object



144
145
146
# File 'lib/3scale_toolbox/entities/application_plan.rb', line 144

def create_pricing_rule(metric_id, pr_attrs)
  PricingRule.create(plan: self, metric_id: metric_id, attrs: pr_attrs)
end

#customObject



66
67
68
# File 'lib/3scale_toolbox/entities/application_plan.rb', line 66

def custom
  attrs.fetch('custom', false)
end

#deleteObject



180
181
182
# File 'lib/3scale_toolbox/entities/application_plan.rb', line 180

def delete
  remote.delete_application_plan service.id, id
end

#disableObject



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/3scale_toolbox/entities/application_plan.rb', line 93

def disable
  # Split metrics into three groups:
  # a) metrics having limits set with eternity period and zero value, nothing to do.
  # b) metrics having limits set with eternity period, but not zero value, must be updated
  # c) metrics not having limits set with eternity period, must be created

  eternity_limits = limits.select { |limit| limit.period == 'eternity' }
  eternity_metric_ids = eternity_limits.map { |limit| limit.metric_id }
  service_metric_ids = service.metrics.map { |metric| metric.id }
  metric_ids_without_eternity = service_metric_ids - eternity_metric_ids

  # create eternity zero limit for each metric without eternity limit set
  metric_ids_without_eternity.each do |metric_id|
    create_limit(metric_id, zero_eternity_limit_attrs)
  end

  # update eternity zero limit those metrics already having eternity limit set
  not_zero_eternity_limits = eternity_limits.reject { |limit| limit.value.zero? }
  not_zero_eternity_limits.each do |limit|
    limit.update(zero_eternity_limit_attrs)
  end
end

#enableObject



116
117
118
# File 'lib/3scale_toolbox/entities/application_plan.rb', line 116

def enable
  eternity_zero_limits.each(&:delete)
end

#featuresObject



160
161
162
163
164
165
166
167
168
# File 'lib/3scale_toolbox/entities/application_plan.rb', line 160

def features
  feature_list = remote.list_features_per_application_plan id

  if feature_list.respond_to?(:has_key?) && (errors = feature_list['errors'])
    raise ThreeScaleToolbox::ThreeScaleApiError.new('features not read', errors)
  end

  feature_list
end

#limitsObject



120
121
122
123
124
125
126
127
128
129
# File 'lib/3scale_toolbox/entities/application_plan.rb', line 120

def limits
  plan_limits = remote.list_application_plan_limits id
  if plan_limits.respond_to?(:has_key?) && (errors = plan_limits['errors'])
    raise ThreeScaleToolbox::ThreeScaleApiError.new('Limits per application plan not read', errors)
  end

  plan_limits.map do |limit_attrs|
    Limit.new(id: limit_attrs.fetch('id'), plan: self, metric_id: limit_attrs.fetch('metric_id'), attrs: limit_attrs)
  end
end

#make_defaultObject



84
85
86
87
88
89
90
91
# File 'lib/3scale_toolbox/entities/application_plan.rb', line 84

def make_default
  plan = remote.application_plan_as_default service.id, id
  if (errors = plan['errors'])
    raise ThreeScaleToolbox::ThreeScaleApiError.new('Application plan has not been set to default', errors)
  end

  plan
end

#metric_limits(metric_id) ⇒ Object



131
132
133
134
135
136
137
138
# File 'lib/3scale_toolbox/entities/application_plan.rb', line 131

def metric_limits(metric_id)
  # remote.list_metric_limits(plan_id, metric_id) returns all limits for a given metric,
  # without filtering by app plan
  # Already reported. https://issues.jboss.org/browse/THREESCALE-2486
  # Meanwhile, the strategy will be to get all metrics from a given plan
  # and filter by metric_id
  limits.select { |limit| limit.metric_id == metric_id }
end

#nameObject



58
59
60
# File 'lib/3scale_toolbox/entities/application_plan.rb', line 58

def name
  attrs['name']
end

#pricing_rulesObject



148
149
150
151
152
153
154
155
156
157
158
# File 'lib/3scale_toolbox/entities/application_plan.rb', line 148

def pricing_rules
  pr_list = remote.list_pricingrules_per_application_plan id

  if pr_list.respond_to?(:has_key?) && (errors = pr_list['errors'])
    raise ThreeScaleToolbox::ThreeScaleApiError.new('pricing rules not read', errors)
  end

  pr_list.map do |pr_attrs|
    PricingRule.new(id: pr_attrs.fetch('id'), plan: self, metric_id: pr_attrs.fetch('metric_id'), attrs: pr_attrs)
  end
end

#published?Boolean

Returns:

  • (Boolean)


195
196
197
# File 'lib/3scale_toolbox/entities/application_plan.rb', line 195

def published?
  attrs.fetch('state') == 'published'
end

#setup_feeObject



207
208
209
# File 'lib/3scale_toolbox/entities/application_plan.rb', line 207

def setup_fee
  attrs.fetch('setup_fee', 0.0)
end

#stateObject



62
63
64
# File 'lib/3scale_toolbox/entities/application_plan.rb', line 62

def state
  attrs['state']
end

#system_nameObject



54
55
56
# File 'lib/3scale_toolbox/entities/application_plan.rb', line 54

def system_name
  attrs['system_name']
end

#to_hashObject



215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/3scale_toolbox/entities/application_plan.rb', line 215

def to_hash
  {
    'plan' => attrs.reject { |key, _| APP_PLANS_BLACKLIST.include? key },
    'limits' => limits.map(&:to_hash),
    'pricingrules' => pricing_rules.map(&:to_hash),
    'plan_features' => features.map do |feature|
        feature.reject { |key, _| PLAN_FEATURE_BLACKLIST.include? key }
    end,
    'metrics' => uniq_metrics_to_hash,
    'methods' => uniq_methods_to_hash,
  }
end

#trial_period_daysObject



203
204
205
# File 'lib/3scale_toolbox/entities/application_plan.rb', line 203

def trial_period_days
  attrs.fetch('trial_period_days', 0)
end

#update(plan_attrs) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/3scale_toolbox/entities/application_plan.rb', line 70

def update(plan_attrs)
  return attrs if update_plan_attrs(plan_attrs).empty?

  new_attrs = remote.update_application_plan(service.id, id,
                                             update_plan_attrs(plan_attrs))
  if (errors = new_attrs['errors'])
    raise ThreeScaleToolbox::ThreeScaleApiError.new('Application plan has not been updated', errors)
  end

  @attrs = new_attrs

  new_attrs
end