revans_right_aws 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
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,388 @@
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
+ # :multi_thread => true|false # Multi-threaded (connection per each thread): true or false (default)
63
+ # :signature_version => '0' # The signature version : '0' or '1'(default)
64
+ # :logger => Logger Object} # Logger instance: logs to STDOUT if omitted }
65
+ #
66
+ class Sqs
67
+ attr_reader :interface
68
+
69
+ def initialize(aws_access_key_id=nil, aws_secret_access_key=nil, params={})
70
+ @interface = SqsInterface.new(aws_access_key_id, aws_secret_access_key, params)
71
+ end
72
+
73
+ # Retrieves a list of queues.
74
+ # Returns an +array+ of +Queue+ instances.
75
+ #
76
+ # RightAws::Sqs.queues #=> array of queues
77
+ #
78
+ def queues(prefix=nil)
79
+ @interface.list_queues(prefix).map do |url|
80
+ Queue.new(self, url)
81
+ end
82
+ end
83
+
84
+ # Returns Queue instance by queue name.
85
+ # If the queue does not exist at Amazon SQS and +create+ is true, the method creates it.
86
+ #
87
+ # RightAws::Sqs.queue('my_awesome_queue') #=> #<RightAws::Sqs::Queue:0xb7b626e4 ... >
88
+ #
89
+ def queue(queue_name, create=true, visibility=nil)
90
+ url = @interface.queue_url_by_name(queue_name)
91
+ url = (create ? @interface.create_queue(queue_name, visibility) : nil) unless url
92
+ url ? Queue.new(self, url) : nil
93
+ end
94
+
95
+
96
+ class Queue
97
+ attr_reader :name, :url, :sqs
98
+
99
+ # Returns Queue instance by queue name.
100
+ # If the queue does not exist at Amazon SQS and +create+ is true, the method creates it.
101
+ #
102
+ # RightAws::Sqs::Queue.create(sqs, 'my_awesome_queue') #=> #<RightAws::Sqs::Queue:0xb7b626e4 ... >
103
+ #
104
+ def self.create(sqs, url_or_name, create=true, visibility=nil)
105
+ sqs.queue(url_or_name, create, visibility)
106
+ end
107
+
108
+ # Creates new Queue instance.
109
+ # Does not create a queue at Amazon.
110
+ #
111
+ # queue = RightAws::Sqs::Queue.new(sqs, 'my_awesome_queue')
112
+ #
113
+ def initialize(sqs, url_or_name)
114
+ @sqs = sqs
115
+ @url = @sqs.interface.queue_url_by_name(url_or_name)
116
+ @name = @sqs.interface.queue_name_by_url(@url)
117
+ end
118
+
119
+ # Retrieves queue size.
120
+ #
121
+ # queue.size #=> 1
122
+ #
123
+ def size
124
+ @sqs.interface.get_queue_length(@url)
125
+ end
126
+
127
+ # Clears queue.
128
+ # Deletes only the visible messages unless +force+ is +true+.
129
+ #
130
+ # queue.clear(true) #=> true
131
+ #
132
+ # P.S. when <tt>force==true</tt> the queue deletes then creates again. This is
133
+ # the quickest method to clear a big queue or a queue with 'locked' messages. All queue
134
+ # attributes are restored. But there is no way to restore grantees' permissions to
135
+ # this queue. If you have no grantees except 'root' then you have no problems.
136
+ # Otherwise, it's better to use <tt>queue.clear(false)</tt>.
137
+ #
138
+ # PS This function is no longer supported. Amazon has changed the SQS semantics to require at least 60 seconds between
139
+ # queue deletion and creation. Hence this method will fail with an exception.
140
+ #
141
+ def clear(force=false)
142
+ ## if force
143
+ ## @sqs.interface.force_clear_queue(@url)
144
+ ## else
145
+ @sqs.interface.clear_queue(@url)
146
+ ## end
147
+ end
148
+
149
+ # Deletes queue.
150
+ # Queue must be empty or +force+ must be set to +true+.
151
+ # Returns +true+.
152
+ #
153
+ # queue.delete(true) #=> true
154
+ #
155
+ def delete(force=false)
156
+ @sqs.interface.delete_queue(@url, force)
157
+ end
158
+
159
+ # Sends new message to queue.
160
+ # Returns new Message instance that has been sent to queue.
161
+ def send_message(message)
162
+ message = message.to_s
163
+ msg = Message.new(self, @sqs.interface.send_message(@url, message), message)
164
+ msg.sent_at = Time.now
165
+ msg
166
+ end
167
+ alias_method :push, :send_message
168
+
169
+ # Retrieves several messages from queue.
170
+ # Returns an array of Message instances.
171
+ #
172
+ # queue.receive_messages(2,10) #=> array of messages
173
+ #
174
+ def receive_messages(number_of_messages=1, visibility=nil)
175
+ list = @sqs.interface.receive_messages(@url, number_of_messages, visibility)
176
+ list.map! do |entry|
177
+ msg = Message.new(self, entry[:id], entry[:body], visibility)
178
+ msg.received_at = Time.now
179
+ msg
180
+ end
181
+ end
182
+
183
+ # Retrieves first accessible message from queue.
184
+ # Returns Message instance or +nil+ it the queue is empty.
185
+ #
186
+ # queue.receive #=> #<RightAws::Sqs::Message:0xb7bf0884 ... >
187
+ #
188
+ def receive(visibility=nil)
189
+ list = receive_messages(1, visibility)
190
+ list.empty? ? nil : list[0]
191
+ end
192
+
193
+ # Peeks message body.
194
+ #
195
+ # queue.peek #=> #<RightAws::Sqs::Message:0xb7bf0884 ... >
196
+ #
197
+ def peek(message_id)
198
+ entry = @sqs.interface.peek_message(@url, message_id)
199
+ msg = Message.new(self, entry[:id], entry[:body])
200
+ msg.received_at = Time.now
201
+ msg
202
+ end
203
+
204
+ # Pops (and deletes) first accessible message from queue.
205
+ # Returns Message instance or +nil+ it the queue is empty.
206
+ #
207
+ # queue.pop #=> #<RightAws::Sqs::Message:0xb7bf0884 ... >
208
+ #
209
+ def pop
210
+ msg = receive
211
+ msg.delete if msg
212
+ msg
213
+ end
214
+
215
+ # Retrieves +VisibilityTimeout+ value for the queue.
216
+ # Returns new timeout value.
217
+ #
218
+ # queue.visibility #=> 30
219
+ #
220
+ def visibility
221
+ @sqs.interface.get_visibility_timeout(@url)
222
+ end
223
+
224
+ # Sets new +VisibilityTimeout+ for the queue.
225
+ # Returns new timeout value.
226
+ #
227
+ # queue.visibility #=> 30
228
+ # queue.visibility = 33
229
+ # queue.visibility #=> 33
230
+ #
231
+ def visibility=(visibility_timeout)
232
+ @sqs.interface.set_visibility_timeout(@url, visibility_timeout)
233
+ visibility_timeout
234
+ end
235
+
236
+ # Sets new queue attribute value.
237
+ # Not all attributes may be changed: +ApproximateNumberOfMessages+ (for example) is a read only attribute.
238
+ # Returns a value to be assigned to attribute.
239
+ #
240
+ # queue.set_attribute('VisibilityTimeout', '100') #=> '100'
241
+ # queue.get_attribute('VisibilityTimeout') #=> '100'
242
+ #
243
+ def set_attribute(attribute, value)
244
+ @sqs.interface.set_queue_attributes(@url, attribute, value)
245
+ value
246
+ end
247
+
248
+ # Retrieves queue attributes.
249
+ # At this moment Amazon supports +VisibilityTimeout+ and +ApproximateNumberOfMessages+ only.
250
+ # If the name of attribute is set, returns its value. Otherwise, returns a hash of attributes.
251
+ #
252
+ # queue.get_attribute('VisibilityTimeout') #=> '100'
253
+ #
254
+ def get_attribute(attribute='All')
255
+ attributes = @sqs.interface.get_queue_attributes(@url, attribute)
256
+ attribute=='All' ? attributes : attributes[attribute]
257
+ end
258
+
259
+ # Retrieves a list of grantees.
260
+ # Returns an +array+ of Grantee instances if the +grantee_email_address+ is unset.
261
+ # Otherwise returns a Grantee instance that points to +grantee_email_address+ or +nil+.
262
+ #
263
+ # grantees = queue.grantees #=> [#<RightAws::Sqs::Grantee:0xb7bf0888 ... >, ...]
264
+ # ...
265
+ # grantee = queue.grantees('cool_guy@email.address') #=> nil | #<RightAws::Sqs::Grantee:0xb7bf0888 ... >
266
+ #
267
+ def grantees(grantee_email_address=nil, permission = nil)
268
+ hash = @sqs.interface.list_grants(@url, grantee_email_address, permission)
269
+ grantees = []
270
+ hash.each do |key, value|
271
+ grantees << Grantee.new(self, grantee_email_address, key, value[:name], value[:perms])
272
+ end
273
+ if grantee_email_address
274
+ grantees.blank? ? nil : grantees.shift
275
+ else
276
+ grantees
277
+ end
278
+ end
279
+ end
280
+
281
+
282
+ class Message
283
+ attr_reader :queue, :id, :body, :visibility
284
+ attr_accessor :sent_at, :received_at
285
+
286
+ def initialize(queue, id=nil, body=nil, visibility=nil)
287
+ @queue = queue
288
+ @id = id
289
+ @body = body
290
+ @visibility = visibility
291
+ @sent_at = nil
292
+ @received_at = nil
293
+ end
294
+
295
+ # Returns +Message+ instance body.
296
+ def to_s
297
+ @body
298
+ end
299
+
300
+ # Changes +VisibilityTimeout+ for current message.
301
+ # Returns new +VisibilityTimeout+ value.
302
+ def visibility=(visibility_timeout)
303
+ @queue.sqs.interface.change_message_visibility(@queue.url, @id, visibility_timeout)
304
+ @visibility = visibility_timeout
305
+ end
306
+
307
+ # Removes message from queue.
308
+ # Returns +true+.
309
+ def delete
310
+ @queue.sqs.interface.delete_message(@queue.url, @id)
311
+ end
312
+ end
313
+
314
+
315
+ class Grantee
316
+ attr_accessor :queue, :id, :name, :perms, :email
317
+
318
+ # Creates new Grantee instance.
319
+ # To create new grantee for queue use:
320
+ #
321
+ # grantee = Grantee.new(queue, grantee@email.address)
322
+ # grantee.grant('FULLCONTROL')
323
+ #
324
+ def initialize(queue, email=nil, id=nil, name=nil, perms=[])
325
+ @queue = queue
326
+ @id = id
327
+ @name = name
328
+ @perms = perms
329
+ @email = email
330
+ retrieve unless id
331
+ end
332
+
333
+ # Retrieves security information for grantee identified by email.
334
+ # Returns +nil+ if the named user has no privileges on this queue, or
335
+ # +true+ if perms updated successfully.
336
+ def retrieve # :nodoc:
337
+ @id = nil
338
+ @name = nil
339
+ @perms = []
340
+
341
+ hash = @queue.sqs.interface.list_grants(@queue.url, @email)
342
+ return nil if hash.empty?
343
+
344
+ grantee = hash.shift
345
+ @id = grantee[0]
346
+ @name = grantee[1][:name]
347
+ @perms = grantee[1][:perms]
348
+ true
349
+ end
350
+
351
+ # Adds permissions for grantee.
352
+ # Permission: 'FULLCONTROL' | 'RECEIVEMESSAGE' | 'SENDMESSAGE'.
353
+ # The caller must have set the email instance variable.
354
+ def grant(permission=nil)
355
+ raise "You can't grant permission without defining a grantee email address!" unless @email
356
+ @queue.sqs.interface.add_grant(@queue.url, @email, permission)
357
+ retrieve
358
+ end
359
+
360
+ # Revokes permissions for grantee.
361
+ # Permission: 'FULLCONTROL' | 'RECEIVEMESSAGE' | 'SENDMESSAGE'.
362
+ # Default value is 'FULLCONTROL'.
363
+ # User must have +@email+ or +@id+ set.
364
+ # Returns +true+.
365
+ def revoke(permission='FULLCONTROL')
366
+ @queue.sqs.interface.remove_grant(@queue.url, @email || @id, permission)
367
+ unless @email # if email is unknown - just remove permission from local perms list...
368
+ @perms.delete(permission)
369
+ else # ... else retrieve updated information from Amazon
370
+ retrieve
371
+ end
372
+ true
373
+ end
374
+
375
+ # Revokes all permissions for this grantee.
376
+ # Returns +true+
377
+ def drop
378
+ @perms.each do |permission|
379
+ @queue.sqs.interface.remove_grant(@queue.url, @email || @id, permission)
380
+ end
381
+ retrieve
382
+ true
383
+ end
384
+
385
+ end
386
+
387
+ end
388
+ end
@@ -0,0 +1,343 @@
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
+ # :multi_thread => true|false # Multi-threaded (connection per each thread): true or false (default)
64
+ # :signature_version => '0' # The signature version : '0' or '1'(default)
65
+ # :logger => Logger Object} # Logger instance: logs to STDOUT if omitted }
66
+ class SqsGen2
67
+ attr_reader :interface
68
+
69
+ def initialize(aws_access_key_id=nil, aws_secret_access_key=nil, params={})
70
+ @interface = SqsGen2Interface.new(aws_access_key_id, aws_secret_access_key, params)
71
+ end
72
+
73
+ # Retrieves a list of queues.
74
+ # Returns an +array+ of +Queue+ instances.
75
+ #
76
+ # RightAws::Sqs.queues #=> array of queues
77
+ #
78
+ def queues(prefix=nil)
79
+ @interface.list_queues(prefix).map do |url|
80
+ Queue.new(self, url)
81
+ end
82
+ end
83
+
84
+ # Returns Queue instance by queue name.
85
+ # If the queue does not exist at Amazon SQS and +create+ is true, the method creates it.
86
+ #
87
+ # RightAws::SqsGen2.queue('my_awesome_queue') #=> #<RightAws::SqsGen2::Queue:0xb7b626e4 ... >
88
+ #
89
+ def queue(queue_name, create=true, visibility=nil)
90
+ url = @interface.queue_url_by_name(queue_name)
91
+ url = (create ? @interface.create_queue(queue_name, visibility) : nil) unless url
92
+ url ? Queue.new(self, url) : nil
93
+ end
94
+
95
+
96
+ class Queue
97
+ attr_reader :name, :url, :sqs
98
+
99
+ # Returns Queue instance by queue name.
100
+ # If the queue does not exist at Amazon SQS and +create+ is true, the method creates it.
101
+ #
102
+ # RightAws::SqsGen2::Queue.create(sqs, 'my_awesome_queue') #=> #<RightAws::SqsGen2::Queue:0xb7b626e4 ... >
103
+ #
104
+ def self.create(sqs, url_or_name, create=true, visibility=nil)
105
+ sqs.queue(url_or_name, create, visibility)
106
+ end
107
+
108
+ # Creates new Queue instance.
109
+ # Does not create a queue at Amazon.
110
+ #
111
+ # queue = RightAws::SqsGen2::Queue.new(sqs, 'my_awesome_queue')
112
+ #
113
+ def initialize(sqs, url_or_name)
114
+ @sqs = sqs
115
+ @url = @sqs.interface.queue_url_by_name(url_or_name)
116
+ @name = @sqs.interface.queue_name_by_url(@url)
117
+ end
118
+
119
+ # Retrieves queue size.
120
+ #
121
+ # queue.size #=> 1
122
+ #
123
+ def size
124
+ @sqs.interface.get_queue_length(@url)
125
+ end
126
+
127
+ # Clears queue, deleting only the visible messages. Any message within its visibility
128
+ # timeout will not be deleted, and will re-appear in the queue in the
129
+ # future when the timeout expires.
130
+ #
131
+ # To delete all messages in a queue and eliminate the chance of any
132
+ # messages re-appearing in the future, it's best to delete the queue and
133
+ # re-create it as a new queue. Note that doing this will take at least 60
134
+ # s since SQS does not allow re-creation of a queue within this interval.
135
+ #
136
+ # queue.clear() #=> true
137
+ #
138
+ def clear()
139
+ @sqs.interface.clear_queue(@url)
140
+ end
141
+
142
+ # Deletes queue. Any messages in the queue will be permanently lost.
143
+ # Returns +true+.
144
+ #
145
+ # NB: Use with caution; severe data loss is possible!
146
+ #
147
+ # queue.delete(true) #=> true
148
+ #
149
+ def delete(force=false)
150
+ @sqs.interface.delete_queue(@url)
151
+ end
152
+
153
+ # Sends new message to queue.
154
+ # Returns new Message instance that has been sent to queue.
155
+ def send_message(message)
156
+ message = message.to_s
157
+ res = @sqs.interface.send_message(@url, message)
158
+ msg = Message.new(self, res['MessageId'], nil, message)
159
+ msg.send_checksum = res['MD5OfMessageBody']
160
+ msg.sent_at = Time.now
161
+ msg
162
+ end
163
+ alias_method :push, :send_message
164
+
165
+ # Retrieves several messages from queue.
166
+ # Returns an array of Message instances.
167
+ #
168
+ # queue.receive_messages(2,10) #=> array of messages
169
+ #
170
+ def receive_messages(number_of_messages=1, visibility=nil, attributes=nil)
171
+ list = @sqs.interface.receive_message(@url, number_of_messages, visibility, attributes)
172
+ list.map! do |entry|
173
+ msg = Message.new(self, entry['MessageId'], entry['ReceiptHandle'], entry['Body'], visibility, entry['Attributes'])
174
+ msg.received_at = Time.now
175
+ msg.receive_checksum = entry['MD5OfBody']
176
+ msg
177
+ end
178
+ end
179
+
180
+ # Retrieves first accessible message from queue.
181
+ # Returns Message instance or +nil+ it the queue is empty.
182
+ #
183
+ # queue.receive #=> #<RightAws::SqsGen2::Message:0xb7bf0884 ... >
184
+ #
185
+ def receive(visibility=nil, attributes=nil)
186
+ list = receive_messages(1, visibility, attributes)
187
+ list.empty? ? nil : list[0]
188
+ end
189
+
190
+ # Pops (and deletes) first accessible message from queue.
191
+ # Returns Message instance or +nil+ if the queue is empty.
192
+ #
193
+ # queue.pop #=> #<RightAws::SqsGen2::Message:0xb7bf0884 ... >
194
+ #
195
+ # # pop a message with custom attributes
196
+ # m = queue.pop(['SenderId', 'SentTimestamp']) #=> #<RightAws::SqsGen2::Message:0xb7bf1884 ... >
197
+ # m.attributes #=> {"SentTimestamp"=>"1240991906937", "SenderId"=>"800000000005"}
198
+ #
199
+ def pop(attributes=nil)
200
+ list = @sqs.interface.pop_messages(@url, 1, attributes)
201
+ return nil if list.empty?
202
+ entry = list[0]
203
+ msg = Message.new(self, entry['MessageId'], entry['ReceiptHandle'], entry['Body'], visibility, entry['Attributes'])
204
+ msg.received_at = Time.now
205
+ msg.receive_checksum = entry['MD5OfBody']
206
+ msg
207
+ end
208
+
209
+ # Retrieves +VisibilityTimeout+ value for the queue.
210
+ # Returns new timeout value.
211
+ #
212
+ # queue.visibility #=> 30
213
+ #
214
+ def visibility
215
+ @sqs.interface.get_queue_attributes(@url, 'VisibilityTimeout')['VisibilityTimeout']
216
+ end
217
+
218
+ # Sets new +VisibilityTimeout+ for the queue.
219
+ # Returns new timeout value.
220
+ #
221
+ # queue.visibility #=> 30
222
+ # queue.visibility = 33
223
+ # queue.visibility #=> 33
224
+ #
225
+ def visibility=(visibility_timeout)
226
+ @sqs.interface.set_queue_attributes(@url, 'VisibilityTimeout', visibility_timeout)
227
+ visibility_timeout
228
+ end
229
+
230
+ # Sets new queue attribute value.
231
+ # Not all attributes may be changed: +ApproximateNumberOfMessages+ (for example) is a read only attribute.
232
+ # Returns a value to be assigned to attribute.
233
+ # Currently, 'VisibilityTimeout' is the only settable queue attribute.
234
+ # Attempting to set non-existent attributes generates an indignant
235
+ # exception.
236
+ #
237
+ # queue.set_attribute('VisibilityTimeout', '100') #=> '100'
238
+ # queue.get_attribute('VisibilityTimeout') #=> '100'
239
+ #
240
+ def set_attribute(attribute, value)
241
+ @sqs.interface.set_queue_attributes(@url, attribute, value)
242
+ value
243
+ end
244
+
245
+ # Retrieves queue attributes.
246
+ # If the name of attribute is set, returns its value. Otherwise, returns a hash of attributes.
247
+ #
248
+ # queue.get_attribute('VisibilityTimeout') #=> {"VisibilityTimeout"=>"45"}
249
+ #
250
+ # P.S. This guy is deprecated. Use +get_attributes+ instead.
251
+ def get_attribute(attribute='All')
252
+ attributes = get_attributes(attribute)
253
+ attribute=='All' ? attributes : attributes[attribute]
254
+ end
255
+
256
+ # Retrieves queue attributes.
257
+ #
258
+ # queue.get_attributes #=>
259
+ # {"ApproximateNumberOfMessages" => "0",
260
+ # "LastModifiedTimestamp" => "1240946032",
261
+ # "CreatedTimestamp" => "1240816887",
262
+ # "VisibilityTimeout" => "30",
263
+ # "Policy" => "{"Version":"2008-10-17","Id":...}"}
264
+ #
265
+ # queue.get_attributes("LastModifiedTimestamp", "VisibilityTimeout") #=>
266
+ # {"LastModifiedTimestamp" => "1240946032",
267
+ # "VisibilityTimeout" => "30"}
268
+ #
269
+ def get_attributes(*attributes)
270
+ @sqs.interface.get_queue_attributes(@url, attributes)
271
+ end
272
+
273
+ # Add permission to the queue.
274
+ #
275
+ # queue.add_permissions('testLabel',['125074342641', '125074342642'],
276
+ # ['SendMessage','SendMessage','ReceiveMessage']) #=> true
277
+ #
278
+ def add_permissions(label, grantees, actions)
279
+ @sqs.interface.add_permissions(@url, label, grantees, actions)
280
+ end
281
+
282
+ # Revoke any permissions in the queue policy that matches the +label+ parameter.
283
+ #
284
+ # sqs.remove_permissions('testLabel') # => true
285
+ #
286
+ def remove_permissions(label)
287
+ @sqs.interface.remove_permissions(@url, label)
288
+ end
289
+
290
+ # Get current permissions set. The set is JSON packed.
291
+ #
292
+ # sqs.get_permissions #=>
293
+ # '{"Version":"2008-10-17","Id":"/826693181925/kd-test-gen-2_5/SQSDefaultPolicy",
294
+ # "Statement":[{"Sid":"kd-perm-04","Effect":"Allow","Principal":{"AWS":"100000000001",
295
+ # "AWS":"100000000001","AWS":"100000000002"},"Action":["SQS:SendMessage","SQS:DeleteMessage",
296
+ # "SQS:ReceiveMessage"],"Resource":"/826693181925/kd-test-gen-2_5"},{"Sid":"kd-perm-03",
297
+ # "Effect":"Allow","Principal":{"AWS":"648772224137"},"Action":"SQS:SendMessage",
298
+ # "Resource":"/826693181925/kd-test-gen-2_5"}]}'
299
+ #
300
+ def get_permissions
301
+ get_attributes('Policy')['Policy']
302
+ end
303
+
304
+ end
305
+
306
+ class Message
307
+ attr_reader :queue, :id, :body, :visibility, :receipt_handle, :attributes
308
+ attr_accessor :sent_at, :received_at, :send_checksum, :receive_checksum
309
+
310
+ def initialize(queue, id=nil, rh = nil, body=nil, visibility=nil, attributes=nil)
311
+ @queue = queue
312
+ @id = id
313
+ @receipt_handle = rh
314
+ @body = body
315
+ @visibility = visibility
316
+ @attributes = attributes
317
+ @sent_at = nil
318
+ @received_at = nil
319
+ @send_checksum = nil
320
+ @receive_checksum = nil
321
+ end
322
+
323
+ # Returns +Message+ instance body.
324
+ def to_s
325
+ @body
326
+ end
327
+
328
+ # Set message visibility timeout.
329
+ def visibility=(visibility_timeout)
330
+ @queue.sqs.interface.change_message_visibility(@queue.url, @receipt_handle, visibility_timeout)
331
+ @visibility = visibility_timeout
332
+ end
333
+
334
+ # Removes message from queue.
335
+ # Returns +true+.
336
+ def delete
337
+ @queue.sqs.interface.delete_message(@queue.url, @receipt_handle) if @receipt_handle
338
+ end
339
+
340
+ end
341
+
342
+ end
343
+ end