module Aws::AwsBaseInterface

Constants

DEFAULT_SIGNATURE_VERSION

Attributes

aws_access_key_id[R]
cache[R]

RightHttpConnection instance there's a method now to get this since it could be per thread or what have you attr_reader :connection Cache

last_errors[RW]

Last AWS errors list (used by AWSErrorHandler)

last_request[R]

Last HTTP request object

last_request_id[RW]

Last AWS request id (used by AWSErrorHandler)

last_response[R]

Last HTTP response object

logger[RW]

Logger object

params[RW]

Initial params hash

signature_version[R]

Signature version (all services except s3)

Public Class Methods

caching() click to toggle source
# File lib/awsbase/awsbase.rb, line 105
def self.caching
  @@caching
end
caching=(caching) click to toggle source
# File lib/awsbase/awsbase.rb, line 109
def self.caching=(caching)
  @@caching = caching
end

Public Instance Methods

cache_hits?(function, response, do_raise=:raise) click to toggle source

Check if the aws function response hits the cache or not. If the cache hits:

  • raises an AwsNoChange exception if do_raise == :raise.

  • returnes parsed response from the cache if it exists or true otherwise.

If the cache miss or the caching is off then returns false.

# File lib/awsbase/awsbase.rb, line 465
def cache_hits?(function, response, do_raise=:raise)
  result = false
  if caching?
    function = function.to_sym
    # get rid of requestId (this bad boy was added for API 2008-08-08+ and it is uniq for every response)
    response = response.sub(%r{<requestId>.+?</requestId>}, '')
    response_md5 =Digest::MD5.hexdigest(response).to_s
    # check for changes
    unless @cache[function] && @cache[function][:response_md5] == response_md5
      # well, the response is new, reset cache data
      update_cache(function, {:response_md5 => response_md5,
                              :timestamp => Time.now,
                              :hits => 0,
                              :parsed => nil})
    else
      # aha, cache hits, update the data and throw an exception if needed
      @cache[function][:hits] += 1
      if do_raise == :raise
        raise(AwsNoChange, "Cache hit: #{function} response has not changed since "+
            "#{@cache[function][:timestamp].strftime('%Y-%m-%d %H:%M:%S')}, "+
            "hits: #{@cache[function][:hits]}.")
      else
        result = @cache[function][:parsed] || true
      end
    end
  end
  result
end
caching?() click to toggle source

Returns true if the describe_xxx responses are being cached

# File lib/awsbase/awsbase.rb, line 456
def caching?
  @params.key?(:cache) ? @params[:cache] : @@caching
end
close_conn(conn_name) click to toggle source
# File lib/awsbase/awsbase.rb, line 288
def close_conn(conn_name)
  conn_mode = @params[:connection_mode]
  if conn_mode == :per_thread || conn_mode == :single
    thread = conn_mode == :per_thread ? Thread.current : Thread.main
    if !thread[conn_name].nil?
      thread[conn_name].finish
      thread[conn_name] = nil
    end
  end
end
close_connection() click to toggle source
# File lib/awsbase/awsbase.rb, line 303
def close_connection
  close_conn(self.class.connection_name)
end
connection() click to toggle source
# File lib/awsbase/awsbase.rb, line 299
def connection
  get_conn(self.class.connection_name, self.params, self.logger)
end
escape_params(service_hash) click to toggle source
# File lib/awsbase/awsbase.rb, line 250
def escape_params(service_hash)
  canonical_string = service_hash.keys.sort.map do |key|
    "#{Aws::Utils.amz_escape(key)}=#{Aws::Utils.amz_escape(service_hash[key])}"
  end.join('&')
  canonical_string
end
generate_request(action, params={}) click to toggle source
# File lib/awsbase/awsbase.rb, line 189
def generate_request(action, params={})
  generate_request2(@aws_access_key_id, @aws_secret_access_key, action, @params[:api_version], @params, params)
end
get_conn(connection_name, lib_params, logger) click to toggle source
# File lib/awsbase/awsbase.rb, line 257
    def get_conn(connection_name, lib_params, logger)
#            thread = lib_params[:multi_thread] ? Thread.current : Thread.main
#            thread[connection_name] ||= Rightscale::HttpConnection.new(:exception => Aws::AwsError, :logger => logger)
#            conn = thread[connection_name]
#            return conn
      http_conn = nil
      conn_mode = lib_params[:connection_mode]

      params = {:exception => AwsError, :logger => logger}

      # Adds all parameters accepted by Rightscale::HttpConnection#new
      [:user_agent, :ca_file, :http_connection_retry_count,
       :http_connection_open_timeout, :http_connection_read_timeout,
       :http_connection_retry_delay
      ].each do |key|
        params[key] = lib_params[key] if lib_params.has_key?(key)
      end

      if conn_mode == :per_request
        http_conn = Rightscale::HttpConnection.new(params)

      elsif conn_mode == :per_thread || conn_mode == :single
        thread = conn_mode == :per_thread ? Thread.current : Thread.main
        thread[connection_name] ||= Rightscale::HttpConnection.new(params)
        http_conn = thread[connection_name]
#                ret = request_info_impl(http_conn, bench, request, parser, &block)
      end
      return http_conn

    end
multi_thread() click to toggle source

Return true if this instance works in #multi_thread mode and false otherwise.

# File lib/awsbase/awsbase.rb, line 504
def multi_thread
  @params[:multi_thread]
end
request_info3(service_interface, request, parser, options, &block) click to toggle source

This is the latest and greatest now. Service must have connection_name defined.

# File lib/awsbase/awsbase.rb, line 335
def request_info3(service_interface, request, parser, options, &block)
  request_info2(request, parser,
                service_interface.params,
                service_interface.class.connection_name,
                service_interface.logger,
                service_interface.class.bench,
                options, &block)
end
request_info_xml_simple(connection_name, lib_params, request, logger, params = {}) click to toggle source

This is the direction we should head instead of writing our own parsers for everything, much simpler params:

- :group_tags => hash of indirection to eliminate, see: http://xml-simple.rubyforge.org/
- :force_array => true for all or an array of tag names to force
- :pull_out_array => an array of levels to dig into when generating return value (see rds.rb for example)
# File lib/awsbase/awsbase.rb, line 350
    def request_info_xml_simple(connection_name, lib_params, request, logger, params = {})

      connection = get_conn(connection_name, lib_params, logger)
      begin
        @last_request = request[:request]
        @last_response = nil

        response = connection.request(request)
        #       puts "response=" + response.body
        #            benchblock.service.add!{ response = connection.request(request) }
        # check response for errors...
        @last_response = response
        if response.is_a?(Net::HTTPSuccess)
          @error_handler = nil
#                benchblock.xml.add! { parser.parse(response) }
#                return parser.result
          force_array = params[:force_array] || false
# Force_array and group_tags don't work nice together so going to force array manually
          xml_simple_options = {"KeyToSymbol" => false, 'ForceArray' => false}
          xml_simple_options["GroupTags"] = params[:group_tags] if params[:group_tags]

#                { 'GroupTags' => { 'searchpath' => 'dir' }
#                'ForceArray' => %r(_list$)
          parsed = XmlSimple.xml_in(response.body, xml_simple_options)
# todo: we may want to consider stripping off a couple of layers when doing this, for instance:
# <DescribeDBInstancesResponse xmlns="http://rds.amazonaws.com/admin/2009-10-16/">
#  <DescribeDBInstancesResult>
#    <DBInstances>
# <DBInstance>....
# Strip it off and only return an array or hash of <DBInstance>'s (hash by identifier).
# would have to be able to make the RequestId available somehow though, perhaps some special array subclass which included that?
          unless force_array.is_a? Array
            force_array = []
          end
          parsed = symbolize(parsed, force_array)
#                puts 'parsed=' + parsed.inspect
          if params[:pull_out_array]
            ret = Aws::AwsResponseArray.new(parsed[:response_metadata])
            level_hash = parsed
            params[:pull_out_array].each do |x|
              level_hash = level_hash[x]
            end
            if level_hash.is_a? Hash # When there's only one
              ret << level_hash
            else # should be array
                 #                            puts 'level_hash=' + level_hash.inspect
              level_hash.each do |x|
                ret << x
              end
            end
          elsif params[:pull_out_single]
            # returns a single object
            ret = AwsResponseObjectHash.new(parsed[:response_metadata])
            level_hash = parsed
            params[:pull_out_single].each do |x|
              level_hash = level_hash[x]
            end
            ret.merge!(level_hash)
          else
            ret = parsed
          end
          return ret

        else
          @error_handler = AWSErrorHandler.new(self, nil, :errors_list => self.class.amazon_problems) unless @error_handler
          check_result = @error_handler.check(request)
          if check_result
            @error_handler = nil
            return check_result
          end
          request_text_data = "#{request[:server]}:#{request[:port]}#{request[:request].path}"
          raise AwsError2.new(@last_response.code, @last_request_id, request_text_data, @last_response.body)
        end
      ensure
        connection.finish if connection && lib_params[:connection_mode] == :per_request
      end

    end
request_info_xml_simple3(service_interface, request, options) click to toggle source

This is the latest and greatest now. Service must have connection_name defined.

# File lib/awsbase/awsbase.rb, line 430
def request_info_xml_simple3(service_interface, request, options)
  request_info_xml_simple(service_interface.class.connection_name,
                          service_interface.params,
                          request,
                          service_interface.logger,
                          options)
end
signed_service_params(aws_secret_access_key, service_hash, http_verb=nil, host=nil, service=nil) click to toggle source
# File lib/awsbase/awsbase.rb, line 176
def signed_service_params(aws_secret_access_key, service_hash, http_verb=nil, host=nil, service=nil)
  case signature_version.to_s
    when '0' then
      Utils::sign_request_v0(aws_secret_access_key, service_hash)
    when '1' then
      Utils::sign_request_v1(aws_secret_access_key, service_hash)
    when '2' then
      Utils::sign_request_v2(aws_secret_access_key, service_hash, http_verb, host, service)
    else
      raise AwsError.new("Unknown signature version (#{signature_version.to_s}) requested")
  end
end
symbolize(hash, force_array) click to toggle source
# File lib/awsbase/awsbase.rb, line 438
def symbolize(hash, force_array)
  ret = {}
  hash.keys.each do |key|
    val = hash[key]
    if val.is_a? Hash
      val = symbolize(val, force_array)
      if force_array.include? key
        val = [val]
      end
    elsif val.is_a? Array
      val = val.collect { |x| symbolize(x, force_array) }
    end
    ret[Aws::Utils.underscore(key).to_sym] = val
  end
  ret
end
update_cache(function, hash) click to toggle source
# File lib/awsbase/awsbase.rb, line 494
def update_cache(function, hash)
  (@cache[function.to_sym] ||= {}).merge!(hash) if caching?
end