SQS 0.1.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.
- data/MIT-LICENSE +20 -0
- data/README +3 -0
- data/lib/sqs.rb +294 -0
- data/lib/sqs/grant.rb +34 -0
- data/lib/sqs/message.rb +43 -0
- data/lib/sqs/queue.rb +179 -0
- data/test/all_tests.rb +6 -0
- data/test/unit/sqs_grant_test.rb +67 -0
- data/test/unit/sqs_message_test.rb +81 -0
- data/test/unit/sqs_queue_test.rb +312 -0
- data/test/unit/sqs_test.rb +341 -0
- data/test/unit/test_setup.rb +51 -0
- metadata +63 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2006 Zachary Holt
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
data/lib/sqs.rb
ADDED
@@ -0,0 +1,294 @@
|
|
1
|
+
#!/usr/local/bin/ruby
|
2
|
+
|
3
|
+
dir = File::dirname( __FILE__ )
|
4
|
+
|
5
|
+
#require "#{dir}/aws"
|
6
|
+
require 'base64'
|
7
|
+
require 'erb'
|
8
|
+
require 'net/http'
|
9
|
+
require 'openssl'
|
10
|
+
require 'rexml/document'
|
11
|
+
#include Digest
|
12
|
+
include ERB::Util
|
13
|
+
include OpenSSL
|
14
|
+
include REXML
|
15
|
+
|
16
|
+
|
17
|
+
class SQS
|
18
|
+
|
19
|
+
dir = File.dirname( __FILE__ )
|
20
|
+
require "#{dir}/sqs/queue"
|
21
|
+
require "#{dir}/sqs/message"
|
22
|
+
require "#{dir}/sqs/grant"
|
23
|
+
|
24
|
+
|
25
|
+
def self.new
|
26
|
+
# rather than a singleton class, never allow instantiation
|
27
|
+
return SQS
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.prepare_parameters_for_signing( hsh={} )
|
31
|
+
# Param-name1Param-value1Param-name2Param-value2...Param-nameNParam-valueN
|
32
|
+
# see http://docs.amazonwebservices.com/AWSSimpleQueueService/2006-04-01/Query/QueryAuth.html
|
33
|
+
hsh.keys.sort{ |a,b| a.to_s.casecmp( b.to_s ) }.map{ |a| "#{a.to_s}#{hsh[a].to_s}"}.join( '' )
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.prepare_parameters_for_query( hsh={} )
|
37
|
+
# Param-name1Param-value1Param-name2Param-value2...Param-nameNParam-valueN
|
38
|
+
# see http://docs.amazonwebservices.com/AWSSimpleQueueService/2006-04-01/Query/QueryAuth.html
|
39
|
+
hsh.keys.map{ |a| "#{url_encode( a.to_s )}=#{url_encode( hsh[a].to_s )}"}.join( '&' )
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.access_key_id=( i )
|
43
|
+
@@access_key_id = i
|
44
|
+
end
|
45
|
+
def self.access_key_id
|
46
|
+
@@access_key_id
|
47
|
+
end
|
48
|
+
def self.secret_access_key=( k )
|
49
|
+
@@secret_access_key = k
|
50
|
+
end
|
51
|
+
def self.secret_access_key
|
52
|
+
@@secret_access_key
|
53
|
+
end
|
54
|
+
def self.url_for_auery=( u )
|
55
|
+
@@url_for_query = u
|
56
|
+
end
|
57
|
+
def self.url_for_query
|
58
|
+
@@url_for_query
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.create_signature( params )
|
62
|
+
prepared_parameters = self.prepare_parameters_for_signing( params )
|
63
|
+
digest = OpenSSL::HMAC::digest( OpenSSL::Digest::Digest.new("SHA1"), self.secret_access_key, prepared_parameters )
|
64
|
+
b64_hmac = Base64.encode64( digest ).strip
|
65
|
+
b64_hmac
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.permissions( perm=nil )
|
69
|
+
perms = { :full => 'FULLCONTROL', :send => 'SENDMESSAGE', :receive => 'RECEIVEMESSAGE' }
|
70
|
+
if perm.nil?
|
71
|
+
perms
|
72
|
+
else
|
73
|
+
perms.has_value?( perm.to_s.upcase ) ? perm.to_s.upcase : perms[perm.to_sym]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.create_queue( params={} )
|
78
|
+
params = params.is_a?( Hash ) ? params : { :name => params }
|
79
|
+
params[:Action] = 'CreateQueue'
|
80
|
+
return false if params[:name].to_s.empty?
|
81
|
+
params[:QueueName] = params[:name]
|
82
|
+
params.delete( :name )
|
83
|
+
|
84
|
+
doc = self.call_web_service( params )
|
85
|
+
queue_url = doc.queue_url
|
86
|
+
SQS::Queue.new( :url => queue_url )
|
87
|
+
|
88
|
+
rescue Exception => e
|
89
|
+
raise e
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
|
94
|
+
def self.get_queue( params={} )
|
95
|
+
params = params.is_a?( Hash ) ? params : { :name => params }
|
96
|
+
self.list_queues( :prefix => params[:name] ).each do |queue|
|
97
|
+
return queue if queue.name == params[:name]
|
98
|
+
end
|
99
|
+
|
100
|
+
raise "Could not find the queue named '#{params[:name]}'"
|
101
|
+
rescue Exception => e
|
102
|
+
raise e
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
def self.list_queues( params={} )
|
107
|
+
# use :prefix => 'Boo' to get queues whose names begin with 'Boo'
|
108
|
+
params = params.is_a?( Hash ) ? params : { }
|
109
|
+
params[:Action] = 'ListQueues'
|
110
|
+
if ( params.has_key?( :prefix ) )
|
111
|
+
params[:QueueNamePrefix] = params[:prefix]
|
112
|
+
params.delete( :prefix )
|
113
|
+
end
|
114
|
+
|
115
|
+
doc = self.call_web_service( params )
|
116
|
+
queues = Array.new()
|
117
|
+
|
118
|
+
begin
|
119
|
+
XPath.each( doc, '/ListQueuesResponse/QueueUrl' ) do |element|
|
120
|
+
queues << SQS::Queue.new( :url => element.text )
|
121
|
+
end
|
122
|
+
rescue RuntimeError => e
|
123
|
+
queues = Array.new()
|
124
|
+
end
|
125
|
+
queues
|
126
|
+
rescue Exception => e
|
127
|
+
raise e
|
128
|
+
end
|
129
|
+
|
130
|
+
def self.each_queue( params={}, &block )
|
131
|
+
self.list_queues( params ).each do |q|
|
132
|
+
block.call( q )
|
133
|
+
end
|
134
|
+
rescue Exception => e
|
135
|
+
raise e
|
136
|
+
end
|
137
|
+
|
138
|
+
|
139
|
+
|
140
|
+
def self.api_version
|
141
|
+
'2006-04-01'
|
142
|
+
end
|
143
|
+
|
144
|
+
def self.signature_version
|
145
|
+
1
|
146
|
+
end
|
147
|
+
|
148
|
+
def self.request_ttl
|
149
|
+
30
|
150
|
+
end
|
151
|
+
|
152
|
+
def self.retry_attempts
|
153
|
+
10
|
154
|
+
end
|
155
|
+
|
156
|
+
def self.params_for_query( t=nil )
|
157
|
+
expires = t.is_a?( Time ) ? t : Time.now.request_expires
|
158
|
+
|
159
|
+
{
|
160
|
+
:DefaultVisibilityTimeout => SQS::Queue.default_visibility_timeout,
|
161
|
+
:Version => self.api_version,
|
162
|
+
:AWSAccessKeyId => self.access_key_id,
|
163
|
+
:SignatureVersion => self.signature_version,
|
164
|
+
:Expires => expires.to_iso8601
|
165
|
+
}
|
166
|
+
end
|
167
|
+
|
168
|
+
def self.counter
|
169
|
+
@@counter
|
170
|
+
end
|
171
|
+
def self.reset_counter
|
172
|
+
@@counter = 0
|
173
|
+
end
|
174
|
+
def self.increment_counter
|
175
|
+
@@counter += 1
|
176
|
+
end
|
177
|
+
protected
|
178
|
+
@@counter = 0;
|
179
|
+
@@secret_access_key = 'Replace this with your secret access key'
|
180
|
+
@@access_key_id = 'Replace this with your access key id'
|
181
|
+
@@url_for_query = 'http://queue.amazonaws.com/'
|
182
|
+
|
183
|
+
|
184
|
+
def self.reasons_not_to_retry
|
185
|
+
[ 'Success', 'InvalidParameterValue' ]
|
186
|
+
end
|
187
|
+
|
188
|
+
def self.call_web_service( params )
|
189
|
+
params = self.params_for_query.merge( params )
|
190
|
+
|
191
|
+
begin
|
192
|
+
retries = params[:retries] + 0
|
193
|
+
params.delete( :retries )
|
194
|
+
retries = 1 if retries < 1
|
195
|
+
rescue
|
196
|
+
retries = self.retry_attempts
|
197
|
+
end
|
198
|
+
|
199
|
+
if !params[:queue].nil? && params[:queue].respond_to?( :url )
|
200
|
+
url = params[:queue].url
|
201
|
+
params.delete( :queue )
|
202
|
+
else
|
203
|
+
url = "#{self.url_for_query}"
|
204
|
+
end
|
205
|
+
url += "?#{self.prepare_parameters_for_query( params )}&Signature="
|
206
|
+
|
207
|
+
url_encoded_signature = url_encode( self.create_signature( params ) )
|
208
|
+
response = Net::HTTP.get( URI.parse( url + url_encoded_signature ) )
|
209
|
+
self.increment_counter
|
210
|
+
doc = Document.new( response )
|
211
|
+
status = doc.status
|
212
|
+
|
213
|
+
unless status == 'Success'
|
214
|
+
error_code = doc.error_code
|
215
|
+
error_message = doc.error_message
|
216
|
+
case error_code
|
217
|
+
when 'AuthFailure', 'InvalidParameterValue', 'AWS.SimpleQueueService.NonEmptyQueue'
|
218
|
+
raise( "#{error_code}: #{error_message} (#{url}#{url_encoded_signature})" )
|
219
|
+
else
|
220
|
+
raise( "Unknown Error: #{doc} (#{url}#{url_encoded_signature})" )
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
doc
|
225
|
+
rescue Exception => e
|
226
|
+
raise e.is_a?( SocketError ) ? "Do you have internet access? (#{e.message})" : e
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
class Time
|
231
|
+
def to_iso8601
|
232
|
+
self.utc.strftime( "%Y-%m-%dT%H:%M:%SZ" )
|
233
|
+
end
|
234
|
+
|
235
|
+
def request_expires
|
236
|
+
self + SQS.request_ttl
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
module REXML
|
241
|
+
class Document
|
242
|
+
|
243
|
+
def error_code ; self.node_text( '/Response/Errors/Error/Code' ) ; end
|
244
|
+
def error_message ; self.node_text( '/Response/Errors/Error/Message' ) ; end
|
245
|
+
def request_id ; self.node_text( '*/ResponseStatus/RequestId' ) ; end
|
246
|
+
|
247
|
+
def queue_url ; self.node_text( '/CreateQueueResponse/QueueUrl' ) ; end
|
248
|
+
def status ; self.node_text( '*/ResponseStatus/StatusCode' ) ; end
|
249
|
+
|
250
|
+
def message_id( type=:send ) ; self.node_text( "/#{type.to_s.capitalize}MessageResponse/#{ type == :send ? '' : 'Message/'}MessageId" ) ; end
|
251
|
+
def message_body( type=:peek ) ; self.node_text( "/#{type.to_s.capitalize}MessageResponse/Message/MessageBody" ) ; end
|
252
|
+
|
253
|
+
def messages( type=:receive ) ; self.nodes( "/#{type.to_s.capitalize}MessageResponse#{ type == :send ? '' : '/Message'}" ) ; end
|
254
|
+
|
255
|
+
def visibility_timeout( type=:get ) ; self.node_text( "/#{type.to_s.capitalize}VisibilityTimeoutResponse/VisibilityTimeout" ).to_i ; end
|
256
|
+
|
257
|
+
def grant_lists( type=:list ) ; self.nodes("/#{type.to_s.capitalize}GrantsResponse#{ type == :send ? '' : '/GrantList'}" ) ; end
|
258
|
+
|
259
|
+
protected
|
260
|
+
def node_text( xpath )
|
261
|
+
code = XPath.first( self, xpath )
|
262
|
+
code.to_s.empty? ? '' : code.text
|
263
|
+
end
|
264
|
+
|
265
|
+
def nodes( xpath )
|
266
|
+
XPath.match( self, xpath )
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
|
271
|
+
class Element
|
272
|
+
def message_id ; self.node_text( "MessageId" ) ; end
|
273
|
+
def message_body ; self.node_text( "MessageBody" ) ; end
|
274
|
+
|
275
|
+
def id( type=:message ) ; self.node_text( type == :grantee ? "ID" : "Id" ) ; end
|
276
|
+
def display_name ; self.node_text( "DisplayName" ) ; end
|
277
|
+
def permission ; self.node_text( "Permission" ) ; end
|
278
|
+
|
279
|
+
def grantees( type=:list ) ; self.nodes("Grantee" ) ; end
|
280
|
+
|
281
|
+
protected
|
282
|
+
def node_text( xpath )
|
283
|
+
code = XPath.first( self, xpath )
|
284
|
+
code.to_s.empty? ? '' : code.text
|
285
|
+
end
|
286
|
+
|
287
|
+
def nodes( xpath )
|
288
|
+
XPath.match( self, xpath )
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
end
|
293
|
+
|
294
|
+
Dir[File.join( File.join( File.dirname( __FILE__ ), 'sqs' ), "*.rb" )].each { |f| require f }
|
data/lib/sqs/grant.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
|
2
|
+
class SQS::Grant
|
3
|
+
def self.atts
|
4
|
+
[:email, :display_name, :id, :_permission]
|
5
|
+
end
|
6
|
+
|
7
|
+
self.atts.each do |att|
|
8
|
+
attr_accessor att
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize( options={} )
|
12
|
+
if options.is_a?( Hash )
|
13
|
+
SQS::Grant.atts.each do |thing|
|
14
|
+
self.send "#{thing}=", options[thing.to_s =~ /^_(.*)$/ ? $1.to_sym : thing]
|
15
|
+
end
|
16
|
+
else
|
17
|
+
self.email = options
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def permission
|
22
|
+
self._permission
|
23
|
+
end
|
24
|
+
|
25
|
+
def permission=( p )
|
26
|
+
if SQS.permissions.has_key?( p.to_s.to_sym )
|
27
|
+
self._permission = SQS.permissions[p.to_s.to_sym]
|
28
|
+
else
|
29
|
+
self._permission = p.to_s.upcase
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
|
data/lib/sqs/message.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
#!/usr/bin/local/ruby
|
2
|
+
|
3
|
+
class SQS::Message
|
4
|
+
attr_accessor :queue, :_body, :id
|
5
|
+
|
6
|
+
def initialize( options={} )
|
7
|
+
self.body = options.is_a?( Hash ) ? options[:body] : nil
|
8
|
+
self.queue = options.is_a?( Hash ) ? options[:queue] : nil
|
9
|
+
self.id = options.is_a?( Hash ) ? options[:id] : options.to_s
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
def delete
|
14
|
+
raise "This #{self.class.to_s} cannot be deleted, because there is no associated SQS::Queue" unless self.queue.is_a?( SQS::Queue )
|
15
|
+
raise "Cannot delete a message with no id." if self.id.to_s.empty?
|
16
|
+
|
17
|
+
doc = SQS.call_web_service( :Action => 'DeleteMessage', :queue => self.queue, :MessageId => self.id )
|
18
|
+
true
|
19
|
+
rescue Exception => e
|
20
|
+
raise e
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
def peek
|
25
|
+
raise "This #{self.class.to_s} cannot be peeked, because there is no associated SQS::Queue" unless self.queue.is_a?( SQS::Queue )
|
26
|
+
raise "Cannot peek a message with no id." if self.id.to_s.empty?
|
27
|
+
|
28
|
+
doc = SQS.call_web_service( :Action => 'PeekMessage', :queue => self.queue, :MessageId => self.id )
|
29
|
+
self.body = doc.message_body
|
30
|
+
true
|
31
|
+
rescue Exception => e
|
32
|
+
raise e
|
33
|
+
end
|
34
|
+
|
35
|
+
def body
|
36
|
+
self.peek if self._body.to_s.empty?
|
37
|
+
self._body
|
38
|
+
end
|
39
|
+
def body=( b )
|
40
|
+
self._body = b
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
data/lib/sqs/queue.rb
ADDED
@@ -0,0 +1,179 @@
|
|
1
|
+
#!/usr/bin/local/ruby
|
2
|
+
|
3
|
+
require 'uri'
|
4
|
+
require 'rexml/document'
|
5
|
+
include REXML
|
6
|
+
|
7
|
+
class SQS::Queue
|
8
|
+
private
|
9
|
+
@attributes = {}
|
10
|
+
@@acceptable_schemes = ['https', 'http']
|
11
|
+
|
12
|
+
public
|
13
|
+
attr_accessor :url
|
14
|
+
def initialize( options={} )
|
15
|
+
self.url = options.is_a?( Hash ) ? options[:url] : options
|
16
|
+
bad_url = false
|
17
|
+
|
18
|
+
begin
|
19
|
+
u = URI.parse( self.url )
|
20
|
+
bad_url = !@@acceptable_schemes.include?( u.scheme ) || u.host.to_s.empty? || u.path.to_s.empty?
|
21
|
+
rescue URI::InvalidURIError, NoMethodError
|
22
|
+
bad_url = true
|
23
|
+
end
|
24
|
+
raise "'#{self.url}' does not seem to be a parseable URL. (Please provide all parts of the URL.)" if bad_url
|
25
|
+
end
|
26
|
+
|
27
|
+
def ==( other_queue )
|
28
|
+
self.url == other_queue.url
|
29
|
+
rescue
|
30
|
+
false
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_s
|
34
|
+
"#{self.class.to_s} '#{self.name}' (#{self.url})"
|
35
|
+
end
|
36
|
+
|
37
|
+
def delete
|
38
|
+
doc = SQS.call_web_service( :Action => 'DeleteQueue', :queue => self )
|
39
|
+
true
|
40
|
+
rescue Exception => e
|
41
|
+
raise e
|
42
|
+
end
|
43
|
+
|
44
|
+
def force_delete
|
45
|
+
begin
|
46
|
+
self.delete
|
47
|
+
rescue
|
48
|
+
while m = self.receive_message
|
49
|
+
m.delete if m.respond_to?( :delete )
|
50
|
+
end
|
51
|
+
populated = 2
|
52
|
+
while populated > 0
|
53
|
+
begin
|
54
|
+
self.delete
|
55
|
+
populated = 0
|
56
|
+
rescue
|
57
|
+
populated -= 1
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
true
|
62
|
+
rescue Exception => e
|
63
|
+
raise e
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
def send_message( m )
|
68
|
+
doc = SQS.call_web_service( :Action => 'SendMessage', :queue => self, :MessageBody => m.to_s )
|
69
|
+
m = SQS::Message.new( :id => doc.message_id, :queue => self )
|
70
|
+
rescue Exception => e
|
71
|
+
raise e
|
72
|
+
end
|
73
|
+
|
74
|
+
def receive_message
|
75
|
+
# returns the first element of what receive_messages returns
|
76
|
+
m = self.receive_messages( :count => 1 ).first
|
77
|
+
yield( m ) if block_given?
|
78
|
+
m
|
79
|
+
end
|
80
|
+
def receive_messages( options={} )
|
81
|
+
# returns an array of SQS::Message instances (could be empty)
|
82
|
+
count = options.has_key?( :count ) ? options[:count].to_i : 1
|
83
|
+
params = { :Action => 'ReceiveMessage', :queue => self, :NumberOfMessages => count }
|
84
|
+
params[:VisibilityTimeout] = options[:message_ttl] if options.has_key?( :message_ttl )
|
85
|
+
doc = SQS.call_web_service( params )
|
86
|
+
|
87
|
+
messages = Array.new
|
88
|
+
doc.messages.each do |m|
|
89
|
+
messages << SQS::Message.new( :id => m.message_id, :queue => self, :body => m.message_body)
|
90
|
+
end
|
91
|
+
messages
|
92
|
+
rescue Exception => e
|
93
|
+
raise e
|
94
|
+
end
|
95
|
+
|
96
|
+
def visibility_timeout=( timeout )
|
97
|
+
doc = SQS.call_web_service( :Action => 'SetVisibilityTimeout', :queue => self, :VisibilityTimeout => timeout.to_i )
|
98
|
+
true
|
99
|
+
rescue Exception => e
|
100
|
+
raise e
|
101
|
+
end
|
102
|
+
def visibility_timeout
|
103
|
+
doc = SQS.call_web_service( :Action => 'GetVisibilityTimeout', :queue => self )
|
104
|
+
doc.visibility_timeout.to_i
|
105
|
+
rescue Exception => e
|
106
|
+
raise e
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
|
111
|
+
def add_grant( options={} )
|
112
|
+
doc = SQS.call_web_service(
|
113
|
+
:Action => 'AddGrant',
|
114
|
+
:queue => self,
|
115
|
+
:Permission => SQS.permissions[options[:permission]],
|
116
|
+
'Grantee.EmailAddress'.to_sym => options[:email].respond_to?( :email ) ? options[:email].email : options[:email]
|
117
|
+
)
|
118
|
+
true
|
119
|
+
rescue Exception => e
|
120
|
+
raise e
|
121
|
+
end
|
122
|
+
|
123
|
+
def remove_grant( options={} )
|
124
|
+
params = {
|
125
|
+
:Action => 'RemoveGrant',
|
126
|
+
:queue => self,
|
127
|
+
:Permission => SQS.permissions( options[:permission] ),
|
128
|
+
}
|
129
|
+
|
130
|
+
if !options[:id].nil?
|
131
|
+
params['Grantee.ID'.to_sym] = options[:id].respond_to?( :id ) && !options[:id].is_a?( String ) ? options[:id].id : options[:id]
|
132
|
+
elsif !options[:email].nil?
|
133
|
+
params['Grantee.EmailAddress'.to_sym] = options[:email].respond_to?( :email ) ? options[:email].email : options[:email]
|
134
|
+
else
|
135
|
+
raise "You must specify either a grant id (:id) or a grantee email address (:email) when calling remove_grant."
|
136
|
+
end
|
137
|
+
|
138
|
+
doc = SQS.call_web_service( params )
|
139
|
+
true
|
140
|
+
rescue Exception => e
|
141
|
+
raise e
|
142
|
+
end
|
143
|
+
|
144
|
+
def list_grants
|
145
|
+
doc = SQS.call_web_service( :Action => 'ListGrants', :queue => self )
|
146
|
+
grants = Array.new
|
147
|
+
doc.grant_lists.each do |list|
|
148
|
+
list.grantees.each do |g|
|
149
|
+
grants << SQS::Grant.new( :id => g.id( :grantee ), :display_name => g.display_name, :permission => list.permission )
|
150
|
+
end
|
151
|
+
end
|
152
|
+
grants
|
153
|
+
rescue Exception => e
|
154
|
+
raise e
|
155
|
+
end
|
156
|
+
|
157
|
+
def each_grant( &block )
|
158
|
+
self.list_grants.each do |g|
|
159
|
+
block.call( g )
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def name
|
164
|
+
# return everything after the last slash
|
165
|
+
self.url =~ /([^\/]*)$/ ? $1 : ''
|
166
|
+
end
|
167
|
+
|
168
|
+
def self.default_visibility_timeout
|
169
|
+
30
|
170
|
+
end
|
171
|
+
|
172
|
+
def exist?
|
173
|
+
SQS.get_queue( self.name )
|
174
|
+
true
|
175
|
+
rescue
|
176
|
+
false
|
177
|
+
end
|
178
|
+
alias_method :exists?, :exist?
|
179
|
+
end
|