3scale/porta

View on GitHub
app/models/backend/status.rb

Summary

Maintainability
B
6 hrs
Test Coverage
module Backend
Backend::Status has at least 5 instance variables
class Status
class Record < Struct.new(:usage_limit, :metric_name, :metric_id, :current_value)
delegate :period, :period_as_range, :to => :usage_limit
 
def max_value
usage_limit.value
end
end
 
Method `initialize` has a Cognitive Complexity of 8 (exceeds 5 allowed). Consider refactoring.
def initialize(constant_data = {}, usage_set = nil, options = {})
Backend::Status#initialize refers to 'constant_data' more than self (maybe move it to another class?)
@records = (constant_data[:usage_limits] || []).map do |usage_limit|
value = usage_set &&
Backend::Status#initialize calls 'usage_set[usage_limit.period]' 2 times
Backend::Status#initialize calls 'usage_limit.period' 2 times
usage_set[usage_limit.period] &&
Backend::Status#initialize calls 'usage_limit.metric_id' 4 times
usage_set[usage_limit.period][usage_limit.metric_id] ||
0
 
# TODO: this reverse lookup is not optimal. Not a big deal because there is
# usually not that many metrics, but still would be nice to optimize it.
# Perhaps by also storing hash of metric names mapped to ids in constant_data.
# FIXME: no idea why this can be an array...
Backend::Status#initialize manually dispatches method call
Backend::Status#initialize calls 'constant_data[:metric_ids]' 3 times
metric_name = if constant_data[:metric_ids].respond_to?(:index) # this works for arrays and 1.8 hashes
constant_data[:metric_ids].index(usage_limit.metric_id)
else # 1.9 hash
constant_data[:metric_ids].key(usage_limit.metric_id)
end
 
Record.new(usage_limit, metric_name, usage_limit.metric_id, value)
end
 
if options[:include_plan_name]
@plan_name = constant_data[:plan_name]
end
 
if options[:show_eternity]
@show_eternity = true
@service_id = constant_data[:service_id]
@application_id = constant_data[:application_id]
end
end
 
attr_reader :records, :plan_name
 
Method `to_xml` has a Cognitive Complexity of 29 (exceeds 5 allowed). Consider refactoring.
Method `to_xml` has 32 lines of code (exceeds 25 allowed). Consider refactoring.
Backend::Status#to_xml has approx 20 statements
def to_xml(options = {})
xml = options[:builder] || ThreeScale::XML::Builder.new
 
xml.status do |xml|
xml.plan(plan_name) if plan_name
 
if @show_eternity
redis_url = "stats/{service:#{@service_id}}/cinstance:#{@application_id}"
#OPTIMIZE: there's surely a ruby cond to records.uniq{|r| r.metric_id} to
# get uniq metrics inside records
etern_ids = []
end
 
records.each do |record|
Backend::Status#to_xml refers to 'record' more than self (maybe move it to another class?)
Backend::Status#to_xml contains iterators nested 3 deep
Backend::Status#to_xml calls 'record.period' 3 times
Backend::Status#to_xml calls 'record.metric_name' 2 times
xml.usage(:metric => record.metric_name, :period => record.period) do |xml|
Backend::Status#to_xml calls 'record.period_as_range' 2 times
Backend::Status#to_xml calls 'record.period == :eternity' 2 times
xml.period_start(record.period_as_range.begin.to_fs(:db)) unless record.period == :eternity
xml.period_end(record.period_as_range.end.to_fs(:db)) unless record.period == :eternity
xml.current_value(record.current_value)
xml.max_value(record.max_value)
end
 
#TODO: this needs tests!
if @show_eternity
Backend::Status#to_xml calls 'record.metric_id' 3 times
unless etern_ids.include?(record.metric_id)
etern_ids << record.metric_id
 
xml.usage(:metric => record.metric_name, :period => 'eternity') do |xml|
etern_url = redis_url + "/metric:#{record.metric_id}/eternity"
begin
puts "[redis] eternity url #{etern_url}"
xml.current_value Backend::Transaction.storage.get(etern_url).to_i
Backend::Status#to_xml has the variable name 'e'
rescue Exception => e
puts "[redis FAIL] eternity url #{etern_url} -- Exception #{e.inspect}"
xml.current_value -1
end
end
 
end
end
end
end
 
xml.to_xml
end
end
end