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