aboisvert_aws 3.0.0

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