redaranj-right_aws 1.10.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +231 -0
 - data/Manifest.txt +37 -0
 - data/README.txt +164 -0
 - data/Rakefile +103 -0
 - data/lib/acf/right_acf_interface.rb +413 -0
 - data/lib/awsbase/benchmark_fix.rb +39 -0
 - data/lib/awsbase/right_awsbase.rb +903 -0
 - data/lib/awsbase/support.rb +115 -0
 - data/lib/ec2/right_ec2.rb +1837 -0
 - data/lib/right_aws.rb +72 -0
 - data/lib/s3/right_s3.rb +1094 -0
 - data/lib/s3/right_s3_interface.rb +1185 -0
 - data/lib/sdb/active_sdb.rb +930 -0
 - data/lib/sdb/right_sdb_interface.rb +672 -0
 - data/lib/sqs/right_sqs.rb +388 -0
 - data/lib/sqs/right_sqs_gen2.rb +343 -0
 - data/lib/sqs/right_sqs_gen2_interface.rb +521 -0
 - data/lib/sqs/right_sqs_interface.rb +594 -0
 - data/test/acf/test_helper.rb +2 -0
 - data/test/acf/test_right_acf.rb +146 -0
 - data/test/ec2/test_helper.rb +2 -0
 - data/test/ec2/test_right_ec2.rb +108 -0
 - data/test/http_connection.rb +87 -0
 - data/test/s3/test_helper.rb +2 -0
 - data/test/s3/test_right_s3.rb +419 -0
 - data/test/s3/test_right_s3_stubbed.rb +95 -0
 - data/test/sdb/test_active_sdb.rb +299 -0
 - data/test/sdb/test_helper.rb +3 -0
 - data/test/sdb/test_right_sdb.rb +247 -0
 - data/test/sqs/test_helper.rb +2 -0
 - data/test/sqs/test_right_sqs.rb +291 -0
 - data/test/sqs/test_right_sqs_gen2.rb +276 -0
 - data/test/test_credentials.rb +37 -0
 - data/test/ts_right_aws.rb +14 -0
 - metadata +100 -0
 
| 
         @@ -0,0 +1,413 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #
         
     | 
| 
      
 2 
     | 
    
         
            +
            # Copyright (c) 2008 RightScale Inc
         
     | 
| 
      
 3 
     | 
    
         
            +
            #
         
     | 
| 
      
 4 
     | 
    
         
            +
            # Permission is hereby granted, free of charge, to any person obtaining
         
     | 
| 
      
 5 
     | 
    
         
            +
            # a copy of this software and associated documentation files (the
         
     | 
| 
      
 6 
     | 
    
         
            +
            # "Software"), to deal in the Software without restriction, including
         
     | 
| 
      
 7 
     | 
    
         
            +
            # without limitation the rights to use, copy, modify, merge, publish,
         
     | 
| 
      
 8 
     | 
    
         
            +
            # distribute, sublicense, and/or sell copies of the Software, and to
         
     | 
| 
      
 9 
     | 
    
         
            +
            # permit persons to whom the Software is furnished to do so, subject to
         
     | 
| 
      
 10 
     | 
    
         
            +
            # the following conditions:
         
     | 
| 
      
 11 
     | 
    
         
            +
            #
         
     | 
| 
      
 12 
     | 
    
         
            +
            # The above copyright notice and this permission notice shall be
         
     | 
| 
      
 13 
     | 
    
         
            +
            # included in all copies or substantial portions of the Software.
         
     | 
| 
      
 14 
     | 
    
         
            +
            #
         
     | 
| 
      
 15 
     | 
    
         
            +
            # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         
     | 
| 
      
 16 
     | 
    
         
            +
            # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         
     | 
| 
      
 17 
     | 
    
         
            +
            # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         
     | 
| 
      
 18 
     | 
    
         
            +
            # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
         
     | 
| 
      
 19 
     | 
    
         
            +
            # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
         
     | 
| 
      
 20 
     | 
    
         
            +
            # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
         
     | 
| 
      
 21 
     | 
    
         
            +
            # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         
     | 
| 
      
 22 
     | 
    
         
            +
            #
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            module RightAws
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              # = RightAws::AcfInterface -- RightScale Amazon's CloudFront interface
         
     | 
| 
      
 27 
     | 
    
         
            +
              # The AcfInterface class provides a complete interface to Amazon's
         
     | 
| 
      
 28 
     | 
    
         
            +
              # CloudFront service.
         
     | 
| 
      
 29 
     | 
    
         
            +
              #
         
     | 
| 
      
 30 
     | 
    
         
            +
              # For explanations of the semantics of each call, please refer to
         
     | 
| 
      
 31 
     | 
    
         
            +
              # Amazon's documentation at
         
     | 
| 
      
 32 
     | 
    
         
            +
              # http://developer.amazonwebservices.com/connect/kbcategory.jspa?categoryID=211
         
     | 
| 
      
 33 
     | 
    
         
            +
              #
         
     | 
| 
      
 34 
     | 
    
         
            +
              # Example:
         
     | 
| 
      
 35 
     | 
    
         
            +
              #
         
     | 
| 
      
 36 
     | 
    
         
            +
              #  acf = RightAws::AcfInterface.new('1E3GDYEOGFJPIT7XXXXXX','hgTHt68JY07JKUY08ftHYtERkjgtfERn57XXXXXX')
         
     | 
| 
      
 37 
     | 
    
         
            +
              #
         
     | 
| 
      
 38 
     | 
    
         
            +
              #  list = acf.list_distributions #=>
         
     | 
| 
      
 39 
     | 
    
         
            +
              #    [{:status             => "Deployed",
         
     | 
| 
      
 40 
     | 
    
         
            +
              #      :domain_name        => "d74zzrxmpmygb.6hops.net",
         
     | 
| 
      
 41 
     | 
    
         
            +
              #      :aws_id             => "E4U91HCJHGXVC",
         
     | 
| 
      
 42 
     | 
    
         
            +
              #      :origin             => "my-bucket.s3.amazonaws.com",
         
     | 
| 
      
 43 
     | 
    
         
            +
              #      :cnames             => ["x1.my-awesome-site.net", "x1.my-awesome-site.net"]
         
     | 
| 
      
 44 
     | 
    
         
            +
              #      :comment            => "My comments",
         
     | 
| 
      
 45 
     | 
    
         
            +
              #      :last_modified_time => Wed Sep 10 17:00:04 UTC 2008 }, ..., {...} ]
         
     | 
| 
      
 46 
     | 
    
         
            +
              #
         
     | 
| 
      
 47 
     | 
    
         
            +
              #  distibution = list.first
         
     | 
| 
      
 48 
     | 
    
         
            +
              #
         
     | 
| 
      
 49 
     | 
    
         
            +
              #  info = acf.get_distribution(distibution[:aws_id]) #=>
         
     | 
| 
      
 50 
     | 
    
         
            +
              #    {:enabled            => true,
         
     | 
| 
      
 51 
     | 
    
         
            +
              #     :caller_reference   => "200809102100536497863003",
         
     | 
| 
      
 52 
     | 
    
         
            +
              #     :e_tag              => "E39OHHU1ON65SI",
         
     | 
| 
      
 53 
     | 
    
         
            +
              #     :status             => "Deployed",
         
     | 
| 
      
 54 
     | 
    
         
            +
              #     :domain_name        => "d3dxv71tbbt6cd.6hops.net",
         
     | 
| 
      
 55 
     | 
    
         
            +
              #     :cnames             => ["web1.my-awesome-site.net", "web2.my-awesome-site.net"]
         
     | 
| 
      
 56 
     | 
    
         
            +
              #     :aws_id             => "E2REJM3VUN5RSI",
         
     | 
| 
      
 57 
     | 
    
         
            +
              #     :comment            => "Woo-Hoo!",
         
     | 
| 
      
 58 
     | 
    
         
            +
              #     :origin             => "my-bucket.s3.amazonaws.com",
         
     | 
| 
      
 59 
     | 
    
         
            +
              #     :last_modified_time => Wed Sep 10 17:00:54 UTC 2008 }
         
     | 
| 
      
 60 
     | 
    
         
            +
              #
         
     | 
| 
      
 61 
     | 
    
         
            +
              #  config = acf.get_distribution_config(distibution[:aws_id]) #=>
         
     | 
| 
      
 62 
     | 
    
         
            +
              #    {:enabled          => true,
         
     | 
| 
      
 63 
     | 
    
         
            +
              #     :caller_reference => "200809102100536497863003",
         
     | 
| 
      
 64 
     | 
    
         
            +
              #     :e_tag            => "E39OHHU1ON65SI",
         
     | 
| 
      
 65 
     | 
    
         
            +
              #     :cnames           => ["web1.my-awesome-site.net", "web2.my-awesome-site.net"]
         
     | 
| 
      
 66 
     | 
    
         
            +
              #     :comment          => "Woo-Hoo!",
         
     | 
| 
      
 67 
     | 
    
         
            +
              #     :origin           => "my-bucket.s3.amazonaws.com"}
         
     | 
| 
      
 68 
     | 
    
         
            +
              #
         
     | 
| 
      
 69 
     | 
    
         
            +
              #  config[:comment] = 'Olah-lah!'
         
     | 
| 
      
 70 
     | 
    
         
            +
              #  config[:enabled] = false
         
     | 
| 
      
 71 
     | 
    
         
            +
              #  config[:cnames] << "web3.my-awesome-site.net"
         
     | 
| 
      
 72 
     | 
    
         
            +
              #
         
     | 
| 
      
 73 
     | 
    
         
            +
              #  acf.set_distribution_config(distibution[:aws_id], config) #=> true
         
     | 
| 
      
 74 
     | 
    
         
            +
              #
         
     | 
| 
      
 75 
     | 
    
         
            +
              class AcfInterface < RightAwsBase
         
     | 
| 
      
 76 
     | 
    
         
            +
                
         
     | 
| 
      
 77 
     | 
    
         
            +
                include RightAwsBaseInterface
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                API_VERSION      = "2009-04-02"
         
     | 
| 
      
 80 
     | 
    
         
            +
                DEFAULT_HOST     = 'cloudfront.amazonaws.com'
         
     | 
| 
      
 81 
     | 
    
         
            +
                DEFAULT_PORT     = 443
         
     | 
| 
      
 82 
     | 
    
         
            +
                DEFAULT_PROTOCOL = 'https'
         
     | 
| 
      
 83 
     | 
    
         
            +
                DEFAULT_PATH     = '/'
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                @@bench = AwsBenchmarkingBlock.new
         
     | 
| 
      
 86 
     | 
    
         
            +
                def self.bench_xml
         
     | 
| 
      
 87 
     | 
    
         
            +
                  @@bench.xml
         
     | 
| 
      
 88 
     | 
    
         
            +
                end
         
     | 
| 
      
 89 
     | 
    
         
            +
                def self.bench_service
         
     | 
| 
      
 90 
     | 
    
         
            +
                  @@bench.service
         
     | 
| 
      
 91 
     | 
    
         
            +
                end
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
                # Create a new handle to a CloudFront account. All handles share the same per process or per thread
         
     | 
| 
      
 94 
     | 
    
         
            +
                # HTTP connection to CloudFront. Each handle is for a specific account. The params have the
         
     | 
| 
      
 95 
     | 
    
         
            +
                # following options:
         
     | 
| 
      
 96 
     | 
    
         
            +
                # * <tt>:endpoint_url</tt> a fully qualified url to Amazon API endpoint (this overwrites: :server, :port, :service, :protocol). Example: 'https://cloudfront.amazonaws.com'
         
     | 
| 
      
 97 
     | 
    
         
            +
                # * <tt>:server</tt>: CloudFront service host, default: DEFAULT_HOST
         
     | 
| 
      
 98 
     | 
    
         
            +
                # * <tt>:port</tt>: CloudFront service port, default: DEFAULT_PORT
         
     | 
| 
      
 99 
     | 
    
         
            +
                # * <tt>:protocol</tt>: 'http' or 'https', default: DEFAULT_PROTOCOL
         
     | 
| 
      
 100 
     | 
    
         
            +
                # * <tt>:multi_thread</tt>: true=HTTP connection per thread, false=per process
         
     | 
| 
      
 101 
     | 
    
         
            +
                # * <tt>:logger</tt>: for log messages, default: RAILS_DEFAULT_LOGGER else STDOUT
         
     | 
| 
      
 102 
     | 
    
         
            +
                #
         
     | 
| 
      
 103 
     | 
    
         
            +
                #  acf = RightAws::AcfInterface.new('1E3GDYEOGFJPIT7XXXXXX','hgTHt68JY07JKUY08ftHYtERkjgtfERn57XXXXXX',
         
     | 
| 
      
 104 
     | 
    
         
            +
                #    {:logger => Logger.new('/tmp/x.log')}) #=>  #<RightAws::AcfInterface::0xb7b3c30c>
         
     | 
| 
      
 105 
     | 
    
         
            +
                #
         
     | 
| 
      
 106 
     | 
    
         
            +
                def initialize(aws_access_key_id=nil, aws_secret_access_key=nil, params={})
         
     | 
| 
      
 107 
     | 
    
         
            +
                  init({ :name                => 'ACF',
         
     | 
| 
      
 108 
     | 
    
         
            +
                         :default_host        => ENV['ACF_URL'] ? URI.parse(ENV['ACF_URL']).host   : DEFAULT_HOST,
         
     | 
| 
      
 109 
     | 
    
         
            +
                         :default_port        => ENV['ACF_URL'] ? URI.parse(ENV['ACF_URL']).port   : DEFAULT_PORT,
         
     | 
| 
      
 110 
     | 
    
         
            +
                         :default_service     => ENV['ACF_URL'] ? URI.parse(ENV['ACF_URL']).path   : DEFAULT_PATH,
         
     | 
| 
      
 111 
     | 
    
         
            +
                         :default_protocol    => ENV['ACF_URL'] ? URI.parse(ENV['ACF_URL']).scheme : DEFAULT_PROTOCOL,
         
     | 
| 
      
 112 
     | 
    
         
            +
                         :default_api_version => ENV['ACF_API_VERSION'] || API_VERSION },
         
     | 
| 
      
 113 
     | 
    
         
            +
                       aws_access_key_id     || ENV['AWS_ACCESS_KEY_ID'], 
         
     | 
| 
      
 114 
     | 
    
         
            +
                       aws_secret_access_key || ENV['AWS_SECRET_ACCESS_KEY'], 
         
     | 
| 
      
 115 
     | 
    
         
            +
                       params)
         
     | 
| 
      
 116 
     | 
    
         
            +
                end
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
                #-----------------------------------------------------------------
         
     | 
| 
      
 119 
     | 
    
         
            +
                #      Requests
         
     | 
| 
      
 120 
     | 
    
         
            +
                #-----------------------------------------------------------------
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
                # Generates request hash for REST API.
         
     | 
| 
      
 123 
     | 
    
         
            +
                def generate_request(method, path, params={}, body=nil, headers={})  # :nodoc:
         
     | 
| 
      
 124 
     | 
    
         
            +
                  # Params
         
     | 
| 
      
 125 
     | 
    
         
            +
                  params.delete_if{ |key, val| val.blank? }
         
     | 
| 
      
 126 
     | 
    
         
            +
                  unless params.blank?
         
     | 
| 
      
 127 
     | 
    
         
            +
                    path += "?" + params.to_a.collect{ |key,val| "#{AwsUtils::amz_escape(key)}=#{AwsUtils::amz_escape(val.to_s)}" }.join("&")
         
     | 
| 
      
 128 
     | 
    
         
            +
                  end
         
     | 
| 
      
 129 
     | 
    
         
            +
                  # Headers
         
     | 
| 
      
 130 
     | 
    
         
            +
                  headers['content-type'] ||= 'text/xml' if body
         
     | 
| 
      
 131 
     | 
    
         
            +
                  headers['date'] = Time.now.httpdate
         
     | 
| 
      
 132 
     | 
    
         
            +
                  # Auth
         
     | 
| 
      
 133 
     | 
    
         
            +
                  signature = AwsUtils::sign(@aws_secret_access_key, headers['date'])
         
     | 
| 
      
 134 
     | 
    
         
            +
                  headers['Authorization'] = "AWS #{@aws_access_key_id}:#{signature}"
         
     | 
| 
      
 135 
     | 
    
         
            +
                  # Request
         
     | 
| 
      
 136 
     | 
    
         
            +
                  path    = "#{@params[:service]}#{@params[:api_version]}/#{path}"
         
     | 
| 
      
 137 
     | 
    
         
            +
                  request = "Net::HTTP::#{method.capitalize}".constantize.new(path)
         
     | 
| 
      
 138 
     | 
    
         
            +
                  request.body = body if body
         
     | 
| 
      
 139 
     | 
    
         
            +
                  # Set request headers
         
     | 
| 
      
 140 
     | 
    
         
            +
                  headers.each { |key, value| request[key.to_s] = value }
         
     | 
| 
      
 141 
     | 
    
         
            +
                  # prepare output hash
         
     | 
| 
      
 142 
     | 
    
         
            +
                  { :request  => request, 
         
     | 
| 
      
 143 
     | 
    
         
            +
                    :server   => @params[:server],
         
     | 
| 
      
 144 
     | 
    
         
            +
                    :port     => @params[:port],
         
     | 
| 
      
 145 
     | 
    
         
            +
                    :protocol => @params[:protocol] }
         
     | 
| 
      
 146 
     | 
    
         
            +
                  end
         
     | 
| 
      
 147 
     | 
    
         
            +
                  
         
     | 
| 
      
 148 
     | 
    
         
            +
                  # Sends request to Amazon and parses the response.
         
     | 
| 
      
 149 
     | 
    
         
            +
                  # Raises AwsError if any banana happened.
         
     | 
| 
      
 150 
     | 
    
         
            +
                def request_info(request, parser, &block) # :nodoc:
         
     | 
| 
      
 151 
     | 
    
         
            +
                  request_info_impl(:acf_connection, @@bench, request, parser, &block)
         
     | 
| 
      
 152 
     | 
    
         
            +
                end
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
                #-----------------------------------------------------------------
         
     | 
| 
      
 155 
     | 
    
         
            +
                #      Helpers:
         
     | 
| 
      
 156 
     | 
    
         
            +
                #-----------------------------------------------------------------
         
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
      
 158 
     | 
    
         
            +
                def self.escape(text) # :nodoc:
         
     | 
| 
      
 159 
     | 
    
         
            +
                  REXML::Text::normalize(text)
         
     | 
| 
      
 160 
     | 
    
         
            +
                end
         
     | 
| 
      
 161 
     | 
    
         
            +
             
     | 
| 
      
 162 
     | 
    
         
            +
                def self.unescape(text) # :nodoc:
         
     | 
| 
      
 163 
     | 
    
         
            +
                  REXML::Text::unnormalize(text)
         
     | 
| 
      
 164 
     | 
    
         
            +
                end
         
     | 
| 
      
 165 
     | 
    
         
            +
             
     | 
| 
      
 166 
     | 
    
         
            +
                def generate_call_reference # :nodoc:
         
     | 
| 
      
 167 
     | 
    
         
            +
                  result = Time.now.strftime('%Y%m%d%H%M%S')
         
     | 
| 
      
 168 
     | 
    
         
            +
                  10.times{ result << rand(10).to_s }
         
     | 
| 
      
 169 
     | 
    
         
            +
                  result
         
     | 
| 
      
 170 
     | 
    
         
            +
                end
         
     | 
| 
      
 171 
     | 
    
         
            +
             
     | 
| 
      
 172 
     | 
    
         
            +
                def merge_headers(hash) # :nodoc:
         
     | 
| 
      
 173 
     | 
    
         
            +
                  hash[:location] = @last_response['Location'] if @last_response['Location']
         
     | 
| 
      
 174 
     | 
    
         
            +
                  hash[:e_tag]    = @last_response['ETag']     if @last_response['ETag']
         
     | 
| 
      
 175 
     | 
    
         
            +
                  hash
         
     | 
| 
      
 176 
     | 
    
         
            +
                end
         
     | 
| 
      
 177 
     | 
    
         
            +
             
     | 
| 
      
 178 
     | 
    
         
            +
                def config_to_xml(config) # :nodoc:
         
     | 
| 
      
 179 
     | 
    
         
            +
                  cnames = ''
         
     | 
| 
      
 180 
     | 
    
         
            +
                  unless config[:cnames].blank?
         
     | 
| 
      
 181 
     | 
    
         
            +
                    config[:cnames].to_a.each { |cname| cnames += "  <CNAME>#{cname}</CNAME>\n" }
         
     | 
| 
      
 182 
     | 
    
         
            +
                  end
         
     | 
| 
      
 183 
     | 
    
         
            +
                  # logging
         
     | 
| 
      
 184 
     | 
    
         
            +
                  logging = ''
         
     | 
| 
      
 185 
     | 
    
         
            +
                  unless config[:logging].blank?
         
     | 
| 
      
 186 
     | 
    
         
            +
                    logging = "  <Logging>\n" +
         
     | 
| 
      
 187 
     | 
    
         
            +
                              "    <Bucket>#{config[:logging][:bucket]}</Bucket>\n" +
         
     | 
| 
      
 188 
     | 
    
         
            +
                              "    <Prefix>#{config[:logging][:prefix]}</Prefix>\n" +
         
     | 
| 
      
 189 
     | 
    
         
            +
                              "  </Logging>\n"
         
     | 
| 
      
 190 
     | 
    
         
            +
                  end
         
     | 
| 
      
 191 
     | 
    
         
            +
                  # xml
         
     | 
| 
      
 192 
     | 
    
         
            +
                  "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
         
     | 
| 
      
 193 
     | 
    
         
            +
                  "<DistributionConfig xmlns=\"http://#{@params[:server]}/doc/#{API_VERSION}/\">\n" +
         
     | 
| 
      
 194 
     | 
    
         
            +
                  "  <Origin>#{config[:origin]}</Origin>\n" +
         
     | 
| 
      
 195 
     | 
    
         
            +
                  "  <CallerReference>#{config[:caller_reference]}</CallerReference>\n" +
         
     | 
| 
      
 196 
     | 
    
         
            +
                  "  <Comment>#{AcfInterface::escape(config[:comment].to_s)}</Comment>\n" +
         
     | 
| 
      
 197 
     | 
    
         
            +
                  "  <Enabled>#{config[:enabled]}</Enabled>\n" +
         
     | 
| 
      
 198 
     | 
    
         
            +
                  cnames  +
         
     | 
| 
      
 199 
     | 
    
         
            +
                  logging +
         
     | 
| 
      
 200 
     | 
    
         
            +
                  "</DistributionConfig>"
         
     | 
| 
      
 201 
     | 
    
         
            +
                end
         
     | 
| 
      
 202 
     | 
    
         
            +
             
     | 
| 
      
 203 
     | 
    
         
            +
                #-----------------------------------------------------------------
         
     | 
| 
      
 204 
     | 
    
         
            +
                #      API Calls:
         
     | 
| 
      
 205 
     | 
    
         
            +
                #-----------------------------------------------------------------
         
     | 
| 
      
 206 
     | 
    
         
            +
             
     | 
| 
      
 207 
     | 
    
         
            +
                # List all distributions.
         
     | 
| 
      
 208 
     | 
    
         
            +
                # Returns an array of distributions or RightAws::AwsError exception.
         
     | 
| 
      
 209 
     | 
    
         
            +
                #
         
     | 
| 
      
 210 
     | 
    
         
            +
                #  acf.list_distributions #=>
         
     | 
| 
      
 211 
     | 
    
         
            +
                #    [{:status             => "Deployed",
         
     | 
| 
      
 212 
     | 
    
         
            +
                #      :domain_name        => "d74zzrxmpmygb.6hops.net",
         
     | 
| 
      
 213 
     | 
    
         
            +
                #      :aws_id             => "E4U91HCJHGXVC",
         
     | 
| 
      
 214 
     | 
    
         
            +
                #      :cnames             => ["web1.my-awesome-site.net", "web2.my-awesome-site.net"]
         
     | 
| 
      
 215 
     | 
    
         
            +
                #      :origin             => "my-bucket.s3.amazonaws.com",
         
     | 
| 
      
 216 
     | 
    
         
            +
                #      :comment            => "My comments",
         
     | 
| 
      
 217 
     | 
    
         
            +
                #      :last_modified_time => Wed Sep 10 17:00:04 UTC 2008 }, ..., {...} ]
         
     | 
| 
      
 218 
     | 
    
         
            +
                #
         
     | 
| 
      
 219 
     | 
    
         
            +
                def list_distributions
         
     | 
| 
      
 220 
     | 
    
         
            +
                  result = []
         
     | 
| 
      
 221 
     | 
    
         
            +
                  incrementally_list_distributions do |response|
         
     | 
| 
      
 222 
     | 
    
         
            +
                    result += response[:distributions]
         
     | 
| 
      
 223 
     | 
    
         
            +
                    true
         
     | 
| 
      
 224 
     | 
    
         
            +
                  end
         
     | 
| 
      
 225 
     | 
    
         
            +
                  result
         
     | 
| 
      
 226 
     | 
    
         
            +
                end
         
     | 
| 
      
 227 
     | 
    
         
            +
             
     | 
| 
      
 228 
     | 
    
         
            +
                # Incrementally list distributions.
         
     | 
| 
      
 229 
     | 
    
         
            +
                # 
         
     | 
| 
      
 230 
     | 
    
         
            +
                # Optional params: +:marker+ and +:max_items+.
         
     | 
| 
      
 231 
     | 
    
         
            +
                #
         
     | 
| 
      
 232 
     | 
    
         
            +
                #   # get first distribution
         
     | 
| 
      
 233 
     | 
    
         
            +
                #   incrementally_list_distributions(:max_items => 1) #=>
         
     | 
| 
      
 234 
     | 
    
         
            +
                #      {:distributions=>
         
     | 
| 
      
 235 
     | 
    
         
            +
                #        [{:status=>"Deployed",
         
     | 
| 
      
 236 
     | 
    
         
            +
                #          :aws_id=>"E2Q0AOOMFNPSYL",
         
     | 
| 
      
 237 
     | 
    
         
            +
                #          :logging=>{},
         
     | 
| 
      
 238 
     | 
    
         
            +
                #          :origin=>"my-bucket.s3.amazonaws.com",
         
     | 
| 
      
 239 
     | 
    
         
            +
                #          :domain_name=>"d1s5gmdtmafnre.6hops.net",
         
     | 
| 
      
 240 
     | 
    
         
            +
                #          :comment=>"ONE LINE OF COMMENT",
         
     | 
| 
      
 241 
     | 
    
         
            +
                #          :last_modified_time=>Wed Oct 22 19:31:23 UTC 2008,
         
     | 
| 
      
 242 
     | 
    
         
            +
                #          :enabled=>true,
         
     | 
| 
      
 243 
     | 
    
         
            +
                #          :cnames=>[]}],
         
     | 
| 
      
 244 
     | 
    
         
            +
                #       :is_truncated=>true,
         
     | 
| 
      
 245 
     | 
    
         
            +
                #       :max_items=>1,
         
     | 
| 
      
 246 
     | 
    
         
            +
                #       :marker=>"",
         
     | 
| 
      
 247 
     | 
    
         
            +
                #       :next_marker=>"E2Q0AOOMFNPSYL"}
         
     | 
| 
      
 248 
     | 
    
         
            +
                #
         
     | 
| 
      
 249 
     | 
    
         
            +
                #   # get max 100 distributions (the list will be restricted by a default MaxItems value ==100 )
         
     | 
| 
      
 250 
     | 
    
         
            +
                #   incrementally_list_distributions
         
     | 
| 
      
 251 
     | 
    
         
            +
                #
         
     | 
| 
      
 252 
     | 
    
         
            +
                #   # list distributions by 10
         
     | 
| 
      
 253 
     | 
    
         
            +
                #   incrementally_list_distributions(:max_items => 10) do |response|
         
     | 
| 
      
 254 
     | 
    
         
            +
                #     puts response.inspect # a list of 10 distributions
         
     | 
| 
      
 255 
     | 
    
         
            +
                #     false # return false if the listing should be broken otherwise use true
         
     | 
| 
      
 256 
     | 
    
         
            +
                #   end
         
     | 
| 
      
 257 
     | 
    
         
            +
                #
         
     | 
| 
      
 258 
     | 
    
         
            +
                def incrementally_list_distributions(params={}, &block)
         
     | 
| 
      
 259 
     | 
    
         
            +
                  opts = {}
         
     | 
| 
      
 260 
     | 
    
         
            +
                  opts['MaxItems'] = params[:max_items] if params[:max_items]
         
     | 
| 
      
 261 
     | 
    
         
            +
                  opts['Marker']   = params[:marker]    if params[:marker]
         
     | 
| 
      
 262 
     | 
    
         
            +
                  last_response = nil
         
     | 
| 
      
 263 
     | 
    
         
            +
                  loop do
         
     | 
| 
      
 264 
     | 
    
         
            +
                    link = generate_request('GET', 'distribution', opts)
         
     | 
| 
      
 265 
     | 
    
         
            +
                    last_response = request_info(link,  AcfDistributionListParser.new(:logger => @logger))
         
     | 
| 
      
 266 
     | 
    
         
            +
                    opts['Marker'] = last_response[:next_marker]
         
     | 
| 
      
 267 
     | 
    
         
            +
                    break unless block && block.call(last_response) && !last_response[:next_marker].blank?
         
     | 
| 
      
 268 
     | 
    
         
            +
                  end 
         
     | 
| 
      
 269 
     | 
    
         
            +
                  last_response 
         
     | 
| 
      
 270 
     | 
    
         
            +
                end
         
     | 
| 
      
 271 
     | 
    
         
            +
             
     | 
| 
      
 272 
     | 
    
         
            +
                # Create a new distribution.
         
     | 
| 
      
 273 
     | 
    
         
            +
                # Returns the just created distribution or RightAws::AwsError exception.
         
     | 
| 
      
 274 
     | 
    
         
            +
                #
         
     | 
| 
      
 275 
     | 
    
         
            +
                #  acf.create_distribution('my-bucket.s3.amazonaws.com', 'Woo-Hoo!', true, ['web1.my-awesome-site.net'],
         
     | 
| 
      
 276 
     | 
    
         
            +
                #                          { :prefix=>"log/", :bucket=>"my-logs.s3.amazonaws.com" } ) #=>
         
     | 
| 
      
 277 
     | 
    
         
            +
                #    {:comment            => "Woo-Hoo!",
         
     | 
| 
      
 278 
     | 
    
         
            +
                #     :enabled            => true,
         
     | 
| 
      
 279 
     | 
    
         
            +
                #     :location           => "https://cloudfront.amazonaws.com/2008-06-30/distribution/E2REJM3VUN5RSI",
         
     | 
| 
      
 280 
     | 
    
         
            +
                #     :status             => "InProgress",
         
     | 
| 
      
 281 
     | 
    
         
            +
                #     :aws_id             => "E2REJM3VUN5RSI",
         
     | 
| 
      
 282 
     | 
    
         
            +
                #     :domain_name        => "d3dxv71tbbt6cd.6hops.net",
         
     | 
| 
      
 283 
     | 
    
         
            +
                #     :origin             => "my-bucket.s3.amazonaws.com",
         
     | 
| 
      
 284 
     | 
    
         
            +
                #     :cnames             => ["web1.my-awesome-site.net"],
         
     | 
| 
      
 285 
     | 
    
         
            +
                #     :logging            => { :prefix => "log/",
         
     | 
| 
      
 286 
     | 
    
         
            +
                #                              :bucket => "my-logs.s3.amazonaws.com"},
         
     | 
| 
      
 287 
     | 
    
         
            +
                #     :last_modified_time => Wed Sep 10 17:00:54 UTC 2008,
         
     | 
| 
      
 288 
     | 
    
         
            +
                #     :caller_reference   => "200809102100536497863003"}
         
     | 
| 
      
 289 
     | 
    
         
            +
                #
         
     | 
| 
      
 290 
     | 
    
         
            +
                def create_distribution(origin, comment='', enabled=true, cnames=[], caller_reference=nil, logging={})
         
     | 
| 
      
 291 
     | 
    
         
            +
                  config = { :origin  => origin,
         
     | 
| 
      
 292 
     | 
    
         
            +
                             :comment => comment,
         
     | 
| 
      
 293 
     | 
    
         
            +
                             :enabled => enabled,
         
     | 
| 
      
 294 
     | 
    
         
            +
                             :cnames  => cnames.to_a,
         
     | 
| 
      
 295 
     | 
    
         
            +
                             :caller_reference => caller_reference }
         
     | 
| 
      
 296 
     | 
    
         
            +
                  config[:logging] = logging unless logging.blank?
         
     | 
| 
      
 297 
     | 
    
         
            +
                  create_distribution_by_config(config)
         
     | 
| 
      
 298 
     | 
    
         
            +
                end
         
     | 
| 
      
 299 
     | 
    
         
            +
             
     | 
| 
      
 300 
     | 
    
         
            +
                def create_distribution_by_config(config)
         
     | 
| 
      
 301 
     | 
    
         
            +
                  config[:caller_reference] ||= generate_call_reference
         
     | 
| 
      
 302 
     | 
    
         
            +
                  link = generate_request('POST', 'distribution', {}, config_to_xml(config))
         
     | 
| 
      
 303 
     | 
    
         
            +
                  merge_headers(request_info(link, AcfDistributionListParser.new(:logger => @logger))[:distributions].first)
         
     | 
| 
      
 304 
     | 
    
         
            +
                end
         
     | 
| 
      
 305 
     | 
    
         
            +
             
     | 
| 
      
 306 
     | 
    
         
            +
                # Get a distribution's information.
         
     | 
| 
      
 307 
     | 
    
         
            +
                # Returns a distribution's information or RightAws::AwsError exception.
         
     | 
| 
      
 308 
     | 
    
         
            +
                #
         
     | 
| 
      
 309 
     | 
    
         
            +
                #  acf.get_distribution('E2REJM3VUN5RSI') #=>
         
     | 
| 
      
 310 
     | 
    
         
            +
                #    {:enabled            => true,
         
     | 
| 
      
 311 
     | 
    
         
            +
                #     :caller_reference   => "200809102100536497863003",
         
     | 
| 
      
 312 
     | 
    
         
            +
                #     :e_tag              => "E39OHHU1ON65SI",
         
     | 
| 
      
 313 
     | 
    
         
            +
                #     :status             => "Deployed",
         
     | 
| 
      
 314 
     | 
    
         
            +
                #     :domain_name        => "d3dxv71tbbt6cd.6hops.net",
         
     | 
| 
      
 315 
     | 
    
         
            +
                #     :cnames             => ["web1.my-awesome-site.net", "web2.my-awesome-site.net"]
         
     | 
| 
      
 316 
     | 
    
         
            +
                #     :aws_id             => "E2REJM3VUN5RSI",
         
     | 
| 
      
 317 
     | 
    
         
            +
                #     :comment            => "Woo-Hoo!",
         
     | 
| 
      
 318 
     | 
    
         
            +
                #     :origin             => "my-bucket.s3.amazonaws.com",
         
     | 
| 
      
 319 
     | 
    
         
            +
                #     :last_modified_time => Wed Sep 10 17:00:54 UTC 2008 }
         
     | 
| 
      
 320 
     | 
    
         
            +
                #
         
     | 
| 
      
 321 
     | 
    
         
            +
                def get_distribution(aws_id)
         
     | 
| 
      
 322 
     | 
    
         
            +
                  link = generate_request('GET', "distribution/#{aws_id}")
         
     | 
| 
      
 323 
     | 
    
         
            +
                  merge_headers(request_info(link, AcfDistributionListParser.new(:logger => @logger))[:distributions].first)
         
     | 
| 
      
 324 
     | 
    
         
            +
                end
         
     | 
| 
      
 325 
     | 
    
         
            +
             
     | 
| 
      
 326 
     | 
    
         
            +
                # Get a distribution's configuration.
         
     | 
| 
      
 327 
     | 
    
         
            +
                # Returns a distribution's configuration or RightAws::AwsError exception.
         
     | 
| 
      
 328 
     | 
    
         
            +
                #
         
     | 
| 
      
 329 
     | 
    
         
            +
                #  acf.get_distribution_config('E2REJM3VUN5RSI') #=>
         
     | 
| 
      
 330 
     | 
    
         
            +
                #    {:enabled          => true,
         
     | 
| 
      
 331 
     | 
    
         
            +
                #     :caller_reference => "200809102100536497863003",
         
     | 
| 
      
 332 
     | 
    
         
            +
                #     :e_tag            => "E39OHHU1ON65SI",
         
     | 
| 
      
 333 
     | 
    
         
            +
                #     :cnames           => ["web1.my-awesome-site.net", "web2.my-awesome-site.net"]
         
     | 
| 
      
 334 
     | 
    
         
            +
                #     :comment          => "Woo-Hoo!",
         
     | 
| 
      
 335 
     | 
    
         
            +
                #     :origin           => "my-bucket.s3.amazonaws.com"}
         
     | 
| 
      
 336 
     | 
    
         
            +
                #
         
     | 
| 
      
 337 
     | 
    
         
            +
                def get_distribution_config(aws_id)
         
     | 
| 
      
 338 
     | 
    
         
            +
                  link = generate_request('GET', "distribution/#{aws_id}/config")
         
     | 
| 
      
 339 
     | 
    
         
            +
                  merge_headers(request_info(link, AcfDistributionListParser.new(:logger => @logger))[:distributions].first)
         
     | 
| 
      
 340 
     | 
    
         
            +
                end
         
     | 
| 
      
 341 
     | 
    
         
            +
             
     | 
| 
      
 342 
     | 
    
         
            +
                # Set a distribution's configuration 
         
     | 
| 
      
 343 
     | 
    
         
            +
                # (the :origin and the :caller_reference cannot be changed).
         
     | 
| 
      
 344 
     | 
    
         
            +
                # Returns +true+ on success or RightAws::AwsError exception.
         
     | 
| 
      
 345 
     | 
    
         
            +
                #
         
     | 
| 
      
 346 
     | 
    
         
            +
                #  config = acf.get_distribution_config('E2REJM3VUN5RSI') #=>
         
     | 
| 
      
 347 
     | 
    
         
            +
                #    {:enabled          => true,
         
     | 
| 
      
 348 
     | 
    
         
            +
                #     :caller_reference => "200809102100536497863003",
         
     | 
| 
      
 349 
     | 
    
         
            +
                #     :e_tag            => "E39OHHU1ON65SI",
         
     | 
| 
      
 350 
     | 
    
         
            +
                #     :cnames           => ["web1.my-awesome-site.net", "web2.my-awesome-site.net"]
         
     | 
| 
      
 351 
     | 
    
         
            +
                #     :comment          => "Woo-Hoo!",
         
     | 
| 
      
 352 
     | 
    
         
            +
                #     :origin           => "my-bucket.s3.amazonaws.com"}
         
     | 
| 
      
 353 
     | 
    
         
            +
                #  config[:comment] = 'Olah-lah!'
         
     | 
| 
      
 354 
     | 
    
         
            +
                #  config[:enabled] = false
         
     | 
| 
      
 355 
     | 
    
         
            +
                #  acf.set_distribution_config('E2REJM3VUN5RSI', config) #=> true
         
     | 
| 
      
 356 
     | 
    
         
            +
                #
         
     | 
| 
      
 357 
     | 
    
         
            +
                def set_distribution_config(aws_id, config)
         
     | 
| 
      
 358 
     | 
    
         
            +
                  link = generate_request('PUT', "distribution/#{aws_id}/config", {}, config_to_xml(config),
         
     | 
| 
      
 359 
     | 
    
         
            +
                                                 'If-Match' => config[:e_tag])
         
     | 
| 
      
 360 
     | 
    
         
            +
                  request_info(link, RightHttp2xxParser.new(:logger => @logger))
         
     | 
| 
      
 361 
     | 
    
         
            +
                end
         
     | 
| 
      
 362 
     | 
    
         
            +
             
     | 
| 
      
 363 
     | 
    
         
            +
                # Delete a distribution. The enabled distribution cannot be deleted.
         
     | 
| 
      
 364 
     | 
    
         
            +
                # Returns +true+ on success or RightAws::AwsError exception.
         
     | 
| 
      
 365 
     | 
    
         
            +
                #
         
     | 
| 
      
 366 
     | 
    
         
            +
                #  acf.delete_distribution('E2REJM3VUN5RSI', 'E39OHHU1ON65SI') #=> true
         
     | 
| 
      
 367 
     | 
    
         
            +
                #
         
     | 
| 
      
 368 
     | 
    
         
            +
                def delete_distribution(aws_id, e_tag)
         
     | 
| 
      
 369 
     | 
    
         
            +
                  link = generate_request('DELETE', "distribution/#{aws_id}", {}, nil,
         
     | 
| 
      
 370 
     | 
    
         
            +
                                                    'If-Match' => e_tag)
         
     | 
| 
      
 371 
     | 
    
         
            +
                  request_info(link, RightHttp2xxParser.new(:logger => @logger))
         
     | 
| 
      
 372 
     | 
    
         
            +
                end
         
     | 
| 
      
 373 
     | 
    
         
            +
             
     | 
| 
      
 374 
     | 
    
         
            +
                #-----------------------------------------------------------------
         
     | 
| 
      
 375 
     | 
    
         
            +
                #      PARSERS:
         
     | 
| 
      
 376 
     | 
    
         
            +
                #-----------------------------------------------------------------
         
     | 
| 
      
 377 
     | 
    
         
            +
             
     | 
| 
      
 378 
     | 
    
         
            +
                class AcfDistributionListParser < RightAWSParser # :nodoc:
         
     | 
| 
      
 379 
     | 
    
         
            +
                  def reset
         
     | 
| 
      
 380 
     | 
    
         
            +
                    @result = { :distributions => [] }
         
     | 
| 
      
 381 
     | 
    
         
            +
                  end
         
     | 
| 
      
 382 
     | 
    
         
            +
                  def tagstart(name, attributes)
         
     | 
| 
      
 383 
     | 
    
         
            +
                    if name == 'DistributionSummary' || name == 'Distribution' ||
         
     | 
| 
      
 384 
     | 
    
         
            +
                      (name == 'DistributionConfig' && @xmlpath.blank?)
         
     | 
| 
      
 385 
     | 
    
         
            +
                      @distribution = { :cnames  => [], :logging => {} }
         
     | 
| 
      
 386 
     | 
    
         
            +
                    end
         
     | 
| 
      
 387 
     | 
    
         
            +
                  end
         
     | 
| 
      
 388 
     | 
    
         
            +
                  def tagend(name)
         
     | 
| 
      
 389 
     | 
    
         
            +
                    case name
         
     | 
| 
      
 390 
     | 
    
         
            +
                      when 'Marker'      then @result[:marker]       = @text
         
     | 
| 
      
 391 
     | 
    
         
            +
                      when 'NextMarker'  then @result[:next_marker]  = @text
         
     | 
| 
      
 392 
     | 
    
         
            +
                      when 'MaxItems'    then @result[:max_items]    = @text.to_i
         
     | 
| 
      
 393 
     | 
    
         
            +
                      when 'IsTruncated' then @result[:is_truncated] = @text == 'true' ? true : false
         
     | 
| 
      
 394 
     | 
    
         
            +
                      when 'Id'               then @distribution[:aws_id]             = @text
         
     | 
| 
      
 395 
     | 
    
         
            +
                      when 'Status'           then @distribution[:status]             = @text
         
     | 
| 
      
 396 
     | 
    
         
            +
                      when 'LastModifiedTime' then @distribution[:last_modified_time] = Time.parse(@text)
         
     | 
| 
      
 397 
     | 
    
         
            +
                      when 'DomainName'       then @distribution[:domain_name]        = @text
         
     | 
| 
      
 398 
     | 
    
         
            +
                      when 'Origin'           then @distribution[:origin]             = @text
         
     | 
| 
      
 399 
     | 
    
         
            +
                      when 'Comment'          then @distribution[:comment]            = AcfInterface::unescape(@text)
         
     | 
| 
      
 400 
     | 
    
         
            +
                      when 'CallerReference'  then @distribution[:caller_reference]   = @text
         
     | 
| 
      
 401 
     | 
    
         
            +
                      when 'CNAME'            then @distribution[:cnames]            << @text
         
     | 
| 
      
 402 
     | 
    
         
            +
                      when 'Enabled'          then @distribution[:enabled]            = @text == 'true' ? true : false
         
     | 
| 
      
 403 
     | 
    
         
            +
                      when 'Bucket'           then @distribution[:logging][:bucket]   = @text
         
     | 
| 
      
 404 
     | 
    
         
            +
                      when 'Prefix'           then @distribution[:logging][:prefix]   = @text
         
     | 
| 
      
 405 
     | 
    
         
            +
                    end
         
     | 
| 
      
 406 
     | 
    
         
            +
                    if name == 'DistributionSummary' || name == 'Distribution' ||
         
     | 
| 
      
 407 
     | 
    
         
            +
                      (name == 'DistributionConfig' && @xmlpath.blank?)
         
     | 
| 
      
 408 
     | 
    
         
            +
                      @result[:distributions] << @distribution
         
     | 
| 
      
 409 
     | 
    
         
            +
                    end
         
     | 
| 
      
 410 
     | 
    
         
            +
                  end
         
     | 
| 
      
 411 
     | 
    
         
            +
                end
         
     | 
| 
      
 412 
     | 
    
         
            +
              end
         
     | 
| 
      
 413 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,39 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #
         
     | 
| 
      
 2 
     | 
    
         
            +
            # Copyright (c) 2007-2008 RightScale Inc
         
     | 
| 
      
 3 
     | 
    
         
            +
            #
         
     | 
| 
      
 4 
     | 
    
         
            +
            # Permission is hereby granted, free of charge, to any person obtaining
         
     | 
| 
      
 5 
     | 
    
         
            +
            # a copy of this software and associated documentation files (the
         
     | 
| 
      
 6 
     | 
    
         
            +
            # "Software"), to deal in the Software without restriction, including
         
     | 
| 
      
 7 
     | 
    
         
            +
            # without limitation the rights to use, copy, modify, merge, publish,
         
     | 
| 
      
 8 
     | 
    
         
            +
            # distribute, sublicense, and/or sell copies of the Software, and to
         
     | 
| 
      
 9 
     | 
    
         
            +
            # permit persons to whom the Software is furnished to do so, subject to
         
     | 
| 
      
 10 
     | 
    
         
            +
            # the following conditions:
         
     | 
| 
      
 11 
     | 
    
         
            +
            #
         
     | 
| 
      
 12 
     | 
    
         
            +
            # The above copyright notice and this permission notice shall be
         
     | 
| 
      
 13 
     | 
    
         
            +
            # included in all copies or substantial portions of the Software.
         
     | 
| 
      
 14 
     | 
    
         
            +
            #
         
     | 
| 
      
 15 
     | 
    
         
            +
            # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         
     | 
| 
      
 16 
     | 
    
         
            +
            # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         
     | 
| 
      
 17 
     | 
    
         
            +
            # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         
     | 
| 
      
 18 
     | 
    
         
            +
            # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
         
     | 
| 
      
 19 
     | 
    
         
            +
            # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
         
     | 
| 
      
 20 
     | 
    
         
            +
            # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
         
     | 
| 
      
 21 
     | 
    
         
            +
            # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         
     | 
| 
      
 22 
     | 
    
         
            +
            #
         
     | 
| 
      
 23 
     | 
    
         
            +
            #
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            # A hack because there's a bug in add! in Benchmark::Tms
         
     | 
| 
      
 27 
     | 
    
         
            +
            module Benchmark  #:nodoc:
         
     | 
| 
      
 28 
     | 
    
         
            +
              class Tms #:nodoc:
         
     | 
| 
      
 29 
     | 
    
         
            +
                def add!(&blk)
         
     | 
| 
      
 30 
     | 
    
         
            +
                  t = Benchmark::measure(&blk)
         
     | 
| 
      
 31 
     | 
    
         
            +
                  @utime  = utime + t.utime
         
     | 
| 
      
 32 
     | 
    
         
            +
                  @stime  = stime + t.stime
         
     | 
| 
      
 33 
     | 
    
         
            +
                  @cutime = cutime + t.cutime
         
     | 
| 
      
 34 
     | 
    
         
            +
                  @cstime = cstime + t.cstime
         
     | 
| 
      
 35 
     | 
    
         
            +
                  @real   = real + t.real
         
     | 
| 
      
 36 
     | 
    
         
            +
                  self
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
            end
         
     |