talaris-right_aws 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. data/History.txt +305 -0
  2. data/Manifest.txt +60 -0
  3. data/README.txt +163 -0
  4. data/Rakefile +104 -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 +1174 -0
  13. data/lib/awsbase/support.rb +35 -0
  14. data/lib/awsbase/version.rb +9 -0
  15. data/lib/ec2/right_ec2.rb +458 -0
  16. data/lib/ec2/right_ec2_ebs.rb +465 -0
  17. data/lib/ec2/right_ec2_images.rb +413 -0
  18. data/lib/ec2/right_ec2_instances.rb +785 -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 +174 -0
  22. data/lib/ec2/right_ec2_security_groups.rb +396 -0
  23. data/lib/ec2/right_ec2_spot_instances.rb +425 -0
  24. data/lib/ec2/right_ec2_tags.rb +139 -0
  25. data/lib/ec2/right_ec2_vpc.rb +583 -0
  26. data/lib/ec2/right_ec2_windows_mobility.rb +84 -0
  27. data/lib/elb/right_elb_interface.rb +571 -0
  28. data/lib/iam/right_iam_access_keys.rb +71 -0
  29. data/lib/iam/right_iam_groups.rb +195 -0
  30. data/lib/iam/right_iam_interface.rb +341 -0
  31. data/lib/iam/right_iam_mfa_devices.rb +67 -0
  32. data/lib/iam/right_iam_users.rb +251 -0
  33. data/lib/rds/right_rds_interface.rb +1309 -0
  34. data/lib/right_aws.rb +83 -0
  35. data/lib/route_53/right_route_53_interface.rb +630 -0
  36. data/lib/s3/right_s3.rb +1123 -0
  37. data/lib/s3/right_s3_interface.rb +1198 -0
  38. data/lib/sdb/active_sdb.rb +1107 -0
  39. data/lib/sdb/right_sdb_interface.rb +753 -0
  40. data/lib/sqs/right_sqs.rb +387 -0
  41. data/lib/sqs/right_sqs_gen2.rb +342 -0
  42. data/lib/sqs/right_sqs_gen2_interface.rb +523 -0
  43. data/lib/sqs/right_sqs_interface.rb +593 -0
  44. data/right_aws.gemspec +91 -0
  45. data/test/acf/test_helper.rb +2 -0
  46. data/test/acf/test_right_acf.rb +138 -0
  47. data/test/awsbase/test_helper.rb +2 -0
  48. data/test/awsbase/test_right_awsbase.rb +12 -0
  49. data/test/ec2/test_helper.rb +2 -0
  50. data/test/ec2/test_right_ec2.rb +108 -0
  51. data/test/http_connection.rb +87 -0
  52. data/test/rds/test_helper.rb +2 -0
  53. data/test/rds/test_right_rds.rb +120 -0
  54. data/test/s3/test_helper.rb +2 -0
  55. data/test/s3/test_right_s3.rb +421 -0
  56. data/test/s3/test_right_s3_stubbed.rb +97 -0
  57. data/test/sdb/test_active_sdb.rb +357 -0
  58. data/test/sdb/test_batch_put_attributes.rb +54 -0
  59. data/test/sdb/test_helper.rb +3 -0
  60. data/test/sdb/test_right_sdb.rb +253 -0
  61. data/test/sqs/test_helper.rb +2 -0
  62. data/test/sqs/test_right_sqs.rb +285 -0
  63. data/test/sqs/test_right_sqs_gen2.rb +264 -0
  64. data/test/test_credentials.rb +37 -0
  65. data/test/ts_right_aws.rb +14 -0
  66. metadata +214 -0
@@ -0,0 +1,387 @@
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
+ #
27
+ # = RightAws::Sqs -- RightScale's Amazon SQS interface
28
+ # The RightAws::Sqs class provides a complete interface to Amazon's Simple
29
+ # Queue Service.
30
+ # For explanations of the semantics
31
+ # of each call, please refer to Amazon's documentation at
32
+ # http://developer.amazonwebservices.com/connect/kbcategory.jspa?categoryID=31
33
+ #
34
+ # Error handling: all operations raise an RightAws::AwsError in case
35
+ # of problems. Note that transient errors are automatically retried.
36
+ #
37
+ # sqs = RightAws::Sqs.new(aws_access_key_id, aws_secret_access_key)
38
+ # queue1 = sqs.queue('my_awesome_queue')
39
+ # ...
40
+ # queue2 = RightAws::Sqs::Queue.create(sqs, 'my_cool_queue', true)
41
+ # puts queue2.size
42
+ # ...
43
+ # message1 = queue2.receive
44
+ # message1.visibility = 0
45
+ # puts message1
46
+ # ...
47
+ # queue2.clear(true)
48
+ # queue2.send_message('Ola-la!')
49
+ # message2 = queue2.pop
50
+ # ...
51
+ # grantee1 = RightAws::Sqs::Grantee.create(queue2,'one_cool_guy@email.address')
52
+ # grantee1.grant('FULLCONTROL')
53
+ # grantee1.drop
54
+ # ...
55
+ # grantee2 = queue.grantees('another_cool_guy@email.address')
56
+ # grantee2.revoke('SENDMESSAGE')
57
+ #
58
+ # Params is a hash:
59
+ #
60
+ # {:server => 'queue.amazonaws.com' # Amazon service host: 'queue.amazonaws.com' (default)
61
+ # :port => 443 # Amazon service port: 80 or 443 (default)
62
+ # :signature_version => '0' # The signature version : '0' or '1'(default)
63
+ # :logger => Logger Object} # Logger instance: logs to STDOUT if omitted }
64
+ #
65
+ class Sqs
66
+ attr_reader :interface
67
+
68
+ def initialize(aws_access_key_id=nil, aws_secret_access_key=nil, params={})
69
+ @interface = SqsInterface.new(aws_access_key_id, aws_secret_access_key, params)
70
+ end
71
+
72
+ # Retrieves a list of queues.
73
+ # Returns an +array+ of +Queue+ instances.
74
+ #
75
+ # RightAws::Sqs.queues #=> array of queues
76
+ #
77
+ def queues(prefix=nil)
78
+ @interface.list_queues(prefix).map do |url|
79
+ Queue.new(self, url)
80
+ end
81
+ end
82
+
83
+ # Returns Queue instance by queue name.
84
+ # If the queue does not exist at Amazon SQS and +create+ is true, the method creates it.
85
+ #
86
+ # RightAws::Sqs.queue('my_awesome_queue') #=> #<RightAws::Sqs::Queue:0xb7b626e4 ... >
87
+ #
88
+ def queue(queue_name, create=true, visibility=nil)
89
+ url = @interface.queue_url_by_name(queue_name)
90
+ url = (create ? @interface.create_queue(queue_name, visibility) : nil) unless url
91
+ url ? Queue.new(self, url) : nil
92
+ end
93
+
94
+
95
+ class Queue
96
+ attr_reader :name, :url, :sqs
97
+
98
+ # Returns Queue instance by queue name.
99
+ # If the queue does not exist at Amazon SQS and +create+ is true, the method creates it.
100
+ #
101
+ # RightAws::Sqs::Queue.create(sqs, 'my_awesome_queue') #=> #<RightAws::Sqs::Queue:0xb7b626e4 ... >
102
+ #
103
+ def self.create(sqs, url_or_name, create=true, visibility=nil)
104
+ sqs.queue(url_or_name, create, visibility)
105
+ end
106
+
107
+ # Creates new Queue instance.
108
+ # Does not create a queue at Amazon.
109
+ #
110
+ # queue = RightAws::Sqs::Queue.new(sqs, 'my_awesome_queue')
111
+ #
112
+ def initialize(sqs, url_or_name)
113
+ @sqs = sqs
114
+ @url = @sqs.interface.queue_url_by_name(url_or_name)
115
+ @name = @sqs.interface.queue_name_by_url(@url)
116
+ end
117
+
118
+ # Retrieves queue size.
119
+ #
120
+ # queue.size #=> 1
121
+ #
122
+ def size
123
+ @sqs.interface.get_queue_length(@url)
124
+ end
125
+
126
+ # Clears queue.
127
+ # Deletes only the visible messages unless +force+ is +true+.
128
+ #
129
+ # queue.clear(true) #=> true
130
+ #
131
+ # P.S. when <tt>force==true</tt> the queue deletes then creates again. This is
132
+ # the quickest method to clear a big queue or a queue with 'locked' messages. All queue
133
+ # attributes are restored. But there is no way to restore grantees' permissions to
134
+ # this queue. If you have no grantees except 'root' then you have no problems.
135
+ # Otherwise, it's better to use <tt>queue.clear(false)</tt>.
136
+ #
137
+ # PS This function is no longer supported. Amazon has changed the SQS semantics to require at least 60 seconds between
138
+ # queue deletion and creation. Hence this method will fail with an exception.
139
+ #
140
+ def clear(force=false)
141
+ ## if force
142
+ ## @sqs.interface.force_clear_queue(@url)
143
+ ## else
144
+ @sqs.interface.clear_queue(@url)
145
+ ## end
146
+ end
147
+
148
+ # Deletes queue.
149
+ # Queue must be empty or +force+ must be set to +true+.
150
+ # Returns +true+.
151
+ #
152
+ # queue.delete(true) #=> true
153
+ #
154
+ def delete(force=false)
155
+ @sqs.interface.delete_queue(@url, force)
156
+ end
157
+
158
+ # Sends new message to queue.
159
+ # Returns new Message instance that has been sent to queue.
160
+ def send_message(message)
161
+ message = message.to_s
162
+ msg = Message.new(self, @sqs.interface.send_message(@url, message), message)
163
+ msg.sent_at = Time.now
164
+ msg
165
+ end
166
+ alias_method :push, :send_message
167
+
168
+ # Retrieves several messages from queue.
169
+ # Returns an array of Message instances.
170
+ #
171
+ # queue.receive_messages(2,10) #=> array of messages
172
+ #
173
+ def receive_messages(number_of_messages=1, visibility=nil)
174
+ list = @sqs.interface.receive_messages(@url, number_of_messages, visibility)
175
+ list.map! do |entry|
176
+ msg = Message.new(self, entry[:id], entry[:body], visibility)
177
+ msg.received_at = Time.now
178
+ msg
179
+ end
180
+ end
181
+
182
+ # Retrieves first accessible message from queue.
183
+ # Returns Message instance or +nil+ it the queue is empty.
184
+ #
185
+ # queue.receive #=> #<RightAws::Sqs::Message:0xb7bf0884 ... >
186
+ #
187
+ def receive(visibility=nil)
188
+ list = receive_messages(1, visibility)
189
+ list.empty? ? nil : list[0]
190
+ end
191
+
192
+ # Peeks message body.
193
+ #
194
+ # queue.peek #=> #<RightAws::Sqs::Message:0xb7bf0884 ... >
195
+ #
196
+ def peek(message_id)
197
+ entry = @sqs.interface.peek_message(@url, message_id)
198
+ msg = Message.new(self, entry[:id], entry[:body])
199
+ msg.received_at = Time.now
200
+ msg
201
+ end
202
+
203
+ # Pops (and deletes) first accessible message from queue.
204
+ # Returns Message instance or +nil+ it the queue is empty.
205
+ #
206
+ # queue.pop #=> #<RightAws::Sqs::Message:0xb7bf0884 ... >
207
+ #
208
+ def pop
209
+ msg = receive
210
+ msg.delete if msg
211
+ msg
212
+ end
213
+
214
+ # Retrieves +VisibilityTimeout+ value for the queue.
215
+ # Returns new timeout value.
216
+ #
217
+ # queue.visibility #=> 30
218
+ #
219
+ def visibility
220
+ @sqs.interface.get_visibility_timeout(@url)
221
+ end
222
+
223
+ # Sets new +VisibilityTimeout+ for the queue.
224
+ # Returns new timeout value.
225
+ #
226
+ # queue.visibility #=> 30
227
+ # queue.visibility = 33
228
+ # queue.visibility #=> 33
229
+ #
230
+ def visibility=(visibility_timeout)
231
+ @sqs.interface.set_visibility_timeout(@url, visibility_timeout)
232
+ visibility_timeout
233
+ end
234
+
235
+ # Sets new queue attribute value.
236
+ # Not all attributes may be changed: +ApproximateNumberOfMessages+ (for example) is a read only attribute.
237
+ # Returns a value to be assigned to attribute.
238
+ #
239
+ # queue.set_attribute('VisibilityTimeout', '100') #=> '100'
240
+ # queue.get_attribute('VisibilityTimeout') #=> '100'
241
+ #
242
+ def set_attribute(attribute, value)
243
+ @sqs.interface.set_queue_attributes(@url, attribute, value)
244
+ value
245
+ end
246
+
247
+ # Retrieves queue attributes.
248
+ # At this moment Amazon supports +VisibilityTimeout+ and +ApproximateNumberOfMessages+ only.
249
+ # If the name of attribute is set, returns its value. Otherwise, returns a hash of attributes.
250
+ #
251
+ # queue.get_attribute('VisibilityTimeout') #=> '100'
252
+ #
253
+ def get_attribute(attribute='All')
254
+ attributes = @sqs.interface.get_queue_attributes(@url, attribute)
255
+ attribute=='All' ? attributes : attributes[attribute]
256
+ end
257
+
258
+ # Retrieves a list of grantees.
259
+ # Returns an +array+ of Grantee instances if the +grantee_email_address+ is unset.
260
+ # Otherwise returns a Grantee instance that points to +grantee_email_address+ or +nil+.
261
+ #
262
+ # grantees = queue.grantees #=> [#<RightAws::Sqs::Grantee:0xb7bf0888 ... >, ...]
263
+ # ...
264
+ # grantee = queue.grantees('cool_guy@email.address') #=> nil | #<RightAws::Sqs::Grantee:0xb7bf0888 ... >
265
+ #
266
+ def grantees(grantee_email_address=nil, permission = nil)
267
+ hash = @sqs.interface.list_grants(@url, grantee_email_address, permission)
268
+ grantees = []
269
+ hash.each do |key, value|
270
+ grantees << Grantee.new(self, grantee_email_address, key, value[:name], value[:perms])
271
+ end
272
+ if grantee_email_address
273
+ grantees.right_blank? ? nil : grantees.shift
274
+ else
275
+ grantees
276
+ end
277
+ end
278
+ end
279
+
280
+
281
+ class Message
282
+ attr_reader :queue, :id, :body, :visibility
283
+ attr_accessor :sent_at, :received_at
284
+
285
+ def initialize(queue, id=nil, body=nil, visibility=nil)
286
+ @queue = queue
287
+ @id = id
288
+ @body = body
289
+ @visibility = visibility
290
+ @sent_at = nil
291
+ @received_at = nil
292
+ end
293
+
294
+ # Returns +Message+ instance body.
295
+ def to_s
296
+ @body
297
+ end
298
+
299
+ # Changes +VisibilityTimeout+ for current message.
300
+ # Returns new +VisibilityTimeout+ value.
301
+ def visibility=(visibility_timeout)
302
+ @queue.sqs.interface.change_message_visibility(@queue.url, @id, visibility_timeout)
303
+ @visibility = visibility_timeout
304
+ end
305
+
306
+ # Removes message from queue.
307
+ # Returns +true+.
308
+ def delete
309
+ @queue.sqs.interface.delete_message(@queue.url, @id)
310
+ end
311
+ end
312
+
313
+
314
+ class Grantee
315
+ attr_accessor :queue, :id, :name, :perms, :email
316
+
317
+ # Creates new Grantee instance.
318
+ # To create new grantee for queue use:
319
+ #
320
+ # grantee = Grantee.new(queue, grantee@email.address)
321
+ # grantee.grant('FULLCONTROL')
322
+ #
323
+ def initialize(queue, email=nil, id=nil, name=nil, perms=[])
324
+ @queue = queue
325
+ @id = id
326
+ @name = name
327
+ @perms = perms
328
+ @email = email
329
+ retrieve unless id
330
+ end
331
+
332
+ # Retrieves security information for grantee identified by email.
333
+ # Returns +nil+ if the named user has no privileges on this queue, or
334
+ # +true+ if perms updated successfully.
335
+ def retrieve # :nodoc:
336
+ @id = nil
337
+ @name = nil
338
+ @perms = []
339
+
340
+ hash = @queue.sqs.interface.list_grants(@queue.url, @email)
341
+ return nil if hash.empty?
342
+
343
+ grantee = hash.shift
344
+ @id = grantee[0]
345
+ @name = grantee[1][:name]
346
+ @perms = grantee[1][:perms]
347
+ true
348
+ end
349
+
350
+ # Adds permissions for grantee.
351
+ # Permission: 'FULLCONTROL' | 'RECEIVEMESSAGE' | 'SENDMESSAGE'.
352
+ # The caller must have set the email instance variable.
353
+ def grant(permission=nil)
354
+ raise "You can't grant permission without defining a grantee email address!" unless @email
355
+ @queue.sqs.interface.add_grant(@queue.url, @email, permission)
356
+ retrieve
357
+ end
358
+
359
+ # Revokes permissions for grantee.
360
+ # Permission: 'FULLCONTROL' | 'RECEIVEMESSAGE' | 'SENDMESSAGE'.
361
+ # Default value is 'FULLCONTROL'.
362
+ # User must have +@email+ or +@id+ set.
363
+ # Returns +true+.
364
+ def revoke(permission='FULLCONTROL')
365
+ @queue.sqs.interface.remove_grant(@queue.url, @email || @id, permission)
366
+ unless @email # if email is unknown - just remove permission from local perms list...
367
+ @perms.delete(permission)
368
+ else # ... else retrieve updated information from Amazon
369
+ retrieve
370
+ end
371
+ true
372
+ end
373
+
374
+ # Revokes all permissions for this grantee.
375
+ # Returns +true+
376
+ def drop
377
+ @perms.each do |permission|
378
+ @queue.sqs.interface.remove_grant(@queue.url, @email || @id, permission)
379
+ end
380
+ retrieve
381
+ true
382
+ end
383
+
384
+ end
385
+
386
+ end
387
+ end
@@ -0,0 +1,342 @@
1
+ #
2
+ # Copyright (c) 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
+ #
27
+ # RightAws::SqsGen2 -- RightScale's Amazon SQS interface, API version
28
+ # 2008-01-01 and later.
29
+ # The RightAws::SqsGen2 class provides a complete interface to the second generation of Amazon's Simple
30
+ # Queue Service.
31
+ # For explanations of the semantics
32
+ # of each call, please refer to Amazon's documentation at
33
+ # http://developer.amazonwebservices.com/connect/kbcategory.jspa?categoryID=31
34
+ #
35
+ #
36
+ # RightAws::SqsGen2 is built atop RightAws::SqsGen2Interface, a lower-level
37
+ # procedural API that may be appropriate for certain programs.
38
+ #
39
+ # Error handling: all operations raise an RightAws::AwsError in case
40
+ # of problems. Note that transient errors are automatically retried.
41
+ #
42
+ # sqs = RightAws::SqsGen2.new(aws_access_key_id, aws_secret_access_key)
43
+ # queue1 = sqs.queue('my_awesome_queue')
44
+ # ...
45
+ # queue2 = RightAws::SqsGen2::Queue.create(sqs, 'my_cool_queue', true)
46
+ # puts queue2.size
47
+ # ...
48
+ # message1 = queue2.receive
49
+ # message1.visibility = 0
50
+ # puts message1
51
+ # ...
52
+ # queue2.clear(true)
53
+ # queue2.send_message('Ola-la!')
54
+ # message2 = queue2.pop
55
+ # ...
56
+ #
57
+ # NB: Second-generation SQS has eliminated the entire access grant mechanism present in Gen 1.
58
+ #
59
+ # Params is a hash:
60
+ #
61
+ # {:server => 'queue.amazonaws.com' # Amazon service host: 'queue.amazonaws.com' (default)
62
+ # :port => 443 # Amazon service port: 80 or 443 (default)
63
+ # :signature_version => '0' # The signature version : '0' or '1'(default)
64
+ # :logger => Logger Object} # Logger instance: logs to STDOUT if omitted }
65
+ class SqsGen2
66
+ attr_reader :interface
67
+
68
+ def initialize(aws_access_key_id=nil, aws_secret_access_key=nil, params={})
69
+ @interface = SqsGen2Interface.new(aws_access_key_id, aws_secret_access_key, params)
70
+ end
71
+
72
+ # Retrieves a list of queues.
73
+ # Returns an +array+ of +Queue+ instances.
74
+ #
75
+ # RightAws::Sqs.queues #=> array of queues
76
+ #
77
+ def queues(prefix=nil)
78
+ @interface.list_queues(prefix).map do |url|
79
+ Queue.new(self, url)
80
+ end
81
+ end
82
+
83
+ # Returns Queue instance by queue name.
84
+ # If the queue does not exist at Amazon SQS and +create+ is true, the method creates it.
85
+ #
86
+ # RightAws::SqsGen2.queue('my_awesome_queue') #=> #<RightAws::SqsGen2::Queue:0xb7b626e4 ... >
87
+ #
88
+ def queue(queue_name, create=true, visibility=nil)
89
+ url = @interface.queue_url_by_name(queue_name)
90
+ url = (create ? @interface.create_queue(queue_name, visibility) : nil) unless url
91
+ url ? Queue.new(self, url) : nil
92
+ end
93
+
94
+
95
+ class Queue
96
+ attr_reader :name, :url, :sqs
97
+
98
+ # Returns Queue instance by queue name.
99
+ # If the queue does not exist at Amazon SQS and +create+ is true, the method creates it.
100
+ #
101
+ # RightAws::SqsGen2::Queue.create(sqs, 'my_awesome_queue') #=> #<RightAws::SqsGen2::Queue:0xb7b626e4 ... >
102
+ #
103
+ def self.create(sqs, url_or_name, create=true, visibility=nil)
104
+ sqs.queue(url_or_name, create, visibility)
105
+ end
106
+
107
+ # Creates new Queue instance.
108
+ # Does not create a queue at Amazon.
109
+ #
110
+ # queue = RightAws::SqsGen2::Queue.new(sqs, 'my_awesome_queue')
111
+ #
112
+ def initialize(sqs, url_or_name)
113
+ @sqs = sqs
114
+ @url = @sqs.interface.queue_url_by_name(url_or_name)
115
+ @name = @sqs.interface.queue_name_by_url(@url)
116
+ end
117
+
118
+ # Retrieves queue size.
119
+ #
120
+ # queue.size #=> 1
121
+ #
122
+ def size
123
+ @sqs.interface.get_queue_length(@url)
124
+ end
125
+
126
+ # Clears queue, deleting only the visible messages. Any message within its visibility
127
+ # timeout will not be deleted, and will re-appear in the queue in the
128
+ # future when the timeout expires.
129
+ #
130
+ # To delete all messages in a queue and eliminate the chance of any
131
+ # messages re-appearing in the future, it's best to delete the queue and
132
+ # re-create it as a new queue. Note that doing this will take at least 60
133
+ # s since SQS does not allow re-creation of a queue within this interval.
134
+ #
135
+ # queue.clear() #=> true
136
+ #
137
+ def clear()
138
+ @sqs.interface.clear_queue(@url)
139
+ end
140
+
141
+ # Deletes queue. Any messages in the queue will be permanently lost.
142
+ # Returns +true+.
143
+ #
144
+ # NB: Use with caution; severe data loss is possible!
145
+ #
146
+ # queue.delete(true) #=> true
147
+ #
148
+ def delete(force=false)
149
+ @sqs.interface.delete_queue(@url)
150
+ end
151
+
152
+ # Sends new message to queue.
153
+ # Returns new Message instance that has been sent to queue.
154
+ def send_message(message)
155
+ message = message.to_s
156
+ res = @sqs.interface.send_message(@url, message)
157
+ msg = Message.new(self, res['MessageId'], nil, message)
158
+ msg.send_checksum = res['MD5OfMessageBody']
159
+ msg.sent_at = Time.now
160
+ msg
161
+ end
162
+ alias_method :push, :send_message
163
+
164
+ # Retrieves several messages from queue.
165
+ # Returns an array of Message instances.
166
+ #
167
+ # queue.receive_messages(2,10) #=> array of messages
168
+ #
169
+ def receive_messages(number_of_messages=1, visibility=nil, attributes=nil)
170
+ list = @sqs.interface.receive_message(@url, number_of_messages, visibility, attributes)
171
+ list.map! do |entry|
172
+ msg = Message.new(self, entry['MessageId'], entry['ReceiptHandle'], entry['Body'], visibility, entry['Attributes'])
173
+ msg.received_at = Time.now
174
+ msg.receive_checksum = entry['MD5OfBody']
175
+ msg
176
+ end
177
+ end
178
+
179
+ # Retrieves first accessible message from queue.
180
+ # Returns Message instance or +nil+ it the queue is empty.
181
+ #
182
+ # queue.receive #=> #<RightAws::SqsGen2::Message:0xb7bf0884 ... >
183
+ #
184
+ def receive(visibility=nil, attributes=nil)
185
+ list = receive_messages(1, visibility, attributes)
186
+ list.empty? ? nil : list[0]
187
+ end
188
+
189
+ # Pops (and deletes) first accessible message from queue.
190
+ # Returns Message instance or +nil+ if the queue is empty.
191
+ #
192
+ # queue.pop #=> #<RightAws::SqsGen2::Message:0xb7bf0884 ... >
193
+ #
194
+ # # pop a message with custom attributes
195
+ # m = queue.pop(['SenderId', 'SentTimestamp']) #=> #<RightAws::SqsGen2::Message:0xb7bf1884 ... >
196
+ # m.attributes #=> {"SentTimestamp"=>"1240991906937", "SenderId"=>"800000000005"}
197
+ #
198
+ def pop(attributes=nil)
199
+ list = @sqs.interface.pop_messages(@url, 1, attributes)
200
+ return nil if list.empty?
201
+ entry = list[0]
202
+ msg = Message.new(self, entry['MessageId'], entry['ReceiptHandle'], entry['Body'], visibility, entry['Attributes'])
203
+ msg.received_at = Time.now
204
+ msg.receive_checksum = entry['MD5OfBody']
205
+ msg
206
+ end
207
+
208
+ # Retrieves +VisibilityTimeout+ value for the queue.
209
+ # Returns new timeout value.
210
+ #
211
+ # queue.visibility #=> 30
212
+ #
213
+ def visibility
214
+ @sqs.interface.get_queue_attributes(@url, 'VisibilityTimeout')['VisibilityTimeout']
215
+ end
216
+
217
+ # Sets new +VisibilityTimeout+ for the queue.
218
+ # Returns new timeout value.
219
+ #
220
+ # queue.visibility #=> 30
221
+ # queue.visibility = 33
222
+ # queue.visibility #=> 33
223
+ #
224
+ def visibility=(visibility_timeout)
225
+ @sqs.interface.set_queue_attributes(@url, 'VisibilityTimeout', visibility_timeout)
226
+ visibility_timeout
227
+ end
228
+
229
+ # Sets new queue attribute value.
230
+ # Not all attributes may be changed: +ApproximateNumberOfMessages+ (for example) is a read only attribute.
231
+ # Returns a value to be assigned to attribute.
232
+ # Currently, 'VisibilityTimeout' is the only settable queue attribute.
233
+ # Attempting to set non-existent attributes generates an indignant
234
+ # exception.
235
+ #
236
+ # queue.set_attribute('VisibilityTimeout', '100') #=> '100'
237
+ # queue.get_attribute('VisibilityTimeout') #=> '100'
238
+ #
239
+ def set_attribute(attribute, value)
240
+ @sqs.interface.set_queue_attributes(@url, attribute, value)
241
+ value
242
+ end
243
+
244
+ # Retrieves queue attributes.
245
+ # If the name of attribute is set, returns its value. Otherwise, returns a hash of attributes.
246
+ #
247
+ # queue.get_attribute('VisibilityTimeout') #=> {"VisibilityTimeout"=>"45"}
248
+ #
249
+ # P.S. This guy is deprecated. Use +get_attributes+ instead.
250
+ def get_attribute(attribute='All')
251
+ attributes = get_attributes(attribute)
252
+ attribute=='All' ? attributes : attributes[attribute]
253
+ end
254
+
255
+ # Retrieves queue attributes.
256
+ #
257
+ # queue.get_attributes #=>
258
+ # {"ApproximateNumberOfMessages" => "0",
259
+ # "LastModifiedTimestamp" => "1240946032",
260
+ # "CreatedTimestamp" => "1240816887",
261
+ # "VisibilityTimeout" => "30",
262
+ # "Policy" => "{"Version":"2008-10-17","Id":...}"}
263
+ #
264
+ # queue.get_attributes("LastModifiedTimestamp", "VisibilityTimeout") #=>
265
+ # {"LastModifiedTimestamp" => "1240946032",
266
+ # "VisibilityTimeout" => "30"}
267
+ #
268
+ def get_attributes(*attributes)
269
+ @sqs.interface.get_queue_attributes(@url, attributes)
270
+ end
271
+
272
+ # Add permission to the queue.
273
+ #
274
+ # queue.add_permissions('testLabel',['125074342641', '125074342642'],
275
+ # ['SendMessage','SendMessage','ReceiveMessage']) #=> true
276
+ #
277
+ def add_permissions(label, grantees, actions)
278
+ @sqs.interface.add_permissions(@url, label, grantees, actions)
279
+ end
280
+
281
+ # Revoke any permissions in the queue policy that matches the +label+ parameter.
282
+ #
283
+ # sqs.remove_permissions('testLabel') # => true
284
+ #
285
+ def remove_permissions(label)
286
+ @sqs.interface.remove_permissions(@url, label)
287
+ end
288
+
289
+ # Get current permissions set. The set is JSON packed.
290
+ #
291
+ # sqs.get_permissions #=>
292
+ # '{"Version":"2008-10-17","Id":"/826693181925/kd-test-gen-2_5/SQSDefaultPolicy",
293
+ # "Statement":[{"Sid":"kd-perm-04","Effect":"Allow","Principal":{"AWS":"100000000001",
294
+ # "AWS":"100000000001","AWS":"100000000002"},"Action":["SQS:SendMessage","SQS:DeleteMessage",
295
+ # "SQS:ReceiveMessage"],"Resource":"/826693181925/kd-test-gen-2_5"},{"Sid":"kd-perm-03",
296
+ # "Effect":"Allow","Principal":{"AWS":"648772224137"},"Action":"SQS:SendMessage",
297
+ # "Resource":"/826693181925/kd-test-gen-2_5"}]}'
298
+ #
299
+ def get_permissions
300
+ get_attributes('Policy')['Policy']
301
+ end
302
+
303
+ end
304
+
305
+ class Message
306
+ attr_reader :queue, :id, :body, :visibility, :receipt_handle, :attributes
307
+ attr_accessor :sent_at, :received_at, :send_checksum, :receive_checksum
308
+
309
+ def initialize(queue, id=nil, rh = nil, body=nil, visibility=nil, attributes=nil)
310
+ @queue = queue
311
+ @id = id
312
+ @receipt_handle = rh
313
+ @body = body
314
+ @visibility = visibility
315
+ @attributes = attributes
316
+ @sent_at = nil
317
+ @received_at = nil
318
+ @send_checksum = nil
319
+ @receive_checksum = nil
320
+ end
321
+
322
+ # Returns +Message+ instance body.
323
+ def to_s
324
+ @body
325
+ end
326
+
327
+ # Set message visibility timeout.
328
+ def visibility=(visibility_timeout)
329
+ @queue.sqs.interface.change_message_visibility(@queue.url, @receipt_handle, visibility_timeout)
330
+ @visibility = visibility_timeout
331
+ end
332
+
333
+ # Removes message from queue.
334
+ # Returns +true+.
335
+ def delete
336
+ @queue.sqs.interface.delete_message(@queue.url, @receipt_handle) if @receipt_handle
337
+ end
338
+
339
+ end
340
+
341
+ end
342
+ end