# Copyright 2011-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"). You # may not use this file except in compliance with the License. A copy of # the License is located at # # http://aws.amazon.com/apache2.0/ # # or in the "license" file accompanying this file. This file is # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF # ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. require 'aws/core/autoloader' # AWS is the root module for all of the Amazon Web Services. It is also # where you can configure you access to AWS. # # = Supported Services # # The currently supported services are: # # * {AWS::AutoScaling} # * {AWS::CloudFormation} # * {AWS::DynamoDB} # * {AWS::EC2} # * {AWS::ELB} # * {AWS::IAM} # * {AWS::S3} # * {AWS::SNS} # * {AWS::SQS} # * {AWS::STS} # * {AWS::SimpleDB} # * {AWS::SimpleEmailService} # * {AWS::SimpleWorkflow} # # = AWS::Record # # In addition to the above services, bundled is an ORM based on AWS services # See {AWS::Record} for more information. # # = Configuration # # You call {AWS.config} with a hash of options to configure your # access to the Amazon Web Services. # # At a minimum you need to set your access credentials. See {AWS.config} # for additional configuration options. # # AWS.config( # :access_key_id => 'ACCESS_KEY_ID', # :secret_access_key => 'SECRET_ACCESS_KEY') # # == Rails # # If you are loading AWS inside a Rails web application, it is recomended to # place your configuration inside: # # config/initializers/aws-sdk.rb # # Optionally you can create a Yaml configuration file at # RAILS_ROOT/config/aws.yaml; This should be formatted in the same manor # as the default RAILS_ROOT/config/database.yml file (one section for # each Rails environment). # module AWS # Current version of the AWS SDK for Ruby VERSION = "1.5.5" register_autoloads(self) do autoload :Errors, 'errors' end module Core AWS.register_autoloads(self) do autoload :AsyncHandle, 'async_handle' autoload :Cacheable, 'cacheable' autoload :Client, 'client' autoload :Collection, 'collection' autoload :Configuration, 'configuration' autoload :CredentialProviders, 'credential_providers' autoload :Data, 'data' autoload :IndifferentHash, 'indifferent_hash' autoload :Inflection, 'inflection' autoload :LazyErrorClasses, 'lazy_error_classes' autoload :LogFormatter, 'log_formatter' autoload :MetaUtils, 'meta_utils' autoload :Model, 'model' autoload :Naming, 'naming' autoload :OptionGrammar, 'option_grammar' autoload :PageResult, 'page_result' autoload :Policy, 'policy' autoload :Resource, 'resource' autoload :ResourceCache, 'resource_cache' autoload :Response, 'response' autoload :ResponseCache, 'response_cache' autoload :ServiceInterface, 'service_interface' autoload :Signer, 'signer' autoload :UriEscape, 'uri_escape' end module Signature AWS.register_autoloads(self) do autoload :Version2, 'version_2' autoload :Version3, 'version_3' autoload :Version4, 'version_4' end end module XML AWS.register_autoloads(self) do autoload :Parser, 'parser' autoload :Grammar, 'grammar' autoload :Stub, 'stub' autoload :Frame, 'frame' autoload :RootFrame, 'root_frame' autoload :FrameStack, 'frame_stack' end module SaxHandlers AWS.register_autoloads(self, 'aws/core/xml/sax_handlers') do autoload :Nokogiri, 'nokogiri' autoload :REXML, 'rexml' end end end module Http AWS.register_autoloads(self) do autoload :Handler, 'handler' autoload :NetHttpHandler, 'net_http_handler' autoload :HTTPartyHandler, 'httparty_handler' # non-standard inflection autoload :Request, 'request' autoload :Response, 'response' end end end # the http party handler should still be accessible from its old namespace module Http AWS.register_autoloads(self, 'aws/core/http') do autoload :HTTPartyHandler, 'httparty_handler' end end class << self # @private @@config = nil # The global configuration for AWS. Generally you set your prefered # configuration operations once after loading the aws-sdk gem. # # AWS.config({ # :access_key_id => 'ACCESS_KEY_ID', # :secret_access_key => 'SECRET_ACCESS_KEY', # :simple_db_endpoint => 'sdb.us-west-1.amazonaws.com', # :max_retries => 2, # }) # # When using AWS classes they will always default to use configuration # values defined in {AWS.config}. # # AWS.config(:max_retries => 2) # # sqs = AWS::SQS.new # sqs.config.max_retries #=> 2 # # If you want to change a configuration value for a single instance you # pass the new configuration value to that object's initializer: # # AWS::SQS.new(:max_retries => 0) # # @note Changing the global configuration does not affect objects # that have already been constructed. # # @param [Hash] options # # @option options [String] :access_key_id AWS access key id # credential. # # @option options [String] :secret_access_key AWS secret access # key credential. # # @option options [String,nil] :session_token AWS secret token # credential. # # @option options [String] :auto_scaling_endpoint ('autoscaling.us-east-1.amazonaws.com') # The service endpoint for Auto Scaling. # # @option options [String] :cloud_formation_endpoint ('cloudformation.us-east-1.amazonaws.com') # The service endpoint for AWS CloudFormation. # # @option options [String] :dynamo_db_endpoint ('dynamodb.amazonaws.com') # The service endpoint for Amazon DynamoDB. # # @option options [String] :dynamo_db_retry_throughput_errors (true) When # true, AWS::DynamoDB::Errors::ProvisionedThroughputExceededException # errors will be retried. # # @option options [String] :ec2_endpoint ('ec2.amazonaws.com') The # service endpoint for Amazon EC2. # # @option options [String] :elb_endpoint ('elasticloadbalancing.us-east-1.amazonaws.com') # The service endpoint for Elastic Load Balancing. # # @option options [Object] :http_handler (AWS::Core::Http::NetHttpHandler) # The http handler that sends requests to AWS. # # @option options [Integer] :http_idle_timeout (60) The number of seconds # a persistent connection is allowed to sit idle before it should no # longer be used. # # @option options [Integer] :http_open_timeout (15) The number of seconds # before the +:http_handler+ should timeout while trying to open a new # HTTP sesssion. # # @option options [Integer] :http_read_timeout (60) The number of seconds # before the +:http_handler+ should timeout while waiting for a HTTP # response. # # @option options [Boolean] :http_wire_trace (false) When +true+, the # http handler will log all wire traces to the +:logger+. If a # +:logger+ is not configured, then wire traces will be sent to # standard out. # # @option options [String] :iam_endpoint ('iam.amazonaws.com') The # service endpoint for AWS Idenity Access Management (IAM). # # @option options [Logger,nil] :logger (nil) A logger to send # log messages to. Here is an example that logs to standard out. # # require 'logger' # AWS.config(:logger => Logger.new($stdout)) # # @option options [Symbol] :log_level (:info) The level log messages are # sent to the logger with (e.g. +:notice+, +:info+, +:warn+, # +:debug+, etc). # # @option options [Object] :log_formatter The log formatter is responsible # for building log messages from responses. You can quickly change # log formats by providing a pre-configured log formatter. # # AWS.config(:log_formatter => AWS::Core::LogFormatter.colored) # # Here is a list of pre-configured log formatters: # # * +AWS::Core::LogFormatter.default+ # * +AWS::Core::LogFormatter.short+ # * +AWS::Core::LogFormatter.debug+ # * +AWS::Core::LogFormatter.colored+ # # You can also create an instance of AWS::Core::LogFormatter # with a custom log message pattern. See {Core::LogFormatter} for # a complete list of pattern substituions. # # pattern = "[AWS :operation :duration] :error_message" # AWS.config(:log_formatter => AWS::Core::LogFormatter.new(pattern)) # # Lastly you can pass any object that responds to +#format+ accepting # and instance of {Core::Response} and returns a string. # # @option options [Integer] :max_retries (3) The maximum number of times # service errors (500) should be retried. There is an exponential # backoff in between service request retries, so the more retries the # longer it can take to fail. # # @option options [String, URI, nil] :proxy_uri (nil) The URI of the proxy # to send service requests through. You can pass a URI object or a # URI string: # # AWS.config(:proxy_uri => 'https://user:password@my.proxy:443/path?query') # # @option options [String] :s3_endpoint ('s3.amazonaws.com') The # service endpoint for Amazon S3. # # @option options [Integer] :s3_multipart_max_parts (1000) The maximum # number of parts to split a file into when uploading in parts to S3. # # @option options [Integer] :s3_multipart_threshold (16777216) When # uploading data to S3, if the number of bytes to send exceedes # +:s3_multipart_threshold+ then a multi part session is automatically # started and the data is sent up in chunks. The size of each part # is specified by +:s3_multipart_min_part_size+. Defaults to # 16777216 (16MB). # # @option options [Integer] :s3_multipart_min_part_size (5242880) The # absolute minimum size (in bytes) each S3 multipart segment should be. # Defaults to 5242880 (5MB). # # @option options [Symbol] :s3_server_side_encryption (nil) The # algorithm to use when encrypting object data on the server # side. The only valid value is +:aes256+, which specifies that # the object should be stored using the AES encryption algorithm # with 256 bit keys. Defaults to +nil+, meaning server side # encryption is not used unless specified on each individual # call to upload an object. This option controls the default # behavior for the following methods: # # * {S3::S3Object#write} # * {S3::S3Object#multipart_upload} # * {S3::S3Object#copy_from} and {S3::S3Object#copy_to} # * {S3::S3Object#presigned_post} # * {S3::Bucket#presigned_post} # # @option options [String] :simple_db_endpoint ('sdb.amazonaws.com') # The service endpoint for Amazon SimpleDB. # # @option options [Boolean] :simple_db_consistent_reads (false) Determines # if all SimpleDB read requests should be done consistently. # Consistent reads are slower, but reflect all changes to SDB. # # @option options [String] :simple_email_service_endpoint ('email.us-east-1.amazonaws.com') # The service endpoint for Amazon Simple Email Service. # # @option options [String] :simple_workflow_service ('swf.us-east-1.amazonaws.com') # The service endpoint for Amazon Simple Workflow Service. # # @option options [CredentialProviders::Provider] :credential_provider (AWS::Core::CredentialProviders::DefaultProvider.new) # Returns the credential provider. The default credential provider # attempts to check for statically assigned credentials, ENV credentials # and credentials in the metadata service of EC2. # # @option options [String] :ssl_ca_file The path to a CA cert bundle in # PEM format. # # If +:ssl_verify_peer+ is +true+ (the default) this bundle will be # used to validate the server certificate in each HTTPS request. # The AWS SDK for Ruby ships with a CA cert bundle, which is the # default value for this option. # # @option options [String] :ssl_ca_path (nil) # The path the a CA cert directory. # # @option options [Boolean] :ssl_verify_peer (true) When +true+ # the HTTP handler validate server certificates for HTTPS requests. # # This option should only be disabled for diagnostic purposes; # leaving this option set to +false+ exposes your application to # man-in-the-middle attacks and can pose a serious security # risk. # # @option options [Boolean] :stub_requests (false) When +true+ requests # are not sent to AWS, instead empty reponses are generated and # returned to each service request. # # @option options [String] :sns_endpoint ('sns.us-east-1.amazonaws.com') The # service endpoint for Amazon SNS. # # @option options [String] :sqs_endpoint ('sqs.us-east-1.amazonaws.com') The # service endpoint for Amazon SQS. # # @option options [String] :sts_endpoint ('sts.amazonaws.com') The # service endpoint for AWS Security Token Service. # # @option options [Boolean] :use_ssl (true) When +true+, all requests # to AWS are sent using HTTPS instead vanilla HTTP. # # @option options [String] :user_agent_prefix (nil) A string prefix to # append to all requets against AWS services. This should be set # for clients and applications built ontop of the aws-sdk gem. # # @return [Core::Configuration] Returns the new configuration. # def config options = {} @@config ||= Core::Configuration.new @@config = @@config.with(options) unless options.empty? @@config end # @note Memoization is currently only supported for the EC2 APIs; # other APIs are unaffected by the status of memoization. To # protect your code from future changes in memoization support, # you should not enable memoization while calling non-EC2 APIs. # # Starts memoizing service requests made in the current thread. # See {memoize} for a full discussion of the memoization feature. # This has no effect if memoization is already enabled. def start_memoizing Thread.current[:aws_memoization] ||= {} nil end # @note Memoization is currently only supported for the EC2 APIs; # other APIs are unaffected by the status of memoization. To # protect your code from future changes in memoization support, # you should not enable memoization while calling non-EC2 APIs. # # Stops memoizing service requests made in the current thread. # See {memoize} for a full discussion of the memoization feature. # This has no effect if memoization is already disabled. def stop_memoizing Thread.current[:aws_memoization] = nil end # @note Memoization is currently only supported for the EC2 APIs; # other APIs are unaffected by the status of memoization. To # protect your code from future changes in memoization support, # you should not enable memoization while calling non-EC2 APIs. # # @return [Boolean] True if memoization is enabled for the current # thread. See {memoize} for a full discussion of the # memoization feature. def memoizing? !Thread.current[:aws_memoization].nil? end # @note Memoization is currently only supported for the EC2 APIs; # other APIs are unaffected by the status of memoization. To # protect your code from future changes in memoization support, # you should not enable memoization while calling non-EC2 APIs. # # Enables memoization for the current thread, within a block. # Memoization lets you avoid making multiple requests for the same # data by reusing the responses which have already been received. # For example, consider the following code to get the most # recently launched EC2 instance: # # latest = ec2.instances.sort_by(&:launch_time).last # # The above code would make N+1 requests (where N is the number of # instances in the account); iterating the collection of instances # is one request, and +Enumerable#sort_by+ calls # {AWS::EC2::Instance#launch_time} for each instance, causing # another request per instance. We can rewrite the code as # follows to make only one request: # # latest = AWS.memoize do # ec2.instances.sort_by(&:launch_time).last # end # # Iterating the collection still causes a request, but each # subsequent call to {AWS::EC2::Instance#launch_time} uses the # results from that first request rather than making a new request # for the same data. # # While memoization is enabled, every response that is received # from the service is retained in memory. Therefore you should # use memoization only for short-lived blocks of code that make # relatively small numbers of requests. The cached responses are # used in two ways while memoization is enabled: # # 1. Before making a request, the SDK checks the cache for a # response to a request with the same signature (credentials, # service endpoint, operation name, and parameters). If such a # response is found, it is used instead of making a new # request. # # 2. Before retrieving data for an attribute of a resource # (e.g. {AWS::EC2::Instance#launch_time}), the SDK attempts to # find a cached response that contains the requested data. If # such a response is found, the cached data is returned instead # of making a new request. # # When memoization is disabled, all previously cached responses # are discarded. def memoize return yield if memoizing? begin start_memoizing yield if block_given? ensure stop_memoizing end end # @private def resource_cache if memoizing? Thread.current[:aws_memoization][:resource_cache] ||= Core::ResourceCache.new end end # @private def response_cache if memoizing? Thread.current[:aws_memoization][:response_cache] ||= Core::ResponseCache.new end end # Causes all requests to return empty responses without making any # requests against the live services. This does not attempt to # mock the services. # @return [nil] def stub! config(:stub_requests => true) nil end end end