redaranj-right_aws 1.10.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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