lib/3scale/client.rb in 3scale_client-2.7.0 vs lib/3scale/client.rb in 3scale_client-2.8.0
- old
+ new
@@ -39,10 +39,16 @@
# end
#
class Client
DEFAULT_HOST = 'su1.3scale.net'
+ DEPRECATION_MSG_OLD_REPORT = 'warning: def report(*transactions) is '\
+ 'deprecated. In next versions, the signature of the report method is '\
+ 'going to be: '\
+ 'def report(transactions: [], service_id: nil).'.freeze
+ private_constant :DEPRECATION_MSG_OLD_REPORT
+
def initialize(options)
if options[:provider_key].nil? || options[:provider_key] =~ /^\s*$/
raise ArgumentError, 'missing :provider_key'
end
@@ -67,16 +73,11 @@
options.each_pair do |param, value|
path += "&#{param}=#{CGI.escape(value.to_s)}"
end
options_usage ||= {:hits => 1}
- usage = []
- options_usage.each_pair do |metric, value|
- escaped_metric = CGI.escape "[usage][#{metric}]"
- usage << "#{escaped_metric}=#{CGI.escape(value.to_s)}"
- end
- path += "&#{usage.join('&')}"
+ path += "&#{usage_query_params(options_usage)}"
if options_log
log = []
options_log.each_pair do |key, value|
escaped_key = CGI.escape "[log][#{key}]"
@@ -99,25 +100,27 @@
# Report transaction(s).
#
# == Parameters
#
- # The parameters the transactions to report. Each transaction is a hash with
- # these elements:
+ # Hash with two fields:
#
- # app_id:: ID of the application to report the transaction for. This parameter is
- # required.
- # usage:: Hash of usage values. The keys are metric names and values are
- # correspoding numeric values. Example: {'hits' => 1, 'transfer' => 1024}.
- # This parameter is required.
- # timestamp:: Timestamp of the transaction. This can be either a object of the
- # ruby's Time class, or a string in the "YYYY-MM-DD HH:MM:SS" format
- # (if the time is in the UTC), or a string in
- # the "YYYY-MM-DD HH:MM:SS ZZZZZ" format, where the ZZZZZ is the time offset
- # from the UTC. For example, "US Pacific Time" has offset -0800, "Tokyo"
- # has offset +0900. This parameter is optional, and if not provided, equals
- # to the current time.
+ # transactions:: It is required. It is an enumerable. Each element is a hash with the fields:
+ # app_id: ID of the application to report the transaction for. This parameter is
+ # required.
+ # usage: Hash of usage values. The keys are metric names and values are
+ # corresponding numeric values. Example: {'hits' => 1, 'transfer' => 1024}.
+ # This parameter is required.
+ # timestamp: Timestamp of the transaction. This can be either a object of the
+ # ruby's Time class, or a string in the "YYYY-MM-DD HH:MM:SS" format
+ # (if the time is in the UTC), or a string in
+ # the "YYYY-MM-DD HH:MM:SS ZZZZZ" format, where the ZZZZZ is the time offset
+ # from the UTC. For example, "US Pacific Time" has offset -0800, "Tokyo"
+ # has offset +0900. This parameter is optional, and if not provided, equals
+ # to the current time.
+ # service_id:: ID of the service. It is optional. When not specified, the transactions
+ # are reported to the default service.
#
# == Return
#
# A Response object with method +success?+ that returns true if the report was successful,
# or false if there was an error. See ThreeScale::Response class for more information.
@@ -125,24 +128,43 @@
# In case of unexpected internal server error, this method raises a ThreeScale::ServerError
# exception.
#
# == Examples
#
- # # Report two transactions of two applications.
- # client.report({:app_id => 'foo', :usage => {'hits' => 1}},
- # {:app_id => 'bar', :usage => {'hits' => 1}})
+ # Report two transactions of two applications. Using the default service.
+ # client.report(transactions: [{:app_id => 'foo', :usage => {'hits' => 1}},
+ # {:app_id => 'bar', :usage => {'hits' => 1}}])
#
- # # Report one transaction with timestamp.
- # client.report({:app_id => 'foo',
- # :timestamp => Time.local(2010, 4, 27, 15, 14),
- # :usage => {'hits' => 1})
+ # Report one transaction with timestamp. Using the default service.
+ # client.report(transactions: [{:app_id => 'foo',
+ # :timestamp => Time.local(2010, 4, 27, 15, 14),
+ # :usage => {'hits' => 1}])
#
- def report(*transactions)
- raise ArgumentError, 'no transactions to report' if transactions.empty?
+ # Report a transaction specifying the service.
+ # client.report(transactions: [{:app_id => 'foo', :usage => {'hits' => 1}}],
+ # service_id: 'a_service_id')
+ #
+ # == Note
+ #
+ # The signature of this method is a bit complicated because we decided to
+ # keep backwards compatibility with a previous version of the method:
+ # def report(*transactions)
+ def report(*reports, transactions: [], service_id: nil, **rest)
+ if (!transactions || transactions.empty?) && rest.empty?
+ raise ArgumentError, 'no transactions to report'
+ end
+ transactions = transactions.concat(reports)
+
+ unless rest.empty?
+ warn(DEPRECATION_MSG_OLD_REPORT)
+ transactions.concat([rest])
+ end
+
payload = encode_transactions(transactions)
payload['provider_key'] = CGI.escape(provider_key)
+ payload['service_id'] = CGI.escape(service_id.to_s) if service_id
http_response = @http.post('/transactions.xml', payload)
case http_response
when Net::HTTPSuccess
@@ -162,10 +184,13 @@
#
# app_id:: id of the application to authorize. This is required.
# app_key:: secret key assigned to the application. Required only if application has
# a key defined.
# service_id:: id of the service (required if you have more than one service)
+ # usage:: predicted usage. It is optional. It is a hash where the keys are metrics
+ # and the values their predicted usage.
+ # Example: {'hits' => 1, 'my_metric' => 100}
#
# == Return
#
# An ThreeScale::AuthorizeResponse object. It's +success?+ method returns true if
# the authorization is successful, false otherwise. It contains additional information
@@ -205,10 +230,13 @@
#
# Hash with options:
#
# app_id:: id of the application to authorize. This is required.
# service_id:: id of the service (required if you have more than one service)
+ # usage:: predicted usage. It is optional. It is a hash where the keys are metrics
+ # and the values their predicted usage.
+ # Example: {'hits' => 1, 'my_metric' => 100}
#
# == Return
#
# A ThreeScale::AuthorizeResponse object. It's +success?+ method returns true if
# the authorization is successful, false otherwise. It contains additional information
@@ -245,26 +273,33 @@
end
end
private
- OAUTH_PARAMS = [:app_id, :app_key, :service_id, :redirect_url]
- ALL_PARAMS = [:user_key, :app_id, :app_key, :service_id, :redirect_url]
+ OAUTH_PARAMS = [:app_id, :app_key, :service_id, :redirect_url, :usage]
+ ALL_PARAMS = [:user_key, :app_id, :app_key, :service_id, :redirect_url, :usage]
REPORT_PARAMS = [:user_key, :app_id, :service_id, :timestamp]
def options_to_params(options, allowed_keys)
params = { :provider_key => provider_key }
- allowed_keys.each do |key|
+ (allowed_keys - [:usage]).each do |key|
params[key] = options[key] if options.has_key?(key)
end
tuples = params.map do |key, value|
"#{key}=#{CGI.escape(value.to_s)}"
end
- '?' + tuples.join('&')
+ res = '?' + tuples.join('&')
+
+ # Usage is a hash. The format is a bit different
+ if allowed_keys.include?(:usage) && options.has_key?(:usage)
+ res << "&#{usage_query_params(options[:usage])}"
+ end
+
+ res
end
def encode_transactions(transactions)
result = {}
@@ -281,9 +316,13 @@
append_value(result, index, [:log, name], value)
end
end
result
+ end
+
+ def usage_query_params(usage)
+ URI.encode_www_form(usage.map { |metric, value| ["[usage][#{metric}]", value ] })
end
def append_value(result, index, names, value)
result["transactions[#{index}][#{names.join('][')}]"] = value if value
end