Class: Elasticity::AwsRequest

Inherits:
Object
  • Object
show all
Defined in:
lib/elasticity/aws_request.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(access = nil, secret = nil, options = {}) ⇒ AwsRequest

Supported values for options:

:region - AWS region (e.g. us-west-1)
:secure - true or false, default true.


18
19
20
21
22
23
24
25
26
27
28
# File 'lib/elasticity/aws_request.rb', line 18

def initialize(access=nil, secret=nil, options={})
  # There is a cryptic error if this isn't set
  if options.has_key?(:region) && options[:region] == nil
    raise MissingRegionError, 'A valid :region is required to connect to EMR'
  end

  @access_key = get_access_key(access)
  @secret_key = get_secret_key(secret)
  @host = "elasticmapreduce.#{{:region => 'us-east-1'}.merge(options)[:region]}.amazonaws.com"
  @protocol = {:secure => true}.merge(options)[:secure] ? 'https' : 'http'
end

Instance Attribute Details

#access_keyObject (readonly)

Returns the value of attribute access_key.



10
11
12
# File 'lib/elasticity/aws_request.rb', line 10

def access_key
  @access_key
end

#hostObject (readonly)

Returns the value of attribute host.



12
13
14
# File 'lib/elasticity/aws_request.rb', line 12

def host
  @host
end

#protocolObject (readonly)

Returns the value of attribute protocol.



13
14
15
# File 'lib/elasticity/aws_request.rb', line 13

def protocol
  @protocol
end

#secret_keyObject (readonly)

Returns the value of attribute secret_key.



11
12
13
# File 'lib/elasticity/aws_request.rb', line 11

def secret_key
  @secret_key
end

Class Method Details

.aws_escape(param) ⇒ Object

(Used from RightScale’s right_aws gem) Escape a string according to Amazon’s rules. See: docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/index.html?REST_RESTAuth.html



85
86
87
88
89
# File 'lib/elasticity/aws_request.rb', line 85

def self.aws_escape(param)
  param.to_s.gsub(/([^a-zA-Z0-9._~-]+)/n) do
    '%' + $1.unpack('H2' * $1.size).join('%').upcase
  end
end

.camelize(word) ⇒ Object

(Used from Rails’ ActiveSupport)



121
122
123
# File 'lib/elasticity/aws_request.rb', line 121

def self.camelize(word)
  word.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
end

.convert_ruby_to_aws(params) ⇒ Object

Since we use the same structure as AWS, we can generate AWS param names from the Ruby versions of those names (and the param nesting).



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/elasticity/aws_request.rb', line 93

def self.convert_ruby_to_aws(params)
  result = {}
  params.each do |key, value|
    case value
      when Array
        prefix = "#{camelize(key.to_s)}.member"
        value.each_with_index do |item, index|
          if item.is_a?(String)
            result["#{prefix}.#{index+1}"] = item
          else
            convert_ruby_to_aws(item).each do |nested_key, nested_value|
              result["#{prefix}.#{index+1}.#{nested_key}"] = nested_value
            end
          end
        end
      when Hash
        prefix = "#{camelize(key.to_s)}"
        convert_ruby_to_aws(value).each do |nested_key, nested_value|
          result["#{prefix}.#{nested_key}"] = nested_value
        end
      else
        result[camelize(key.to_s)] = value
    end
  end
  result
end

.parse_error_response(error_xml) ⇒ Object

AWS error responses all follow the same form. Extract the message from the error document.



127
128
129
130
131
# File 'lib/elasticity/aws_request.rb', line 127

def self.parse_error_response(error_xml)
  xml_doc = Nokogiri::XML(error_xml)
  xml_doc.remove_namespaces!
  xml_doc.xpath("/ErrorResponse/Error/Message").text
end

Instance Method Details

#==(other) ⇒ Object



40
41
42
43
44
45
46
47
# File 'lib/elasticity/aws_request.rb', line 40

def ==(other)
  return false unless other.is_a? AwsRequest
  return false unless @access_key == other.access_key
  return false unless @secret_key == other.secret_key
  return false unless @host == other.host
  return false unless @protocol == other.protocol
  true
end

#submit(ruby_params) ⇒ Object



30
31
32
33
34
35
36
37
38
# File 'lib/elasticity/aws_request.rb', line 30

def submit(ruby_params)
  aws_params = AwsRequest.convert_ruby_to_aws(ruby_params)
  signed_params = sign_params(aws_params)
  begin
    RestClient.post("#@protocol://#@host", signed_params, :content_type => 'application/x-www-form-urlencoded; charset=utf-8')
  rescue RestClient::BadRequest => e
    raise ArgumentError, AwsRequest.parse_error_response(e.http_body)
  end
end