right_aws 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +47 -0
- data/Manifest.txt +1 -0
- data/README.txt +65 -48
- data/Rakefile +11 -6
- data/lib/awsbase/right_awsbase.rb +94 -25
- data/lib/awsbase/support.rb +106 -0
- data/lib/ec2/right_ec2.rb +257 -140
- data/lib/right_aws.rb +4 -2
- data/lib/s3/right_s3.rb +39 -24
- data/lib/s3/right_s3_interface.rb +13 -16
- data/lib/sqs/right_sqs.rb +30 -19
- data/lib/sqs/right_sqs_interface.rb +49 -43
- data/test/ec2/test_right_ec2.rb +3 -2
- data/test/s3/test_right_s3.rb +1 -1
- data/test/sqs/test_right_sqs.rb +19 -24
- data/test/ts_right_aws.rb +1 -0
- metadata +6 -22
- data/test/awsbase/test_helper.rb +0 -2
- data/test/awsbase/test_right_awsbase.rb +0 -12
data/lib/right_aws.rb
CHANGED
@@ -32,11 +32,11 @@ require "openssl"
|
|
32
32
|
require "digest/sha1"
|
33
33
|
|
34
34
|
require 'rubygems'
|
35
|
-
require 'active_support'
|
36
35
|
require 'right_http_connection'
|
37
36
|
|
38
37
|
$:.unshift(File.dirname(__FILE__))
|
39
38
|
require 'awsbase/benchmark_fix'
|
39
|
+
require 'awsbase/support'
|
40
40
|
require 'awsbase/right_awsbase'
|
41
41
|
require 'ec2/right_ec2'
|
42
42
|
require 's3/right_s3_interface'
|
@@ -48,13 +48,15 @@ require 'sqs/right_sqs'
|
|
48
48
|
module RightAws #:nodoc:
|
49
49
|
module VERSION #:nodoc:
|
50
50
|
MAJOR = 1
|
51
|
-
MINOR =
|
51
|
+
MINOR = 2
|
52
52
|
TINY = 0
|
53
53
|
|
54
54
|
STRING = [MAJOR, MINOR, TINY].join('.')
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
|
+
#-
|
59
|
+
|
58
60
|
# We also want everything available in the Rightscale namespace for backward
|
59
61
|
# compatibility reasons.
|
60
62
|
module Rightscale
|
data/lib/s3/right_s3.rb
CHANGED
@@ -22,20 +22,35 @@
|
|
22
22
|
#
|
23
23
|
|
24
24
|
module RightAws
|
25
|
-
|
25
|
+
|
26
|
+
# = RightAws::S3 -- RightScale's Amazon S3 interface
|
27
|
+
# The RightAws::S3 class provides a complete interface to Amazon's Simple
|
28
|
+
# Storage Service.
|
29
|
+
# For explanations of the semantics
|
30
|
+
# of each call, please refer to Amazon's documentation at
|
31
|
+
# http://developer.amazonwebservices.com/connect/kbcategory.jspa?categoryID=48
|
32
|
+
#
|
33
|
+
# See examples below for the bucket and buckets methods.
|
34
|
+
#
|
35
|
+
# Error handling: all operations raise an RightAws::AwsError in case
|
36
|
+
# of problems. Note that transient errors are automatically retried.
|
37
|
+
|
26
38
|
class S3
|
27
39
|
attr_reader :interface
|
28
40
|
|
41
|
+
# Create a new handle to an S3 account. All handles share the same per process or per thread
|
42
|
+
# HTTP connection to Amazon S3. Each handle is for a specific account.
|
43
|
+
# The +params+ are passed through as-is to RightAws::S3Interface.new
|
29
44
|
def initialize(aws_access_key_id, aws_secret_access_key, params={})
|
30
45
|
@interface = S3Interface.new(aws_access_key_id, aws_secret_access_key, params)
|
31
46
|
end
|
32
47
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
48
|
+
# Retrieve a list of buckets.
|
49
|
+
# Returns an array of RightAws::S3::Bucket instances.
|
50
|
+
# # Create handle to S3 account
|
51
|
+
# s3 = RightAws::S3.new(aws_access_key_id, aws_secret_access_key)
|
52
|
+
# my_buckets_names = s3.buckets.map{|b| b.name}
|
53
|
+
# puts "Buckets on S3: #{my_bucket_names.join(', ')}"
|
39
54
|
def buckets
|
40
55
|
@interface.list_all_my_buckets.map! do |entry|
|
41
56
|
owner = Owner.new(entry[:owner_id], entry[:owner_display_name])
|
@@ -43,23 +58,23 @@ module RightAws
|
|
43
58
|
end
|
44
59
|
end
|
45
60
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
61
|
+
# Retrieve an individual bucket.
|
62
|
+
# If the bucket does not exist and +create+ is set, a new bucket
|
63
|
+
# is created on S3. The +create+ parameter has no effect if
|
64
|
+
# the bucket alrady exists.
|
65
|
+
# Returns a RightAws::S3::Bucket instance or +nil+ if the bucket does not exist
|
66
|
+
# and +create+ is not set.
|
67
|
+
#
|
68
|
+
# s3 = RightAws::S3.new(aws_access_key_id, aws_secret_access_key)
|
69
|
+
# bucket1 = s3.bucket('my_awesome_bucket')
|
70
|
+
# bucket1.keys #=> exception here if the bucket does not exists
|
71
|
+
# ...
|
72
|
+
# bucket2 = s3.bucket('my_awesome_bucket', true)
|
73
|
+
# bucket2.keys #=> list of keys
|
74
|
+
#
|
75
|
+
# see http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAccessPolicy.html
|
76
|
+
# (section: Canned Access Policies)
|
77
|
+
#
|
63
78
|
def bucket(name, create=true, perms=nil, headers={})
|
64
79
|
headers['x-amz-acl'] = perms if perms
|
65
80
|
@interface.create_bucket(name, headers) if create
|
@@ -29,7 +29,7 @@ module RightAws
|
|
29
29
|
DEFAULT_PORT = 443
|
30
30
|
DEFAULT_PROTOCOL = 'https'
|
31
31
|
REQUEST_TTL = 30
|
32
|
-
DEFAULT_EXPIRES_AFTER = 1
|
32
|
+
DEFAULT_EXPIRES_AFTER = 1 * 24 * 60 * 60 # One day's worth of seconds
|
33
33
|
AMAZON_HEADER_PREFIX = 'x-amz-'
|
34
34
|
AMAZON_METADATA_PREFIX = 'x-amz-meta-'
|
35
35
|
|
@@ -68,13 +68,15 @@ module RightAws
|
|
68
68
|
# Benchmark::Tms instance for XML parsing benchmark.
|
69
69
|
def self.bench_xml; @@bench_xml; end # For benchmark puposes.
|
70
70
|
|
71
|
-
# Returns a list of Amazon service responses which are known
|
72
|
-
# We have to re-request
|
71
|
+
# Returns a list of Amazon service responses which are known to be transient problems.
|
72
|
+
# We have to re-request if we get any of them, because the problem will probably disappear.
|
73
|
+
# By default this method returns the same value as the AMAZON_PROBLEMS const.
|
73
74
|
def self.amazon_problems
|
74
75
|
@@amazon_problems
|
75
76
|
end
|
76
77
|
|
77
|
-
# Sets
|
78
|
+
# Sets the list of Amazon side problems. Use in conjunction with the
|
79
|
+
# getter to append problems.
|
78
80
|
def self.amazon_problems=(problems_list)
|
79
81
|
@@amazon_problems = problems_list
|
80
82
|
end
|
@@ -111,6 +113,7 @@ module RightAws
|
|
111
113
|
@logger = RAILS_DEFAULT_LOGGER if !@logger && defined?(RAILS_DEFAULT_LOGGER)
|
112
114
|
@logger = Logger.new(STDOUT) if !@logger
|
113
115
|
@logger.info "New #{self.class.name} using #{@params[:multi_thread] ? 'multi' : 'single'}-threaded mode"
|
116
|
+
@error_handler = nil
|
114
117
|
end
|
115
118
|
|
116
119
|
# TODO TRB 6/19/07 - Service gem common method
|
@@ -163,7 +166,7 @@ module RightAws
|
|
163
166
|
headers['content-type'] ||= ''
|
164
167
|
headers['date'] = Time.now.httpdate
|
165
168
|
# create request
|
166
|
-
request = "Net::HTTP::#{method.
|
169
|
+
request = "Net::HTTP::#{method.capitalize}".constantize.new(URI::escape(CGI::unescape(path)))
|
167
170
|
request.body = data if data
|
168
171
|
# set request headers and meta headers
|
169
172
|
headers.each { |key, value| request[key.to_s] = value }
|
@@ -219,13 +222,7 @@ module RightAws
|
|
219
222
|
@last_response = response
|
220
223
|
if response.is_a?(Net::HTTPSuccess)
|
221
224
|
@error_handler = nil
|
222
|
-
@@bench_xml.add!
|
223
|
-
if parser.kind_of?(RightAWSParser)
|
224
|
-
REXML::Document.parse_stream(response.body, parser)
|
225
|
-
else
|
226
|
-
parser.parse(response)
|
227
|
-
end
|
228
|
-
end
|
225
|
+
@@bench_xml.add! { parser.parse(response) }
|
229
226
|
return parser.result
|
230
227
|
else
|
231
228
|
@error_handler = AWSErrorHandler.new(self, parser, @@amazon_problems) unless @error_handler
|
@@ -253,7 +250,7 @@ module RightAws
|
|
253
250
|
#
|
254
251
|
def list_all_my_buckets(headers={})
|
255
252
|
req_hash = generate_rest_request('GET', headers.merge(:url=>''))
|
256
|
-
request_info(req_hash, S3ListAllMyBucketsParser.new)
|
253
|
+
request_info(req_hash, S3ListAllMyBucketsParser.new(:logger => @logger))
|
257
254
|
rescue
|
258
255
|
on_exception
|
259
256
|
end
|
@@ -301,7 +298,7 @@ module RightAws
|
|
301
298
|
def list_bucket(bucket, options={}, headers={})
|
302
299
|
bucket += '?'+options.map{|k, v| "#{k.to_s}=#{CGI::escape v.to_s}"}.join('&') unless options.blank?
|
303
300
|
req_hash = generate_rest_request('GET', headers.merge(:url=>bucket))
|
304
|
-
request_info(req_hash, S3ListBucketParser.new)
|
301
|
+
request_info(req_hash, S3ListBucketParser.new(:logger => @logger))
|
305
302
|
rescue
|
306
303
|
on_exception
|
307
304
|
end
|
@@ -339,7 +336,7 @@ module RightAws
|
|
339
336
|
internal_bucket = bucket.dup
|
340
337
|
internal_bucket += '?'+internal_options.map{|k, v| "#{k.to_s}=#{CGI::escape v.to_s}"}.join('&') unless internal_options.blank?
|
341
338
|
req_hash = generate_rest_request('GET', headers.merge(:url=>internal_bucket))
|
342
|
-
response = request_info(req_hash, S3ImprovedListBucketParser.new)
|
339
|
+
response = request_info(req_hash, S3ImprovedListBucketParser.new(:logger => @logger))
|
343
340
|
there_are_more_keys = response[:is_truncated]
|
344
341
|
if(there_are_more_keys)
|
345
342
|
if(response[:next_marker])
|
@@ -482,7 +479,7 @@ module RightAws
|
|
482
479
|
def get_acl_parse(bucket, key='', headers={})
|
483
480
|
key = key.blank? ? '' : "/#{CGI::escape key}"
|
484
481
|
req_hash = generate_rest_request('GET', headers.merge(:url=>"#{bucket}#{key}?acl"))
|
485
|
-
acl = request_info(req_hash, S3AclParser.new)
|
482
|
+
acl = request_info(req_hash, S3AclParser.new(:logger => @logger))
|
486
483
|
result = {}
|
487
484
|
result[:owner] = acl[:owner]
|
488
485
|
result[:grantees] = {}
|
data/lib/sqs/right_sqs.rb
CHANGED
@@ -24,7 +24,15 @@
|
|
24
24
|
module RightAws
|
25
25
|
|
26
26
|
#
|
27
|
-
# SQS
|
27
|
+
# = RightAws::Sqs -- RightScale's Amazon SQS interface
|
28
|
+
# The RightAws::Sqs class provides a complete interface to Amazon's Simple
|
29
|
+
# Queue Service.
|
30
|
+
# For explanations of the semantics
|
31
|
+
# of each call, please refer to Amazon's documentation at
|
32
|
+
# http://developer.amazonwebservices.com/connect/kbcategory.jspa?categoryID=31
|
33
|
+
#
|
34
|
+
# Error handling: all operations raise an RightAws::AwsError in case
|
35
|
+
# of problems. Note that transient errors are automatically retried.
|
28
36
|
#
|
29
37
|
# sqs = RightAws::Sqs.new(aws_access_key_id, aws_secret_access_key)
|
30
38
|
# queue1 = sqs.queue('my_awesome_queue')
|
@@ -66,7 +74,7 @@ module RightAws
|
|
66
74
|
end
|
67
75
|
|
68
76
|
# Returns Queue instance by queue name.
|
69
|
-
# If the queue does not exist at Amazon SQS and +create+
|
77
|
+
# If the queue does not exist at Amazon SQS and +create+ is true, the method creates it.
|
70
78
|
#
|
71
79
|
# RightAws::Sqs.queue('my_awesome_queue') #=> #<RightAws::Sqs::Queue:0xb7b626e4 ... >
|
72
80
|
#
|
@@ -81,16 +89,16 @@ module RightAws
|
|
81
89
|
attr_reader :name, :url, :sqs
|
82
90
|
|
83
91
|
# Returns Queue instance by queue name.
|
84
|
-
# If the queue does not exist at Amazon SQS and +create+
|
92
|
+
# If the queue does not exist at Amazon SQS and +create+ is true, the method creates it.
|
85
93
|
#
|
86
94
|
# RightAws::Sqs::Queue.create(sqs, 'my_awesome_queue') #=> #<RightAws::Sqs::Queue:0xb7b626e4 ... >
|
87
95
|
#
|
88
96
|
def self.create(sqs, url_or_name, create=true, visibility=nil)
|
89
|
-
sqs.queue(url_or_name, create
|
97
|
+
sqs.queue(url_or_name, create, visibility)
|
90
98
|
end
|
91
99
|
|
92
100
|
# Creates new Queue instance.
|
93
|
-
# Does not create queue at Amazon.
|
101
|
+
# Does not create a queue at Amazon.
|
94
102
|
#
|
95
103
|
# queue = RightAws::Sqs::Queue.new(sqs, 'my_awesome_queue')
|
96
104
|
#
|
@@ -114,17 +122,20 @@ module RightAws
|
|
114
122
|
# queue.clear(true) #=> true
|
115
123
|
#
|
116
124
|
# P.S. when <tt>force==true</tt> the queue deletes then creates again. This is
|
117
|
-
# the quickest method to clear big queue
|
118
|
-
# attributes
|
119
|
-
# this queue. If you have no grantees except
|
120
|
-
#
|
125
|
+
# the quickest method to clear a big queue or a queue with 'locked' messages. All queue
|
126
|
+
# attributes are restored. But there is no way to restore grantees' permissions to
|
127
|
+
# this queue. If you have no grantees except 'root' then you have no problems.
|
128
|
+
# Otherwise, it's better to use <tt>queue.clear(false)</tt>.
|
129
|
+
#
|
130
|
+
# PS This function is no longer supported. Amazon has changed the SQS semantics to require at least 60 seconds between
|
131
|
+
# queue deletion and creation. Hence this method will fail with an exception.
|
121
132
|
#
|
122
133
|
def clear(force=false)
|
123
|
-
if force
|
124
|
-
@sqs.interface.force_clear_queue(@url)
|
125
|
-
else
|
134
|
+
## if force
|
135
|
+
## @sqs.interface.force_clear_queue(@url)
|
136
|
+
## else
|
126
137
|
@sqs.interface.clear_queue(@url)
|
127
|
-
end
|
138
|
+
## end
|
128
139
|
end
|
129
140
|
|
130
141
|
# Deletes queue.
|
@@ -147,7 +158,7 @@ module RightAws
|
|
147
158
|
end
|
148
159
|
alias_method :push, :send_message
|
149
160
|
|
150
|
-
# Retrieves
|
161
|
+
# Retrieves several messages from queue.
|
151
162
|
# Returns an array of Message instances.
|
152
163
|
#
|
153
164
|
# queue.receive_messages(2,10) #=> array of messages
|
@@ -228,7 +239,7 @@ module RightAws
|
|
228
239
|
|
229
240
|
# Retrieves queue attributes.
|
230
241
|
# At this moment Amazon supports +VisibilityTimeout+ and +ApproximateNumberOfMessages+ only.
|
231
|
-
# If the name of attribute is set
|
242
|
+
# If the name of attribute is set, returns its value. Otherwise, returns a hash of attributes.
|
232
243
|
#
|
233
244
|
# queue.get_attribute('VisibilityTimeout') #=> '100'
|
234
245
|
#
|
@@ -237,9 +248,9 @@ module RightAws
|
|
237
248
|
attribute=='All' ? attributes : attributes[attribute]
|
238
249
|
end
|
239
250
|
|
240
|
-
# Retrieves a list grantees.
|
251
|
+
# Retrieves a list of grantees.
|
241
252
|
# Returns an +array+ of Grantee instances if the +grantee_email_address+ is unset.
|
242
|
-
#
|
253
|
+
# Otherwise returns a Grantee instance that points to +grantee_email_address+ or +nil+.
|
243
254
|
#
|
244
255
|
# grantees = queue.grantees #=> [#<RightAws::Sqs::Grantee:0xb7bf0888 ... >, ...]
|
245
256
|
# ...
|
@@ -312,7 +323,7 @@ module RightAws
|
|
312
323
|
end
|
313
324
|
|
314
325
|
# Retrieves security information for grantee identified by email.
|
315
|
-
# Returns +nil+ if
|
326
|
+
# Returns +nil+ if the named user has no privileges on this queue, or
|
316
327
|
# +true+ if perms updated successfully.
|
317
328
|
def retrieve # :nodoc:
|
318
329
|
@id = nil
|
@@ -331,7 +342,7 @@ module RightAws
|
|
331
342
|
|
332
343
|
# Adds permissions for grantee.
|
333
344
|
# Permission: 'FULLCONTROL' | 'RECEIVEMESSAGE' | 'SENDMESSAGE'.
|
334
|
-
#
|
345
|
+
# The caller must have set the email instance variable.
|
335
346
|
def grant(permission=nil)
|
336
347
|
raise "You can't grant permission without defining a grantee email address!" unless @email
|
337
348
|
@queue.sqs.interface.add_grant(@queue.url, @email, permission)
|
@@ -32,7 +32,7 @@ module RightAws
|
|
32
32
|
DEFAULT_PROTOCOL = 'https'
|
33
33
|
REQUEST_TTL = 30
|
34
34
|
DEFAULT_VISIBILITY_TIMEOUT = 30
|
35
|
-
# A list
|
35
|
+
# A list of Amazon problems we can handle via AWSErrorHandler.
|
36
36
|
@@amazon_problems = RightAws::AMAZON_PROBLEMS
|
37
37
|
|
38
38
|
# Current aws_access_key_id
|
@@ -53,25 +53,27 @@ module RightAws
|
|
53
53
|
@@bench_sqs = Benchmark::Tms.new()
|
54
54
|
@@bench_xml = Benchmark::Tms.new()
|
55
55
|
|
56
|
-
# Benchmark::Tms instance for SQS access
|
56
|
+
# Benchmark::Tms instance for SQS access benchmarking.
|
57
57
|
def self.bench_sqs; @@bench_sqs; end
|
58
|
-
# Benchmark::Tms instance for XML parsing
|
59
|
-
def self.bench_xml; @@bench_xml; end # For benchmark
|
58
|
+
# Benchmark::Tms instance for XML parsing benchmarking.
|
59
|
+
def self.bench_xml; @@bench_xml; end # For benchmark purposes.
|
60
60
|
|
61
|
-
# Returns a list of Amazon service responses which are known
|
62
|
-
# We have to re-request
|
61
|
+
# Returns a list of Amazon service responses which are known to be transient problems.
|
62
|
+
# We have to re-request if we get any of them, because the problem will probably disappear.
|
63
|
+
# By default this method returns the same value as the AMAZON_PROBLEMS const.
|
63
64
|
def self.amazon_problems
|
64
65
|
@@amazon_problems
|
65
66
|
end
|
66
67
|
|
67
|
-
# Sets
|
68
|
+
# Sets the list of Amazon side problems. Use in conjunction with the
|
69
|
+
# getter to append problems.
|
68
70
|
def self.amazon_problems=(problems_list)
|
69
71
|
@@amazon_problems = problems_list
|
70
72
|
end
|
71
73
|
|
72
|
-
# Creates new
|
74
|
+
# Creates a new SqsInterface instance.
|
73
75
|
#
|
74
|
-
# sqs =
|
76
|
+
# sqs = RightAws::SqsInterface.new('1E3GDYEOGFJPIT75KDT40','hgTHt68JY07JKUY08ftHYtERkjgtfERn57DFE379', {:multi_thread => true, :logger => Logger.new('/tmp/x.log')}) #=> <RightSqs:0xb7af6264>
|
75
77
|
#
|
76
78
|
# Params is a hash:
|
77
79
|
#
|
@@ -102,7 +104,7 @@ module RightAws
|
|
102
104
|
AwsError::on_aws_exception(self, options)
|
103
105
|
end
|
104
106
|
|
105
|
-
# Return
|
107
|
+
# Return +true+ if this RightS3 instance is running in multi_thread state and +false+ otherwise.
|
106
108
|
def multi_thread
|
107
109
|
@params[:multi_thread]
|
108
110
|
end
|
@@ -111,7 +113,7 @@ module RightAws
|
|
111
113
|
# Requests
|
112
114
|
#-----------------------------------------------------------------
|
113
115
|
|
114
|
-
# Generates request hash for
|
116
|
+
# Generates a request hash for the query API
|
115
117
|
def generate_request(action, param={}) # :nodoc:
|
116
118
|
# Sometimes we need to use queue uri (delete queue etc)
|
117
119
|
# In that case we will use Symbol key: 'param[:queue_url]'
|
@@ -120,7 +122,8 @@ module RightAws
|
|
120
122
|
param.each{ |key, value| param.delete(key) if (value.nil? || key.is_a?(Symbol)) }
|
121
123
|
# prepare output hash
|
122
124
|
request_hash = { "Action" => action,
|
123
|
-
"Expires" => Time.now.utc.since(REQUEST_TTL).strftime("%Y-%m-%dT%H:%M:%SZ"),
|
125
|
+
# "Expires" => Time.now.utc.since(REQUEST_TTL).strftime("%Y-%m-%dT%H:%M:%SZ"),
|
126
|
+
"Expires" => (Time.now + REQUEST_TTL).utc.strftime("%Y-%m-%dT%H:%M:%SZ"),
|
124
127
|
"AWSAccessKeyId" => @aws_access_key_id,
|
125
128
|
"Version" => API_VERSION,
|
126
129
|
"SignatureVersion" => SIGNATURE_VERSION }
|
@@ -136,7 +139,7 @@ module RightAws
|
|
136
139
|
:protocol => @params[:protocol] }
|
137
140
|
end
|
138
141
|
|
139
|
-
# Generates request hash for REST API
|
142
|
+
# Generates a request hash for the REST API
|
140
143
|
def generate_rest_request(method, param) # :nodoc:
|
141
144
|
queue_uri = param[:queue_url] ? URI(param[:queue_url]).path : '/'
|
142
145
|
message = param[:message] # extract message body if nesessary
|
@@ -145,7 +148,7 @@ module RightAws
|
|
145
148
|
# created request
|
146
149
|
param_to_str = param.to_a.collect{|key,val| key.to_s + "=" + CGI::escape(val.to_s) }.join("&")
|
147
150
|
param_to_str = "?#{param_to_str}" unless param_to_str.blank?
|
148
|
-
request = "Net::HTTP::#{method.
|
151
|
+
request = "Net::HTTP::#{method.capitalize}".constantize.new("#{queue_uri}#{param_to_str}")
|
149
152
|
request.body = message if message
|
150
153
|
# set main headers
|
151
154
|
request['content-md5'] = ''
|
@@ -179,13 +182,7 @@ module RightAws
|
|
179
182
|
@last_response = response
|
180
183
|
if response.is_a?(Net::HTTPSuccess)
|
181
184
|
@error_handler = nil
|
182
|
-
@@bench_xml.add!
|
183
|
-
if parser.kind_of?(RightAWSParser)
|
184
|
-
REXML::Document.parse_stream(response.body, parser)
|
185
|
-
else
|
186
|
-
parser.parse(response)
|
187
|
-
end
|
188
|
-
end
|
185
|
+
@@bench_xml.add! { parser.parse(response) }
|
189
186
|
return parser.result
|
190
187
|
else
|
191
188
|
@error_handler = AWSErrorHandler.new(self, parser, @@amazon_problems) unless @error_handler
|
@@ -206,22 +203,25 @@ module RightAws
|
|
206
203
|
#
|
207
204
|
# sqs.create_queue('my_awesome_queue') #=> 'http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue'
|
208
205
|
#
|
206
|
+
# PS Some queue based requests may not become available until a couple of minutes after queue creation
|
207
|
+
# (permission grant and removal for example)
|
208
|
+
#
|
209
209
|
def create_queue(queue_name, default_visibility_timeout=nil)
|
210
210
|
req_hash = generate_request('CreateQueue',
|
211
211
|
'QueueName' => queue_name,
|
212
212
|
'DefaultVisibilityTimeout' => default_visibility_timeout || DEFAULT_VISIBILITY_TIMEOUT )
|
213
|
-
request_info(req_hash, SqsCreateQueueParser.new)
|
213
|
+
request_info(req_hash, SqsCreateQueueParser.new(:logger => @logger))
|
214
214
|
end
|
215
215
|
|
216
|
-
#
|
216
|
+
# Lists all queues owned by this user that have names beginning with +queue_name_prefix+. If +queue_name_prefix+ is omitted then retrieves a list of all queues.
|
217
217
|
#
|
218
218
|
# sqs.create_queue('my_awesome_queue')
|
219
219
|
# sqs.create_queue('my_awesome_queue_2')
|
220
|
-
# sqs.list_queues('
|
220
|
+
# sqs.list_queues('my_awesome') #=> ['http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue','http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue_2']
|
221
221
|
#
|
222
222
|
def list_queues(queue_name_prefix=nil)
|
223
223
|
req_hash = generate_request('ListQueues', 'QueueNamePrefix' => queue_name_prefix)
|
224
|
-
request_info(req_hash, SqsListQueuesParser.new)
|
224
|
+
request_info(req_hash, SqsListQueuesParser.new(:logger => @logger))
|
225
225
|
rescue
|
226
226
|
on_exception
|
227
227
|
end
|
@@ -234,7 +234,7 @@ module RightAws
|
|
234
234
|
req_hash = generate_request('DeleteQueue',
|
235
235
|
'ForceDeletion' => force_deletion.to_s,
|
236
236
|
:queue_url => queue_url)
|
237
|
-
request_info(req_hash, SqsStatusParser.new)
|
237
|
+
request_info(req_hash, SqsStatusParser.new(:logger => @logger))
|
238
238
|
rescue
|
239
239
|
on_exception
|
240
240
|
end
|
@@ -247,7 +247,7 @@ module RightAws
|
|
247
247
|
req_hash = generate_request('GetQueueAttributes',
|
248
248
|
'Attribute' => attribute,
|
249
249
|
:queue_url => queue_url)
|
250
|
-
request_info(req_hash, SqsGetQueueAttributesParser.new)
|
250
|
+
request_info(req_hash, SqsGetQueueAttributesParser.new(:logger => @logger))
|
251
251
|
rescue
|
252
252
|
on_exception
|
253
253
|
end
|
@@ -256,13 +256,15 @@ module RightAws
|
|
256
256
|
#
|
257
257
|
# sqs.set_queue_attributes('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue', "VisibilityTimeout", 10) #=> true
|
258
258
|
#
|
259
|
-
# P.S.
|
259
|
+
# P.S. Amazon returns success even if the attribute does not exist. Also, attribute values may not be immediately available to other queries
|
260
|
+
# for some time after an update (see the SQS documentation for
|
261
|
+
# semantics).
|
260
262
|
def set_queue_attributes(queue_url, attribute, value)
|
261
263
|
req_hash = generate_request('SetQueueAttributes',
|
262
264
|
'Attribute' => attribute,
|
263
265
|
'Value' => value,
|
264
266
|
:queue_url => queue_url)
|
265
|
-
request_info(req_hash, SqsStatusParser.new)
|
267
|
+
request_info(req_hash, SqsStatusParser.new(:logger => @logger))
|
266
268
|
rescue
|
267
269
|
on_exception
|
268
270
|
end
|
@@ -277,7 +279,7 @@ module RightAws
|
|
277
279
|
req_hash = generate_request('SetVisibilityTimeout',
|
278
280
|
'VisibilityTimeout' => visibility_timeout || DEFAULT_VISIBILITY_TIMEOUT,
|
279
281
|
:queue_url => queue_url )
|
280
|
-
request_info(req_hash, SqsStatusParser.new)
|
282
|
+
request_info(req_hash, SqsStatusParser.new(:logger => @logger))
|
281
283
|
rescue
|
282
284
|
on_exception
|
283
285
|
end
|
@@ -290,7 +292,7 @@ module RightAws
|
|
290
292
|
#
|
291
293
|
def get_visibility_timeout(queue_url)
|
292
294
|
req_hash = generate_request('GetVisibilityTimeout', :queue_url => queue_url )
|
293
|
-
request_info(req_hash, SqsGetVisibilityTimeoutParser.new)
|
295
|
+
request_info(req_hash, SqsGetVisibilityTimeoutParser.new(:logger => @logger))
|
294
296
|
rescue
|
295
297
|
on_exception
|
296
298
|
end
|
@@ -304,7 +306,7 @@ module RightAws
|
|
304
306
|
'Grantee.EmailAddress' => grantee_email_address,
|
305
307
|
'Permission' => permission,
|
306
308
|
:queue_url => queue_url)
|
307
|
-
request_info(req_hash, SqsStatusParser.new)
|
309
|
+
request_info(req_hash, SqsStatusParser.new(:logger => @logger))
|
308
310
|
rescue
|
309
311
|
on_exception
|
310
312
|
end
|
@@ -320,7 +322,7 @@ module RightAws
|
|
320
322
|
'Grantee.EmailAddress' => grantee_email_address,
|
321
323
|
'Permission' => permission,
|
322
324
|
:queue_url => queue_url)
|
323
|
-
response = request_info(req_hash, SqsListGrantsParser.new)
|
325
|
+
response = request_info(req_hash, SqsListGrantsParser.new(:logger => @logger))
|
324
326
|
# One user may have up to 3 permission records for every queue.
|
325
327
|
# We will join these records to one.
|
326
328
|
result = {}
|
@@ -345,7 +347,7 @@ module RightAws
|
|
345
347
|
grantee_key => grantee_email_address_or_id,
|
346
348
|
'Permission' => permission,
|
347
349
|
:queue_url => queue_url)
|
348
|
-
request_info(req_hash, SqsStatusParser.new)
|
350
|
+
request_info(req_hash, SqsStatusParser.new(:logger => @logger))
|
349
351
|
rescue
|
350
352
|
on_exception
|
351
353
|
end
|
@@ -355,7 +357,7 @@ module RightAws
|
|
355
357
|
# sqs.receive_messages('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue',10, 5) #=>
|
356
358
|
# [{:id=>"12345678904GEZX9746N|0N9ED344VK5Z3SV1DTM0|1RVYH4X3TJ0987654321", :body=>"message_1"}, ..., {}]
|
357
359
|
#
|
358
|
-
# P.S. Usually returns
|
360
|
+
# P.S. Usually returns fewer messages than requested even if they are available.
|
359
361
|
#
|
360
362
|
def receive_messages(queue_url, number_of_messages=1, visibility_timeout=nil)
|
361
363
|
return [] if number_of_messages == 0
|
@@ -363,7 +365,7 @@ module RightAws
|
|
363
365
|
'NumberOfMessages' => number_of_messages,
|
364
366
|
'VisibilityTimeout' => visibility_timeout,
|
365
367
|
:queue_url => "#{queue_url}/front" )
|
366
|
-
request_info(req_hash, SqsReceiveMessagesParser.new)
|
368
|
+
request_info(req_hash, SqsReceiveMessagesParser.new(:logger => @logger))
|
367
369
|
rescue
|
368
370
|
on_exception
|
369
371
|
end
|
@@ -375,7 +377,7 @@ module RightAws
|
|
375
377
|
#
|
376
378
|
def peek_message(queue_url, message_id)
|
377
379
|
req_hash = generate_rest_request('GET', :queue_url => "#{queue_url}/#{CGI::escape message_id}" )
|
378
|
-
messages = request_info(req_hash, SqsReceiveMessagesParser.new)
|
380
|
+
messages = request_info(req_hash, SqsReceiveMessagesParser.new(:logger => @logger))
|
379
381
|
messages.blank? ? nil : messages[0]
|
380
382
|
rescue
|
381
383
|
on_exception
|
@@ -389,12 +391,13 @@ module RightAws
|
|
389
391
|
req_hash = generate_rest_request('PUT',
|
390
392
|
:message => message,
|
391
393
|
:queue_url => "#{queue_url}/back")
|
392
|
-
request_info(req_hash, SqsSendMessagesParser.new)
|
394
|
+
request_info(req_hash, SqsSendMessagesParser.new(:logger => @logger))
|
393
395
|
rescue
|
394
396
|
on_exception
|
395
397
|
end
|
396
398
|
|
397
|
-
# Deletes message from queue. Returns +true+ or an exception.
|
399
|
+
# Deletes message from queue. Returns +true+ or an exception. Amazon
|
400
|
+
# returns +true+ on deletion of non-existent messages.
|
398
401
|
#
|
399
402
|
# sqs.delete_message('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue', '12345678904...0987654321') #=> true
|
400
403
|
#
|
@@ -402,7 +405,7 @@ module RightAws
|
|
402
405
|
req_hash = generate_request('DeleteMessage',
|
403
406
|
'MessageId' => message_id,
|
404
407
|
:queue_url => queue_url)
|
405
|
-
request_info(req_hash, SqsStatusParser.new)
|
408
|
+
request_info(req_hash, SqsStatusParser.new(:logger => @logger))
|
406
409
|
rescue
|
407
410
|
on_exception
|
408
411
|
end
|
@@ -416,7 +419,7 @@ module RightAws
|
|
416
419
|
'MessageId' => message_id,
|
417
420
|
'VisibilityTimeout' => visibility_timeout.to_s,
|
418
421
|
:queue_url => queue_url)
|
419
|
-
request_info(req_hash, SqsStatusParser.new)
|
422
|
+
request_info(req_hash, SqsStatusParser.new(:logger => @logger))
|
420
423
|
rescue
|
421
424
|
on_exception
|
422
425
|
end
|
@@ -456,7 +459,7 @@ module RightAws
|
|
456
459
|
on_exception
|
457
460
|
end
|
458
461
|
|
459
|
-
# Returns approximate
|
462
|
+
# Returns approximate number of messages in queue.
|
460
463
|
#
|
461
464
|
# sqs.get_queue_length('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue') #=> 3
|
462
465
|
#
|
@@ -481,12 +484,15 @@ module RightAws
|
|
481
484
|
#
|
482
485
|
# sqs.force_clear_queue('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue') #=> true
|
483
486
|
#
|
487
|
+
# PS This function is no longer supported. Amazon has changed the SQS semantics to require at least 60 seconds between
|
488
|
+
# queue deletion and creation. Hence this method will fail with an exception.
|
489
|
+
#
|
484
490
|
def force_clear_queue(queue_url)
|
485
491
|
queue_name = queue_name_by_url(queue_url)
|
486
492
|
queue_attributes = get_queue_attributes(queue_url)
|
487
493
|
force_delete_queue(queue_url)
|
488
494
|
create_queue(queue_name)
|
489
|
-
# hmmm... The next
|
495
|
+
# hmmm... The next line is a trick. Amazon do not want change attributes immediately after queue creation
|
490
496
|
# So we do 'empty' get_queue_attributes. Probably they need some time to allow attributes change.
|
491
497
|
get_queue_attributes(queue_url)
|
492
498
|
queue_attributes.each{ |attribute, value| set_queue_attributes(queue_url, attribute, value) }
|