aws 1.11.9 → 1.11.36

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.
@@ -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