aws 1.11.9 → 1.11.36

Sign up to get free protection for your applications and to get access to all the features.
@@ -23,13 +23,25 @@
23
23
 
24
24
  module RightAws
25
25
 
26
+ #
27
+ # Right::Aws::SqsGen2Interface - RightScale's low-level Amazon SQS interface
28
+ # for API version 2008-01-01 and later.
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=31
32
+ #
33
+ # This class provides a procedural interface to SQS. Conceptually it is
34
+ # mostly a pass-through interface to SQS and its API is very similar to the
35
+ # bare SQS API. For a somewhat higher-level and object-oriented interface, see
36
+ # RightAws::SqsGen2.
37
+
26
38
  class SqsInterface < RightAwsBase
27
39
  include RightAwsBaseInterface
28
-
29
- API_VERSION = "2007-05-01"
40
+
41
+ API_VERSION = "2008-01-01"
30
42
  DEFAULT_HOST = "queue.amazonaws.com"
31
- DEFAULT_PORT = 443
32
- DEFAULT_PROTOCOL = 'https'
43
+ DEFAULT_PORT = 80
44
+ DEFAULT_PROTOCOL = 'http'
33
45
  REQUEST_TTL = 30
34
46
  DEFAULT_VISIBILITY_TIMEOUT = 30
35
47
 
@@ -43,29 +55,33 @@ module RightAws
43
55
  end
44
56
 
45
57
  @@api = API_VERSION
46
- def self.api
58
+ def self.api
47
59
  @@api
48
60
  end
49
61
 
50
- # Creates a new SqsInterface instance.
51
- #
52
- # sqs = RightAws::SqsInterface.new('1E3GDYEOGFJPIT75KDT40','hgTHt68JY07JKUY08ftHYtERkjgtfERn57DFE379', {:multi_thread => true, :logger => Logger.new('/tmp/x.log')})
53
- #
54
- # Params is a hash:
55
- #
56
- # {:server => 'queue.amazonaws.com' # Amazon service host: 'queue.amazonaws.com'(default)
57
- # :port => 443 # Amazon service port: 80 or 443(default)
58
- # :multi_thread => true|false # Multi-threaded (connection per each thread): true or false(default)
59
- # :signature_version => '0' # The signature version : '0' or '1'(default)
60
- # :logger => Logger Object} # Logger instance: logs to STDOUT if omitted }
61
- #
62
+ # Creates a new SqsInterface instance. This instance is limited to
63
+ # operations on SQS objects created with Amazon's 2008-01-01 API version. This
64
+ # interface will not work on objects created with prior API versions. See
65
+ # Amazon's article "Migrating to Amazon SQS API version 2008-01-01" at:
66
+ # http://developer.amazonwebservices.com/connect/entry.jspa?externalID=1148
67
+ #
68
+ # sqs = RightAws::SqsGen2Interface.new('1E3GDYEOGFJPIT75KDT40','hgTHt68JY07JKUY08ftHYtERkjgtfERn57DFE379', {:multi_thread => true, :logger => Logger.new('/tmp/x.log')})
69
+ #
70
+ # Params is a hash:
71
+ #
72
+ # {:server => 'queue.amazonaws.com' # Amazon service host: 'queue.amazonaws.com' (default)
73
+ # :port => 443 # Amazon service port: 80 or 443 (default)
74
+ # :multi_thread => true|false # Multi-threaded (connection per each thread): true or false (default)
75
+ # :signature_version => '0' # The signature version : '0' or '1'(default)
76
+ # :logger => Logger Object} # Logger instance: logs to STDOUT if omitted }
77
+ #
62
78
  def initialize(aws_access_key_id=nil, aws_secret_access_key=nil, params={})
63
- init({ :name => 'SQS',
64
- :default_host => ENV['SQS_URL'] ? URI.parse(ENV['SQS_URL']).host : DEFAULT_HOST,
65
- :default_port => ENV['SQS_URL'] ? URI.parse(ENV['SQS_URL']).port : DEFAULT_PORT,
66
- :default_protocol => ENV['SQS_URL'] ? URI.parse(ENV['SQS_URL']).scheme : DEFAULT_PROTOCOL },
67
- aws_access_key_id || ENV['AWS_ACCESS_KEY_ID'],
68
- aws_secret_access_key || ENV['AWS_SECRET_ACCESS_KEY'],
79
+ init({ :name => 'SQS',
80
+ :default_host => ENV['SQS_URL'] ? URI.parse(ENV['SQS_URL']).host : DEFAULT_HOST,
81
+ :default_port => ENV['SQS_URL'] ? URI.parse(ENV['SQS_URL']).port : DEFAULT_PORT,
82
+ :default_protocol => ENV['SQS_URL'] ? URI.parse(ENV['SQS_URL']).scheme : DEFAULT_PROTOCOL },
83
+ aws_access_key_id || ENV['AWS_ACCESS_KEY_ID'],
84
+ aws_secret_access_key || ENV['AWS_SECRET_ACCESS_KEY'],
69
85
  params)
70
86
  end
71
87
 
@@ -74,51 +90,47 @@ module RightAws
74
90
  # Requests
75
91
  #-----------------------------------------------------------------
76
92
 
77
- # Generates a request hash for the query API
78
- def generate_request(action, params={}) # :nodoc:
79
- # Sometimes we need to use queue uri (delete queue etc)
80
- # In that case we will use Symbol key: 'param[:queue_url]'
81
- service = params[:queue_url] ? URI(params[:queue_url]).path : '/'
82
- # remove unset(=optional) and symbolyc keys
83
- params.each{ |key, value| params.delete(key) if (value.nil? || key.is_a?(Symbol)) }
84
- # prepare output hash
93
+ # Generates a request hash for the query API
94
+ def generate_request(action, param={}) # :nodoc:
95
+ # For operation requests on a queue, the queue URI will be a parameter,
96
+ # so we first extract it from the call parameters. Next we remove any
97
+ # parameters with no value or with symbolic keys. We add the header
98
+ # fields required in all requests, and then the headers passed in as
99
+ # params. We sort the header fields alphabetically and then generate the
100
+ # signature before URL escaping the resulting query and sending it.
101
+ service = param[:queue_url] ? URI(param[:queue_url]).path : '/'
102
+ param.each{ |key, value| param.delete(key) if (value.nil? || key.is_a?(Symbol)) }
85
103
  service_hash = { "Action" => action,
86
104
  "Expires" => (Time.now + REQUEST_TTL).utc.strftime("%Y-%m-%dT%H:%M:%SZ"),
87
105
  "AWSAccessKeyId" => @aws_access_key_id,
88
106
  "Version" => API_VERSION }
89
- service_hash.update(params)
107
+ service_hash.update(param)
90
108
  service_params = signed_service_params(@aws_secret_access_key, service_hash, :get, @params[:server], service)
91
- request = Net::HTTP::Get.new("#{AwsUtils::URLencode(service)}?#{service_params}")
109
+ request = Net::HTTP::Get.new("#{AwsUtils.URLencode(service)}?#{service_params}")
92
110
  # prepare output hash
93
- { :request => request,
111
+ { :request => request,
94
112
  :server => @params[:server],
95
113
  :port => @params[:port],
96
114
  :protocol => @params[:protocol] }
97
115
  end
98
116
 
99
- # Generates a request hash for the REST API
100
- def generate_rest_request(method, param) # :nodoc:
101
- queue_uri = param[:queue_url] ? URI(param[:queue_url]).path : '/'
117
+ def generate_post_request(action, param={}) # :nodoc:
118
+ service = param[:queue_url] ? URI(param[:queue_url]).path : '/'
102
119
  message = param[:message] # extract message body if nesessary
103
- # remove unset(=optional) and symbolyc keys
104
120
  param.each{ |key, value| param.delete(key) if (value.nil? || key.is_a?(Symbol)) }
105
- # created request
106
- param_to_str = param.to_a.collect{|key,val| key.to_s + "=" + CGI::escape(val.to_s) }.join("&")
107
- param_to_str = "?#{param_to_str}" unless param_to_str.blank?
108
- request = "Net::HTTP::#{method.capitalize}".constantize.new("#{queue_uri}#{param_to_str}")
109
- request.body = message if message
110
- # set main headers
111
- request['content-md5'] = ''
112
- request['Content-Type'] = 'text/plain'
113
- request['Date'] = Time.now.httpdate
114
- # generate authorization string
115
- auth_string = "#{method.upcase}\n#{request['content-md5']}\n#{request['Content-Type']}\n#{request['Date']}\n#{CGI::unescape(queue_uri)}"
116
- signature = AwsUtils::sign(@aws_secret_access_key, auth_string)
117
- # set other headers
118
- request['Authorization'] = "AWS #{@aws_access_key_id}:#{signature}"
119
- request['AWS-Version'] = API_VERSION
121
+ service_hash = { "Action" => action,
122
+ "Expires" => (Time.now + REQUEST_TTL).utc.strftime("%Y-%m-%dT%H:%M:%SZ"),
123
+ "AWSAccessKeyId" => @aws_access_key_id,
124
+ "MessageBody" => message,
125
+ "Version" => API_VERSION }
126
+ service_hash.update(param)
127
+ #
128
+ service_params = signed_service_params(@aws_secret_access_key, service_hash, :post, @params[:server], service)
129
+ request = Net::HTTP::Post.new(AwsUtils::URLencode(service))
130
+ request['Content-Type'] = 'application/x-www-form-urlencoded'
131
+ request.body = service_params
120
132
  # prepare output hash
121
- { :request => request,
133
+ { :request => request,
122
134
  :server => @params[:server],
123
135
  :port => @params[:port],
124
136
  :protocol => @params[:protocol] }
@@ -134,21 +146,21 @@ module RightAws
134
146
  end
135
147
 
136
148
 
137
- # Creates new queue. Returns new queue link.
149
+ # Creates a new queue, returning its URI.
138
150
  #
139
151
  # sqs.create_queue('my_awesome_queue') #=> 'http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue'
140
152
  #
141
- # PS Some queue based requests may not become available until a couple of minutes after queue creation
142
- # (permission grant and removal for example)
143
- #
144
153
  def create_queue(queue_name, default_visibility_timeout=nil)
145
- req_hash = generate_request('CreateQueue',
146
- 'QueueName' => queue_name,
154
+ req_hash = generate_request('CreateQueue', 'QueueName' => queue_name,
147
155
  'DefaultVisibilityTimeout' => default_visibility_timeout || DEFAULT_VISIBILITY_TIMEOUT )
148
156
  request_info(req_hash, SqsCreateQueueParser.new(:logger => @logger))
157
+ rescue
158
+ on_exception
149
159
  end
150
160
 
151
- # 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.
161
+ # Lists all queues owned by this user that have names beginning with +queue_name_prefix+.
162
+ # If +queue_name_prefix+ is omitted then retrieves a list of all queues.
163
+ # Queue creation is an eventual operation and created queues may not show up in immediately subsequent list_queues calls.
152
164
  #
153
165
  # sqs.create_queue('my_awesome_queue')
154
166
  # sqs.create_queue('my_awesome_queue_2')
@@ -160,15 +172,18 @@ module RightAws
160
172
  rescue
161
173
  on_exception
162
174
  end
163
-
164
- # Deletes queue (queue must be empty or +force_deletion+ must be set to true). Queue is identified by url. Returns +true+ or an exception.
175
+
176
+ # Deletes queue. Any messages in the queue are permanently lost.
177
+ # Returns +true+ or an exception.
178
+ # Queue deletion can take up to 60 s to propagate through SQS. Thus, after a deletion, subsequent list_queues calls
179
+ # may still show the deleted queue. It is not unusual within the 60 s window to see the deleted queue absent from
180
+ # one list_queues call but present in the subsequent one. Deletion is eventual.
165
181
  #
166
182
  # sqs.delete_queue('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue_2') #=> true
167
183
  #
168
- def delete_queue(queue_url, force_deletion = false)
169
- req_hash = generate_request('DeleteQueue',
170
- 'ForceDeletion' => force_deletion.to_s,
171
- :queue_url => queue_url)
184
+ #
185
+ def delete_queue(queue_url)
186
+ req_hash = generate_request('DeleteQueue', :queue_url => queue_url)
172
187
  request_info(req_hash, SqsStatusParser.new(:logger => @logger))
173
188
  rescue
174
189
  on_exception
@@ -176,12 +191,11 @@ module RightAws
176
191
 
177
192
  # Retrieves the queue attribute(s). Returns a hash of attribute(s) or an exception.
178
193
  #
179
- # sqs.get_queue_attributes('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue') #=> {"ApproximateNumberOfMessages"=>"0", "VisibilityTimeout"=>"30"}
194
+ # sqs.get_queue_attributes('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue')
195
+ # #=> {"ApproximateNumberOfMessages"=>"0", "VisibilityTimeout"=>"30"}
180
196
  #
181
197
  def get_queue_attributes(queue_url, attribute='All')
182
- req_hash = generate_request('GetQueueAttributes',
183
- 'Attribute' => attribute,
184
- :queue_url => queue_url)
198
+ req_hash = generate_request('GetQueueAttributes', 'AttributeName' => attribute, :queue_url => queue_url)
185
199
  request_info(req_hash, SqsGetQueueAttributesParser.new(:logger => @logger))
186
200
  rescue
187
201
  on_exception
@@ -191,97 +205,17 @@ module RightAws
191
205
  #
192
206
  # sqs.set_queue_attributes('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue', "VisibilityTimeout", 10) #=> true
193
207
  #
194
- # P.S. Amazon returns success even if the attribute does not exist. Also, attribute values may not be immediately available to other queries
195
- # for some time after an update (see the SQS documentation for
196
- # semantics).
197
- def set_queue_attributes(queue_url, attribute, value)
198
- req_hash = generate_request('SetQueueAttributes',
199
- 'Attribute' => attribute,
200
- 'Value' => value,
201
- :queue_url => queue_url)
202
- request_info(req_hash, SqsStatusParser.new(:logger => @logger))
203
- rescue
204
- on_exception
205
- end
206
-
207
- # Sets visibility timeout. Returns +true+ or an exception.
208
- #
209
- # sqs.set_visibility_timeout('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue', 15) #=> true
210
- #
211
- # See also: +set_queue_attributes+
212
- #
213
- def set_visibility_timeout(queue_url, visibility_timeout=nil)
214
- req_hash = generate_request('SetVisibilityTimeout',
215
- 'VisibilityTimeout' => visibility_timeout || DEFAULT_VISIBILITY_TIMEOUT,
216
- :queue_url => queue_url )
217
- request_info(req_hash, SqsStatusParser.new(:logger => @logger))
218
- rescue
219
- on_exception
220
- end
221
-
222
- # Retrieves visibility timeout.
223
- #
224
- # sqs.get_visibility_timeout('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue') #=> 15
225
- #
226
- # See also: +get_queue_attributes+
227
- #
228
- def get_visibility_timeout(queue_url)
229
- req_hash = generate_request('GetVisibilityTimeout', :queue_url => queue_url )
230
- request_info(req_hash, SqsGetVisibilityTimeoutParser.new(:logger => @logger))
231
- rescue
232
- on_exception
233
- end
234
-
235
- # Adds grants for user (identified by email he registered at Amazon). Returns +true+ or an exception. Permission = 'FULLCONTROL' | 'RECEIVEMESSAGE' | 'SENDMESSAGE'.
236
- #
237
- # sqs.add_grant('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue', 'my_awesome_friend@gmail.com', 'FULLCONTROL') #=> true
238
- #
239
- def add_grant(queue_url, grantee_email_address, permission = nil)
240
- req_hash = generate_request('AddGrant',
241
- 'Grantee.EmailAddress' => grantee_email_address,
242
- 'Permission' => permission,
243
- :queue_url => queue_url)
244
- request_info(req_hash, SqsStatusParser.new(:logger => @logger))
245
- rescue
246
- on_exception
247
- end
248
-
249
- # Retrieves hash of +grantee_id+ => +perms+ for this queue:
250
- #
251
- # sqs.list_grants('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue') #=>
252
- # {"000000000000000000000001111111111117476c7fea6efb2c3347ac3ab2792a"=>{:name=>"root", :perms=>["FULLCONTROL"]},
253
- # "00000000000000000000000111111111111e5828344600fc9e4a784a09e97041"=>{:name=>"myawesomefriend", :perms=>["FULLCONTROL"]}
254
- #
255
- def list_grants(queue_url, grantee_email_address=nil, permission = nil)
256
- req_hash = generate_request('ListGrants',
257
- 'Grantee.EmailAddress' => grantee_email_address,
258
- 'Permission' => permission,
259
- :queue_url => queue_url)
260
- response = request_info(req_hash, SqsListGrantsParser.new(:logger => @logger))
261
- # One user may have up to 3 permission records for every queue.
262
- # We will join these records to one.
263
- result = {}
264
- response.each do |perm|
265
- id = perm[:id]
266
- # create hash for new user if unexisit
267
- result[id] = {:perms=>[]} unless result[id]
268
- # fill current grantee params
269
- result[id][:perms] << perm[:permission]
270
- result[id][:name] = perm[:name]
271
- end
272
- result
273
- end
274
-
275
- # Revokes permission from user. Returns +true+ or an exception.
208
+ # From the SQS Dev Guide:
209
+ # "Currently, you can set only the
210
+ # VisibilityTimeout attribute for a queue...
211
+ # When you change a queue's attributes, the change can take up to 60 seconds to propagate
212
+ # throughout the SQS system."
276
213
  #
277
- # sqs.remove_grant('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue', 'my_awesome_friend@gmail.com', 'FULLCONTROL') #=> true
278
- #
279
- def remove_grant(queue_url, grantee_email_address_or_id, permission = nil)
280
- grantee_key = grantee_email_address_or_id.include?('@') ? 'Grantee.EmailAddress' : 'Grantee.ID'
281
- req_hash = generate_request('RemoveGrant',
282
- grantee_key => grantee_email_address_or_id,
283
- 'Permission' => permission,
284
- :queue_url => queue_url)
214
+ # NB: Attribute values may not be immediately available to other queries
215
+ # for some time after an update. See the SQS documentation for
216
+ # semantics, but in general propagation can take up to 60 s.
217
+ def set_queue_attributes(queue_url, attribute, value)
218
+ req_hash = generate_request('SetQueueAttributes', 'Attribute.Name' => attribute, 'Attribute.Value' => value, :queue_url => queue_url)
285
219
  request_info(req_hash, SqsStatusParser.new(:logger => @logger))
286
220
  rescue
287
221
  on_exception
@@ -289,78 +223,64 @@ module RightAws
289
223
 
290
224
  # Retrieves a list of messages from queue. Returns an array of hashes in format: <tt>{:id=>'message_id', body=>'message_body'}</tt>
291
225
  #
292
- # sqs.receive_messages('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue',10, 5) #=>
293
- # [{:id=>"12345678904GEZX9746N|0N9ED344VK5Z3SV1DTM0|1RVYH4X3TJ0987654321", :body=>"message_1"}, ..., {}]
294
- #
295
- # P.S. Usually returns fewer messages than requested even if they are available.
296
- #
297
- def receive_messages(queue_url, number_of_messages=1, visibility_timeout=nil)
298
- return [] if number_of_messages == 0
299
- req_hash = generate_rest_request('GET',
300
- 'NumberOfMessages' => number_of_messages,
301
- 'VisibilityTimeout' => visibility_timeout,
302
- :queue_url => "#{queue_url}/front" )
303
- request_info(req_hash, SqsReceiveMessagesParser.new(:logger => @logger))
304
- rescue
305
- on_exception
306
- end
307
-
308
- # Peeks message from queue by message id. Returns message in format of <tt>{:id=>'message_id', :body=>'message_body'}</tt> or +nil+.
226
+ # sqs.receive_message('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue',10, 5) #=>
227
+ # [{"ReceiptHandle"=>"Euvo62...kw==", "MD5OfBody"=>"16af2171b5b83cfa35ce254966ba81e3",
228
+ # "Body"=>"Goodbyte World!", "MessageId"=>"MUM4WlAyR...pYOTA="}, ..., {}]
309
229
  #
310
- # sqs.peek_message('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue', '1234567890...0987654321') #=>
311
- # {:id=>"12345678904GEZX9746N|0N9ED344VK5Z3SV1DTM0|1RVYH4X3TJ0987654321", :body=>"message_1"}
230
+ # Normally this call returns fewer messages than the maximum specified,
231
+ # even if they are available.
312
232
  #
313
- def peek_message(queue_url, message_id)
314
- req_hash = generate_rest_request('GET', :queue_url => "#{queue_url}/#{CGI::escape message_id}" )
315
- messages = request_info(req_hash, SqsReceiveMessagesParser.new(:logger => @logger))
316
- messages.blank? ? nil : messages[0]
233
+ def receive_message(queue_url, max_number_of_messages=1, visibility_timeout=nil)
234
+ return [] if max_number_of_messages == 0
235
+ req_hash = generate_post_request('ReceiveMessage', 'MaxNumberOfMessages' => max_number_of_messages, 'VisibilityTimeout' => visibility_timeout,
236
+ :queue_url => queue_url )
237
+ request_info(req_hash, SqsReceiveMessageParser.new(:logger => @logger))
317
238
  rescue
318
239
  on_exception
319
240
  end
320
241
 
321
- # Sends new message to queue.Returns 'message_id' or raises an exception.
242
+ # Sends a new message to a queue. Message size is limited to 8 KB.
243
+ # If successful, this call returns a hash containing key/value pairs for
244
+ # "MessageId" and "MD5OfMessageBody":
322
245
  #
323
246
  # sqs.send_message('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue', 'message_1') #=> "1234567890...0987654321"
247
+ # => {"MessageId"=>"MEs4M0JKNlRCRTBBSENaMjROTk58QVFRNzNEREhDVFlFOVJDQ1JKNjF8UTdBRllCUlJUMjhKMUI1WDJSWDE=", "MD5OfMessageBody"=>"16af2171b5b83cfa35ce254966ba81e3"}
248
+ #
249
+ # On failure, send_message raises an exception.
250
+ #
324
251
  #
325
252
  def send_message(queue_url, message)
326
- req_hash = generate_rest_request('PUT',
327
- :message => message,
328
- :queue_url => "#{queue_url}/back")
253
+ req_hash = generate_post_request('SendMessage', :message => message, :queue_url => queue_url)
329
254
  request_info(req_hash, SqsSendMessagesParser.new(:logger => @logger))
330
255
  rescue
331
256
  on_exception
332
257
  end
333
-
258
+
259
+ # Same as send_message
260
+ alias_method :push_message, :send_message
261
+
262
+
334
263
  # Deletes message from queue. Returns +true+ or an exception. Amazon
335
- # returns +true+ on deletion of non-existent messages.
264
+ # returns +true+ on deletion of non-existent messages. You must use the
265
+ # receipt handle for a message to delete it, not the message ID.
336
266
  #
337
- # sqs.delete_message('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue', '12345678904...0987654321') #=> true
267
+ # From the SQS Developer Guide:
268
+ # "It is possible you will receive a message even after you have deleted it. This might happen
269
+ # on rare occasions if one of the servers storing a copy of the message is unavailable when
270
+ # you request to delete the message. The copy remains on the server and might be returned to
271
+ # you again on a subsequent receive request. You should create your system to be
272
+ # idempotent so that receiving a particular message more than once is not a problem. "
338
273
  #
339
- def delete_message(queue_url, message_id)
340
- req_hash = generate_request('DeleteMessage',
341
- 'MessageId' => message_id,
342
- :queue_url => queue_url)
343
- request_info(req_hash, SqsStatusParser.new(:logger => @logger))
344
- rescue
345
- on_exception
346
- end
347
-
348
- # Changes message visibility timeout. Returns +true+ or an exception.
274
+ # sqs.delete_message('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue', 'Euvo62/1nlIet...ao03hd9Sa0w==') #=> true
349
275
  #
350
- # sqs.change_message_visibility('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue', '1234567890...0987654321', 10) #=> true
351
- #
352
- def change_message_visibility(queue_url, message_id, visibility_timeout=0)
353
- req_hash = generate_request('ChangeMessageVisibility',
354
- 'MessageId' => message_id,
355
- 'VisibilityTimeout' => visibility_timeout.to_s,
356
- :queue_url => queue_url)
276
+ def delete_message(queue_url, receipt_handle)
277
+ req_hash = generate_request('DeleteMessage', 'ReceiptHandle' => receipt_handle, :queue_url => queue_url)
357
278
  request_info(req_hash, SqsStatusParser.new(:logger => @logger))
358
279
  rescue
359
280
  on_exception
360
281
  end
361
-
362
- # Returns queue url by queue short name or +nil+ if queue is not found
363
- #
282
+
283
+ # Given the queue's short name, this call returns the queue URL or +nil+ if queue is not found
364
284
  # sqs.queue_url_by_name('my_awesome_queue') #=> 'http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue'
365
285
  #
366
286
  def queue_url_by_name(queue_name)
@@ -383,7 +303,7 @@ module RightAws
383
303
  rescue
384
304
  on_exception
385
305
  end
386
-
306
+
387
307
  # Returns short queue name by url.
388
308
  #
389
309
  # sqs.queue_name_by_url('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue') #=> 'my_awesome_queue'
@@ -409,68 +329,22 @@ module RightAws
409
329
  # sqs.clear_queue('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue') #=> true
410
330
  #
411
331
  def clear_queue(queue_url)
412
- while (m = pop_message(queue_url)) ; end # delete all messages in queue
332
+ while (pop_messages(queue_url, 10).length > 0) ; end # delete all messages in queue
413
333
  true
414
334
  rescue
415
335
  on_exception
416
336
  end
417
337
 
418
- # Deletes queue then re-creates it (restores attributes also). The fastest method to clear big queue or queue with invisible messages. Return +true+ or an exception.
419
- #
420
- # sqs.force_clear_queue('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue') #=> true
421
- #
422
- # PS This function is no longer supported. Amazon has changed the SQS semantics to require at least 60 seconds between
423
- # queue deletion and creation. Hence this method will fail with an exception.
424
- #
425
- def force_clear_queue(queue_url)
426
- queue_name = queue_name_by_url(queue_url)
427
- queue_attributes = get_queue_attributes(queue_url)
428
- force_delete_queue(queue_url)
429
- create_queue(queue_name)
430
- # hmmm... The next line is a trick. Amazon do not want change attributes immediately after queue creation
431
- # So we do 'empty' get_queue_attributes. Probably they need some time to allow attributes change.
432
- get_queue_attributes(queue_url)
433
- queue_attributes.each{ |attribute, value| set_queue_attributes(queue_url, attribute, value) }
434
- true
435
- rescue
436
- on_exception
437
- end
438
-
439
- # Deletes queue even if it has messages. Return +true+ or an exception.
440
- #
441
- # force_delete_queue('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue') #=> true
442
- #
443
- # P.S. same as <tt>delete_queue('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue', true)</tt>
444
- def force_delete_queue(queue_url)
445
- delete_queue(queue_url, true)
446
- rescue
447
- on_exception
448
- end
449
-
450
- # Reads first accessible message from queue. Returns message as a hash: <tt>{:id=>'message_id', :body=>'message_body'}</tt> or +nil+.
451
- #
452
- # sqs.receive_message('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue', 10) #=>
453
- # {:id=>"12345678904GEZX9746N|0N9ED344VK5Z3SV1DTM0|1RVYH4X3TJ0987654321", :body=>"message_1"}
454
- #
455
- def receive_message(queue_url, visibility_timeout=nil)
456
- result = receive_messages(queue_url, 1, visibility_timeout)
457
- result.blank? ? nil : result[0]
458
- rescue
459
- on_exception
460
- end
461
-
462
- # Same as send_message
463
- alias_method :push_message, :send_message
464
-
465
338
  # Pops (retrieves and deletes) up to 'number_of_messages' from queue. Returns an array of retrieved messages in format: <tt>[{:id=>'message_id', :body=>'message_body'}]</tt>.
466
339
  #
467
340
  # sqs.pop_messages('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue', 3) #=>
468
- # [{:id=>"12345678904GEZX9746N|0N9ED344VK5Z3SV1DTM0|1RVYH4X3TJ0987654321", :body=>"message_1"}, ..., {}]
341
+ # [{"ReceiptHandle"=>"Euvo62/...+Zw==", "MD5OfBody"=>"16af2...81e3", "Body"=>"Goodbyte World!",
342
+ # "MessageId"=>"MEZI...JSWDE="}, {...}, ... , {...} ]
469
343
  #
470
344
  def pop_messages(queue_url, number_of_messages=1)
471
- messages = receive_messages(queue_url, number_of_messages)
345
+ messages = receive_message(queue_url, number_of_messages)
472
346
  messages.each do |message|
473
- delete_message(queue_url, message[:id])
347
+ delete_message(queue_url, message['ReceiptHandle'])
474
348
  end
475
349
  messages
476
350
  rescue
@@ -495,8 +369,8 @@ module RightAws
495
369
 
496
370
  class SqsStatusParser < RightAWSParser # :nodoc:
497
371
  def tagend(name)
498
- if name == 'StatusCode'
499
- @result = @text=='Success' ? true : false
372
+ if name == 'ResponseMetadata'
373
+ @result = true
500
374
  end
501
375
  end
502
376
  end
@@ -525,72 +399,46 @@ module RightAws
525
399
  @result = {}
526
400
  end
527
401
  def tagend(name)
528
- case name
529
- when 'Attribute' ; @current_attribute = @text
402
+ case name
403
+ when 'Name' ; @current_attribute = @text
530
404
  when 'Value' ; @result[@current_attribute] = @text
531
- # when 'StatusCode'; @result['status_code'] = @text
532
- # when 'RequestId' ; @result['request_id'] = @text
533
405
  end
534
406
  end
535
407
  end
536
408
 
537
409
  #-----------------------------------------------------------------
538
- # PARSERS: Timeouts
539
- #-----------------------------------------------------------------
540
-
541
- class SqsGetVisibilityTimeoutParser < RightAWSParser # :nodoc:
542
- def tagend(name)
543
- @result = @text.to_i if name == 'VisibilityTimeout'
544
- end
545
- end
546
-
547
- #-----------------------------------------------------------------
548
- # PARSERS: Permissions
410
+ # PARSERS: Messages
549
411
  #-----------------------------------------------------------------
550
412
 
551
- class SqsListGrantsParser < RightAWSParser # :nodoc:
413
+ class SqsReceiveMessageParser < RightAWSParser # :nodoc:
552
414
  def reset
553
415
  @result = []
554
416
  end
555
417
  def tagstart(name, attributes)
556
- @current_perms = {} if name == 'GrantList'
418
+ @current_message = {} if name == 'Message'
557
419
  end
558
420
  def tagend(name)
559
421
  case name
560
- when 'ID' ; @current_perms[:id] = @text
561
- when 'DisplayName'; @current_perms[:name] = @text
562
- when 'Permission' ; @current_perms[:permission] = @text
563
- when 'GrantList' ; @result << @current_perms
422
+ when 'MessageId' ; @current_message['MessageId'] = @text
423
+ when 'ReceiptHandle' ; @current_message['ReceiptHandle'] = @text
424
+ when 'MD5OfBody' ; @current_message['MD5OfBody'] = @text
425
+ when 'Body'; @current_message['Body'] = @text; @result << @current_message
564
426
  end
565
427
  end
566
428
  end
567
429
 
568
- #-----------------------------------------------------------------
569
- # PARSERS: Messages
570
- #-----------------------------------------------------------------
571
-
572
- class SqsReceiveMessagesParser < RightAWSParser # :nodoc:
430
+ class SqsSendMessagesParser < RightAWSParser # :nodoc:
573
431
  def reset
574
- @result = []
575
- end
576
- def tagstart(name, attributes)
577
- @current_message = {} if name == 'Message'
432
+ @result = {}
578
433
  end
579
434
  def tagend(name)
580
435
  case name
581
- when 'MessageId' ; @current_message[:id] = @text
582
- when 'MessageBody'; @current_message[:body] = @text
583
- when 'Message' ; @result << @current_message
436
+ when 'MessageId' ; @result['MessageId'] = @text
437
+ when 'MD5OfMessageBody' ; @result['MD5OfMessageBody'] = @text
584
438
  end
585
439
  end
586
440
  end
587
441
 
588
- class SqsSendMessagesParser < RightAWSParser # :nodoc:
589
- def tagend(name)
590
- @result = @text if name == 'MessageId'
591
- end
592
- end
593
-
594
442
  end
595
443
 
596
444
  end