revans_right_aws 2.0.1

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.
Files changed (52) hide show
  1. data/.gemtest +0 -0
  2. data/History.txt +284 -0
  3. data/Manifest.txt +50 -0
  4. data/README.txt +167 -0
  5. data/Rakefile +110 -0
  6. data/lib/acf/right_acf_interface.rb +485 -0
  7. data/lib/acf/right_acf_origin_access_identities.rb +230 -0
  8. data/lib/acf/right_acf_streaming_interface.rb +236 -0
  9. data/lib/acw/right_acw_interface.rb +249 -0
  10. data/lib/as/right_as_interface.rb +699 -0
  11. data/lib/awsbase/benchmark_fix.rb +39 -0
  12. data/lib/awsbase/right_awsbase.rb +978 -0
  13. data/lib/awsbase/support.rb +115 -0
  14. data/lib/ec2/right_ec2.rb +395 -0
  15. data/lib/ec2/right_ec2_ebs.rb +452 -0
  16. data/lib/ec2/right_ec2_images.rb +373 -0
  17. data/lib/ec2/right_ec2_instances.rb +755 -0
  18. data/lib/ec2/right_ec2_monitoring.rb +70 -0
  19. data/lib/ec2/right_ec2_reserved_instances.rb +170 -0
  20. data/lib/ec2/right_ec2_security_groups.rb +277 -0
  21. data/lib/ec2/right_ec2_spot_instances.rb +399 -0
  22. data/lib/ec2/right_ec2_vpc.rb +571 -0
  23. data/lib/elb/right_elb_interface.rb +496 -0
  24. data/lib/rds/right_rds_interface.rb +998 -0
  25. data/lib/right_aws.rb +83 -0
  26. data/lib/s3/right_s3.rb +1126 -0
  27. data/lib/s3/right_s3_interface.rb +1199 -0
  28. data/lib/sdb/active_sdb.rb +1122 -0
  29. data/lib/sdb/right_sdb_interface.rb +721 -0
  30. data/lib/sqs/right_sqs.rb +388 -0
  31. data/lib/sqs/right_sqs_gen2.rb +343 -0
  32. data/lib/sqs/right_sqs_gen2_interface.rb +524 -0
  33. data/lib/sqs/right_sqs_interface.rb +594 -0
  34. data/test/acf/test_helper.rb +2 -0
  35. data/test/acf/test_right_acf.rb +138 -0
  36. data/test/ec2/test_helper.rb +2 -0
  37. data/test/ec2/test_right_ec2.rb +108 -0
  38. data/test/http_connection.rb +87 -0
  39. data/test/rds/test_helper.rb +2 -0
  40. data/test/rds/test_right_rds.rb +120 -0
  41. data/test/s3/test_helper.rb +2 -0
  42. data/test/s3/test_right_s3.rb +421 -0
  43. data/test/s3/test_right_s3_stubbed.rb +97 -0
  44. data/test/sdb/test_active_sdb.rb +357 -0
  45. data/test/sdb/test_helper.rb +3 -0
  46. data/test/sdb/test_right_sdb.rb +253 -0
  47. data/test/sqs/test_helper.rb +2 -0
  48. data/test/sqs/test_right_sqs.rb +291 -0
  49. data/test/sqs/test_right_sqs_gen2.rb +264 -0
  50. data/test/test_credentials.rb +37 -0
  51. data/test/ts_right_aws.rb +14 -0
  52. metadata +169 -0
@@ -0,0 +1,594 @@
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
+ module RightAws
25
+
26
+ class SqsInterface < RightAwsBase
27
+ include RightAwsBaseInterface
28
+
29
+ API_VERSION = "2007-05-01"
30
+ DEFAULT_HOST = "queue.amazonaws.com"
31
+ DEFAULT_PORT = 443
32
+ DEFAULT_PROTOCOL = 'https'
33
+ REQUEST_TTL = 30
34
+ DEFAULT_VISIBILITY_TIMEOUT = 30
35
+
36
+
37
+ @@bench = AwsBenchmarkingBlock.new
38
+ def self.bench_xml
39
+ @@bench.xml
40
+ end
41
+ def self.bench_sqs
42
+ @@bench.service
43
+ end
44
+
45
+ @@api = API_VERSION
46
+ def self.api
47
+ @@api
48
+ end
49
+
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', '1' or '2'(default)
60
+ # :logger => Logger Object} # Logger instance: logs to STDOUT if omitted }
61
+ #
62
+ 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'],
69
+ params)
70
+ end
71
+
72
+
73
+ #-----------------------------------------------------------------
74
+ # Requests
75
+ #-----------------------------------------------------------------
76
+
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
85
+ service_hash = { "Action" => action,
86
+ "Expires" => (Time.now + REQUEST_TTL).utc.strftime("%Y-%m-%dT%H:%M:%SZ"),
87
+ "AWSAccessKeyId" => @aws_access_key_id,
88
+ "Version" => API_VERSION }
89
+ service_hash.update(params)
90
+ 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}")
92
+ # prepare output hash
93
+ { :request => request,
94
+ :server => @params[:server],
95
+ :port => @params[:port],
96
+ :protocol => @params[:protocol] }
97
+ end
98
+
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 : '/'
102
+ message = param[:message] # extract message body if nesessary
103
+ # remove unset(=optional) and symbolyc keys
104
+ 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
120
+ # prepare output hash
121
+ { :request => request,
122
+ :server => @params[:server],
123
+ :port => @params[:port],
124
+ :protocol => @params[:protocol] }
125
+ end
126
+
127
+
128
+ # Sends request to Amazon and parses the response
129
+ # Raises AwsError if any banana happened
130
+ def request_info(request, parser) # :nodoc:
131
+ request_info_impl(:sqs_connection, @@bench, request, parser)
132
+ end
133
+
134
+
135
+ # Creates new queue. Returns new queue link.
136
+ #
137
+ # sqs.create_queue('my_awesome_queue') #=> 'http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue'
138
+ #
139
+ # PS Some queue based requests may not become available until a couple of minutes after queue creation
140
+ # (permission grant and removal for example)
141
+ #
142
+ def create_queue(queue_name, default_visibility_timeout=nil)
143
+ req_hash = generate_request('CreateQueue',
144
+ 'QueueName' => queue_name,
145
+ 'DefaultVisibilityTimeout' => default_visibility_timeout || DEFAULT_VISIBILITY_TIMEOUT )
146
+ request_info(req_hash, SqsCreateQueueParser.new(:logger => @logger))
147
+ end
148
+
149
+ # 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.
150
+ #
151
+ # sqs.create_queue('my_awesome_queue')
152
+ # sqs.create_queue('my_awesome_queue_2')
153
+ # sqs.list_queues('my_awesome') #=> ['http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue','http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue_2']
154
+ #
155
+ def list_queues(queue_name_prefix=nil)
156
+ req_hash = generate_request('ListQueues', 'QueueNamePrefix' => queue_name_prefix)
157
+ request_info(req_hash, SqsListQueuesParser.new(:logger => @logger))
158
+ rescue
159
+ on_exception
160
+ end
161
+
162
+ # Deletes queue (queue must be empty or +force_deletion+ must be set to true). Queue is identified by url. Returns +true+ or an exception.
163
+ #
164
+ # sqs.delete_queue('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue_2') #=> true
165
+ #
166
+ def delete_queue(queue_url, force_deletion = false)
167
+ req_hash = generate_request('DeleteQueue',
168
+ 'ForceDeletion' => force_deletion.to_s,
169
+ :queue_url => queue_url)
170
+ request_info(req_hash, SqsStatusParser.new(:logger => @logger))
171
+ rescue
172
+ on_exception
173
+ end
174
+
175
+ # Retrieves the queue attribute(s). Returns a hash of attribute(s) or an exception.
176
+ #
177
+ # sqs.get_queue_attributes('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue') #=> {"ApproximateNumberOfMessages"=>"0", "VisibilityTimeout"=>"30"}
178
+ #
179
+ def get_queue_attributes(queue_url, attribute='All')
180
+ req_hash = generate_request('GetQueueAttributes',
181
+ 'Attribute' => attribute,
182
+ :queue_url => queue_url)
183
+ request_info(req_hash, SqsGetQueueAttributesParser.new(:logger => @logger))
184
+ rescue
185
+ on_exception
186
+ end
187
+
188
+ # Sets queue attribute. Returns +true+ or an exception.
189
+ #
190
+ # sqs.set_queue_attributes('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue', "VisibilityTimeout", 10) #=> true
191
+ #
192
+ # P.S. Amazon returns success even if the attribute does not exist. Also, attribute values may not be immediately available to other queries
193
+ # for some time after an update (see the SQS documentation for
194
+ # semantics).
195
+ def set_queue_attributes(queue_url, attribute, value)
196
+ req_hash = generate_request('SetQueueAttributes',
197
+ 'Attribute' => attribute,
198
+ 'Value' => value,
199
+ :queue_url => queue_url)
200
+ request_info(req_hash, SqsStatusParser.new(:logger => @logger))
201
+ rescue
202
+ on_exception
203
+ end
204
+
205
+ # Sets visibility timeout. Returns +true+ or an exception.
206
+ #
207
+ # sqs.set_visibility_timeout('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue', 15) #=> true
208
+ #
209
+ # See also: +set_queue_attributes+
210
+ #
211
+ def set_visibility_timeout(queue_url, visibility_timeout=nil)
212
+ req_hash = generate_request('SetVisibilityTimeout',
213
+ 'VisibilityTimeout' => visibility_timeout || DEFAULT_VISIBILITY_TIMEOUT,
214
+ :queue_url => queue_url )
215
+ request_info(req_hash, SqsStatusParser.new(:logger => @logger))
216
+ rescue
217
+ on_exception
218
+ end
219
+
220
+ # Retrieves visibility timeout.
221
+ #
222
+ # sqs.get_visibility_timeout('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue') #=> 15
223
+ #
224
+ # See also: +get_queue_attributes+
225
+ #
226
+ def get_visibility_timeout(queue_url)
227
+ req_hash = generate_request('GetVisibilityTimeout', :queue_url => queue_url )
228
+ request_info(req_hash, SqsGetVisibilityTimeoutParser.new(:logger => @logger))
229
+ rescue
230
+ on_exception
231
+ end
232
+
233
+ # Adds grants for user (identified by email he registered at Amazon). Returns +true+ or an exception. Permission = 'FULLCONTROL' | 'RECEIVEMESSAGE' | 'SENDMESSAGE'.
234
+ #
235
+ # sqs.add_grant('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue', 'my_awesome_friend@gmail.com', 'FULLCONTROL') #=> true
236
+ #
237
+ def add_grant(queue_url, grantee_email_address, permission = nil)
238
+ req_hash = generate_request('AddGrant',
239
+ 'Grantee.EmailAddress' => grantee_email_address,
240
+ 'Permission' => permission,
241
+ :queue_url => queue_url)
242
+ request_info(req_hash, SqsStatusParser.new(:logger => @logger))
243
+ rescue
244
+ on_exception
245
+ end
246
+
247
+ # Retrieves hash of +grantee_id+ => +perms+ for this queue:
248
+ #
249
+ # sqs.list_grants('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue') #=>
250
+ # {"000000000000000000000001111111111117476c7fea6efb2c3347ac3ab2792a"=>{:name=>"root", :perms=>["FULLCONTROL"]},
251
+ # "00000000000000000000000111111111111e5828344600fc9e4a784a09e97041"=>{:name=>"myawesomefriend", :perms=>["FULLCONTROL"]}
252
+ #
253
+ def list_grants(queue_url, grantee_email_address=nil, permission = nil)
254
+ req_hash = generate_request('ListGrants',
255
+ 'Grantee.EmailAddress' => grantee_email_address,
256
+ 'Permission' => permission,
257
+ :queue_url => queue_url)
258
+ response = request_info(req_hash, SqsListGrantsParser.new(:logger => @logger))
259
+ # One user may have up to 3 permission records for every queue.
260
+ # We will join these records to one.
261
+ result = {}
262
+ response.each do |perm|
263
+ id = perm[:id]
264
+ # create hash for new user if unexisit
265
+ result[id] = {:perms=>[]} unless result[id]
266
+ # fill current grantee params
267
+ result[id][:perms] << perm[:permission]
268
+ result[id][:name] = perm[:name]
269
+ end
270
+ result
271
+ end
272
+
273
+ # Revokes permission from user. Returns +true+ or an exception.
274
+ #
275
+ # sqs.remove_grant('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue', 'my_awesome_friend@gmail.com', 'FULLCONTROL') #=> true
276
+ #
277
+ def remove_grant(queue_url, grantee_email_address_or_id, permission = nil)
278
+ grantee_key = grantee_email_address_or_id.include?('@') ? 'Grantee.EmailAddress' : 'Grantee.ID'
279
+ req_hash = generate_request('RemoveGrant',
280
+ grantee_key => grantee_email_address_or_id,
281
+ 'Permission' => permission,
282
+ :queue_url => queue_url)
283
+ request_info(req_hash, SqsStatusParser.new(:logger => @logger))
284
+ rescue
285
+ on_exception
286
+ end
287
+
288
+ # Retrieves a list of messages from queue. Returns an array of hashes in format: <tt>{:id=>'message_id', body=>'message_body'}</tt>
289
+ #
290
+ # sqs.receive_messages('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue',10, 5) #=>
291
+ # [{:id=>"12345678904GEZX9746N|0N9ED344VK5Z3SV1DTM0|1RVYH4X3TJ0987654321", :body=>"message_1"}, ..., {}]
292
+ #
293
+ # P.S. Usually returns fewer messages than requested even if they are available.
294
+ #
295
+ def receive_messages(queue_url, number_of_messages=1, visibility_timeout=nil)
296
+ return [] if number_of_messages == 0
297
+ req_hash = generate_rest_request('GET',
298
+ 'NumberOfMessages' => number_of_messages,
299
+ 'VisibilityTimeout' => visibility_timeout,
300
+ :queue_url => "#{queue_url}/front" )
301
+ request_info(req_hash, SqsReceiveMessagesParser.new(:logger => @logger))
302
+ rescue
303
+ on_exception
304
+ end
305
+
306
+ # Peeks message from queue by message id. Returns message in format of <tt>{:id=>'message_id', :body=>'message_body'}</tt> or +nil+.
307
+ #
308
+ # sqs.peek_message('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue', '1234567890...0987654321') #=>
309
+ # {:id=>"12345678904GEZX9746N|0N9ED344VK5Z3SV1DTM0|1RVYH4X3TJ0987654321", :body=>"message_1"}
310
+ #
311
+ def peek_message(queue_url, message_id)
312
+ req_hash = generate_rest_request('GET', :queue_url => "#{queue_url}/#{CGI::escape message_id}" )
313
+ messages = request_info(req_hash, SqsReceiveMessagesParser.new(:logger => @logger))
314
+ messages.blank? ? nil : messages[0]
315
+ rescue
316
+ on_exception
317
+ end
318
+
319
+ # Sends new message to queue.Returns 'message_id' or raises an exception.
320
+ #
321
+ # sqs.send_message('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue', 'message_1') #=> "1234567890...0987654321"
322
+ #
323
+ def send_message(queue_url, message)
324
+ req_hash = generate_rest_request('PUT',
325
+ :message => message,
326
+ :queue_url => "#{queue_url}/back")
327
+ request_info(req_hash, SqsSendMessagesParser.new(:logger => @logger))
328
+ rescue
329
+ on_exception
330
+ end
331
+
332
+ # Deletes message from queue. Returns +true+ or an exception. Amazon
333
+ # returns +true+ on deletion of non-existent messages.
334
+ #
335
+ # sqs.delete_message('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue', '12345678904...0987654321') #=> true
336
+ #
337
+ def delete_message(queue_url, message_id)
338
+ req_hash = generate_request('DeleteMessage',
339
+ 'MessageId' => message_id,
340
+ :queue_url => queue_url)
341
+ request_info(req_hash, SqsStatusParser.new(:logger => @logger))
342
+ rescue
343
+ on_exception
344
+ end
345
+
346
+ # Changes message visibility timeout. Returns +true+ or an exception.
347
+ #
348
+ # sqs.change_message_visibility('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue', '1234567890...0987654321', 10) #=> true
349
+ #
350
+ def change_message_visibility(queue_url, message_id, visibility_timeout=0)
351
+ req_hash = generate_request('ChangeMessageVisibility',
352
+ 'MessageId' => message_id,
353
+ 'VisibilityTimeout' => visibility_timeout.to_s,
354
+ :queue_url => queue_url)
355
+ request_info(req_hash, SqsStatusParser.new(:logger => @logger))
356
+ rescue
357
+ on_exception
358
+ end
359
+
360
+ # Returns queue url by queue short name or +nil+ if queue is not found
361
+ #
362
+ # sqs.queue_url_by_name('my_awesome_queue') #=> 'http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue'
363
+ #
364
+ def queue_url_by_name(queue_name)
365
+ return queue_name if queue_name.include?('/')
366
+ queue_urls = list_queues(queue_name)
367
+ queue_urls.each do |queue_url|
368
+ return queue_url if queue_name_by_url(queue_url) == queue_name
369
+ end
370
+ nil
371
+ rescue
372
+ on_exception
373
+ end
374
+
375
+ # Returns short queue name by url.
376
+ #
377
+ # RightSqs.queue_name_by_url('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue') #=> 'my_awesome_queue'
378
+ #
379
+ def self.queue_name_by_url(queue_url)
380
+ queue_url[/[^\/]*$/]
381
+ rescue
382
+ on_exception
383
+ end
384
+
385
+ # Returns short queue name by url.
386
+ #
387
+ # sqs.queue_name_by_url('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue') #=> 'my_awesome_queue'
388
+ #
389
+ def queue_name_by_url(queue_url)
390
+ self.class.queue_name_by_url(queue_url)
391
+ rescue
392
+ on_exception
393
+ end
394
+
395
+ # Returns approximate number of messages in queue.
396
+ #
397
+ # sqs.get_queue_length('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue') #=> 3
398
+ #
399
+ def get_queue_length(queue_url)
400
+ get_queue_attributes(queue_url)['ApproximateNumberOfMessages'].to_i
401
+ rescue
402
+ on_exception
403
+ end
404
+
405
+ # Removes all visible messages from queue. Return +true+ or an exception.
406
+ #
407
+ # sqs.clear_queue('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue') #=> true
408
+ #
409
+ def clear_queue(queue_url)
410
+ while (m = pop_message(queue_url)) ; end # delete all messages in queue
411
+ true
412
+ rescue
413
+ on_exception
414
+ end
415
+
416
+ # 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.
417
+ #
418
+ # sqs.force_clear_queue('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue') #=> true
419
+ #
420
+ # PS This function is no longer supported. Amazon has changed the SQS semantics to require at least 60 seconds between
421
+ # queue deletion and creation. Hence this method will fail with an exception.
422
+ #
423
+ def force_clear_queue(queue_url)
424
+ queue_name = queue_name_by_url(queue_url)
425
+ queue_attributes = get_queue_attributes(queue_url)
426
+ force_delete_queue(queue_url)
427
+ create_queue(queue_name)
428
+ # hmmm... The next line is a trick. Amazon do not want change attributes immediately after queue creation
429
+ # So we do 'empty' get_queue_attributes. Probably they need some time to allow attributes change.
430
+ get_queue_attributes(queue_url)
431
+ queue_attributes.each{ |attribute, value| set_queue_attributes(queue_url, attribute, value) }
432
+ true
433
+ rescue
434
+ on_exception
435
+ end
436
+
437
+ # Deletes queue even if it has messages. Return +true+ or an exception.
438
+ #
439
+ # force_delete_queue('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue') #=> true
440
+ #
441
+ # P.S. same as <tt>delete_queue('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue', true)</tt>
442
+ def force_delete_queue(queue_url)
443
+ delete_queue(queue_url, true)
444
+ rescue
445
+ on_exception
446
+ end
447
+
448
+ # Reads first accessible message from queue. Returns message as a hash: <tt>{:id=>'message_id', :body=>'message_body'}</tt> or +nil+.
449
+ #
450
+ # sqs.receive_message('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue', 10) #=>
451
+ # {:id=>"12345678904GEZX9746N|0N9ED344VK5Z3SV1DTM0|1RVYH4X3TJ0987654321", :body=>"message_1"}
452
+ #
453
+ def receive_message(queue_url, visibility_timeout=nil)
454
+ result = receive_messages(queue_url, 1, visibility_timeout)
455
+ result.blank? ? nil : result[0]
456
+ rescue
457
+ on_exception
458
+ end
459
+
460
+ # Same as send_message
461
+ alias_method :push_message, :send_message
462
+
463
+ # 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>.
464
+ #
465
+ # sqs.pop_messages('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue', 3) #=>
466
+ # [{:id=>"12345678904GEZX9746N|0N9ED344VK5Z3SV1DTM0|1RVYH4X3TJ0987654321", :body=>"message_1"}, ..., {}]
467
+ #
468
+ def pop_messages(queue_url, number_of_messages=1)
469
+ messages = receive_messages(queue_url, number_of_messages)
470
+ messages.each do |message|
471
+ delete_message(queue_url, message[:id])
472
+ end
473
+ messages
474
+ rescue
475
+ on_exception
476
+ end
477
+
478
+ # Pops (retrieves and deletes) first accessible message from queue. Returns the message in format <tt>{:id=>'message_id', :body=>'message_body'}</tt> or +nil+.
479
+ #
480
+ # sqs.pop_message('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue') #=>
481
+ # {:id=>"12345678904GEZX9746N|0N9ED344VK5Z3SV1DTM0|1RVYH4X3TJ0987654321", :body=>"message_1"}
482
+ #
483
+ def pop_message(queue_url)
484
+ messages = pop_messages(queue_url)
485
+ messages.blank? ? nil : messages[0]
486
+ rescue
487
+ on_exception
488
+ end
489
+
490
+ #-----------------------------------------------------------------
491
+ # PARSERS: Status Response Parser
492
+ #-----------------------------------------------------------------
493
+
494
+ class SqsStatusParser < RightAWSParser # :nodoc:
495
+ def tagend(name)
496
+ if name == 'StatusCode'
497
+ @result = @text=='Success' ? true : false
498
+ end
499
+ end
500
+ end
501
+
502
+ #-----------------------------------------------------------------
503
+ # PARSERS: Queue
504
+ #-----------------------------------------------------------------
505
+
506
+ class SqsCreateQueueParser < RightAWSParser # :nodoc:
507
+ def tagend(name)
508
+ @result = @text if name == 'QueueUrl'
509
+ end
510
+ end
511
+
512
+ class SqsListQueuesParser < RightAWSParser # :nodoc:
513
+ def reset
514
+ @result = []
515
+ end
516
+ def tagend(name)
517
+ @result << @text if name == 'QueueUrl'
518
+ end
519
+ end
520
+
521
+ class SqsGetQueueAttributesParser < RightAWSParser # :nodoc:
522
+ def reset
523
+ @result = {}
524
+ end
525
+ def tagend(name)
526
+ case name
527
+ when 'Attribute' ; @current_attribute = @text
528
+ when 'Value' ; @result[@current_attribute] = @text
529
+ # when 'StatusCode'; @result['status_code'] = @text
530
+ # when 'RequestId' ; @result['request_id'] = @text
531
+ end
532
+ end
533
+ end
534
+
535
+ #-----------------------------------------------------------------
536
+ # PARSERS: Timeouts
537
+ #-----------------------------------------------------------------
538
+
539
+ class SqsGetVisibilityTimeoutParser < RightAWSParser # :nodoc:
540
+ def tagend(name)
541
+ @result = @text.to_i if name == 'VisibilityTimeout'
542
+ end
543
+ end
544
+
545
+ #-----------------------------------------------------------------
546
+ # PARSERS: Permissions
547
+ #-----------------------------------------------------------------
548
+
549
+ class SqsListGrantsParser < RightAWSParser # :nodoc:
550
+ def reset
551
+ @result = []
552
+ end
553
+ def tagstart(name, attributes)
554
+ @current_perms = {} if name == 'GrantList'
555
+ end
556
+ def tagend(name)
557
+ case name
558
+ when 'ID' ; @current_perms[:id] = @text
559
+ when 'DisplayName'; @current_perms[:name] = @text
560
+ when 'Permission' ; @current_perms[:permission] = @text
561
+ when 'GrantList' ; @result << @current_perms
562
+ end
563
+ end
564
+ end
565
+
566
+ #-----------------------------------------------------------------
567
+ # PARSERS: Messages
568
+ #-----------------------------------------------------------------
569
+
570
+ class SqsReceiveMessagesParser < RightAWSParser # :nodoc:
571
+ def reset
572
+ @result = []
573
+ end
574
+ def tagstart(name, attributes)
575
+ @current_message = {} if name == 'Message'
576
+ end
577
+ def tagend(name)
578
+ case name
579
+ when 'MessageId' ; @current_message[:id] = @text
580
+ when 'MessageBody'; @current_message[:body] = @text
581
+ when 'Message' ; @result << @current_message
582
+ end
583
+ end
584
+ end
585
+
586
+ class SqsSendMessagesParser < RightAWSParser # :nodoc:
587
+ def tagend(name)
588
+ @result = @text if name == 'MessageId'
589
+ end
590
+ end
591
+
592
+ end
593
+
594
+ end