right_aws 1.9.0 → 3.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.
Files changed (70) hide show
  1. data/History.txt +164 -13
  2. data/Manifest.txt +28 -1
  3. data/README.txt +12 -10
  4. data/Rakefile +56 -29
  5. data/lib/acf/right_acf_interface.rb +343 -172
  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/right_awsbase.rb +755 -115
  12. data/lib/awsbase/support.rb +2 -78
  13. data/lib/awsbase/version.rb +9 -0
  14. data/lib/ec2/right_ec2.rb +274 -1294
  15. data/lib/ec2/right_ec2_ebs.rb +514 -0
  16. data/lib/ec2/right_ec2_images.rb +444 -0
  17. data/lib/ec2/right_ec2_instances.rb +797 -0
  18. data/lib/ec2/right_ec2_monitoring.rb +70 -0
  19. data/lib/ec2/right_ec2_placement_groups.rb +108 -0
  20. data/lib/ec2/right_ec2_reserved_instances.rb +243 -0
  21. data/lib/ec2/right_ec2_security_groups.rb +496 -0
  22. data/lib/ec2/right_ec2_spot_instances.rb +422 -0
  23. data/lib/ec2/right_ec2_tags.rb +139 -0
  24. data/lib/ec2/right_ec2_vpc.rb +598 -0
  25. data/lib/ec2/right_ec2_vpc2.rb +382 -0
  26. data/lib/ec2/right_ec2_windows_mobility.rb +84 -0
  27. data/lib/elb/right_elb_interface.rb +573 -0
  28. data/lib/emr/right_emr_interface.rb +728 -0
  29. data/lib/iam/right_iam_access_keys.rb +71 -0
  30. data/lib/iam/right_iam_groups.rb +195 -0
  31. data/lib/iam/right_iam_interface.rb +341 -0
  32. data/lib/iam/right_iam_mfa_devices.rb +67 -0
  33. data/lib/iam/right_iam_users.rb +251 -0
  34. data/lib/rds/right_rds_interface.rb +1657 -0
  35. data/lib/right_aws.rb +30 -13
  36. data/lib/route_53/right_route_53_interface.rb +641 -0
  37. data/lib/s3/right_s3.rb +108 -41
  38. data/lib/s3/right_s3_interface.rb +349 -118
  39. data/lib/sdb/active_sdb.rb +388 -54
  40. data/lib/sdb/right_sdb_interface.rb +323 -64
  41. data/lib/sns/right_sns_interface.rb +286 -0
  42. data/lib/sqs/right_sqs.rb +1 -2
  43. data/lib/sqs/right_sqs_gen2.rb +73 -17
  44. data/lib/sqs/right_sqs_gen2_interface.rb +146 -73
  45. data/lib/sqs/right_sqs_interface.rb +12 -22
  46. data/right_aws.gemspec +91 -0
  47. data/test/README.mdown +39 -0
  48. data/test/acf/test_right_acf.rb +11 -19
  49. data/test/awsbase/test_helper.rb +2 -0
  50. data/test/awsbase/test_right_awsbase.rb +11 -0
  51. data/test/ec2/test_right_ec2.rb +32 -1
  52. data/test/elb/test_helper.rb +2 -0
  53. data/test/elb/test_right_elb.rb +43 -0
  54. data/test/rds/test_helper.rb +2 -0
  55. data/test/rds/test_right_rds.rb +120 -0
  56. data/test/route_53/fixtures/a_record.xml +18 -0
  57. data/test/route_53/fixtures/alias_record.xml +18 -0
  58. data/test/route_53/test_helper.rb +2 -0
  59. data/test/route_53/test_right_route_53.rb +141 -0
  60. data/test/s3/test_right_s3.rb +176 -42
  61. data/test/s3/test_right_s3_stubbed.rb +6 -4
  62. data/test/sdb/test_active_sdb.rb +120 -19
  63. data/test/sdb/test_batch_put_attributes.rb +54 -0
  64. data/test/sdb/test_right_sdb.rb +71 -16
  65. data/test/sns/test_helper.rb +2 -0
  66. data/test/sns/test_right_sns.rb +153 -0
  67. data/test/sqs/test_right_sqs.rb +0 -6
  68. data/test/sqs/test_right_sqs_gen2.rb +104 -49
  69. data/test/ts_right_aws.rb +1 -0
  70. metadata +181 -22
@@ -38,8 +38,7 @@ module RightAws
38
38
  class SqsGen2Interface < RightAwsBase
39
39
  include RightAwsBaseInterface
40
40
 
41
- SIGNATURE_VERSION = "1"
42
- API_VERSION = "2008-01-01"
41
+ API_VERSION = "2009-02-01"
43
42
  DEFAULT_HOST = "queue.amazonaws.com"
44
43
  DEFAULT_PORT = 443
45
44
  DEFAULT_PROTOCOL = 'https'
@@ -66,14 +65,13 @@ module RightAws
66
65
  # Amazon's article "Migrating to Amazon SQS API version 2008-01-01" at:
67
66
  # http://developer.amazonwebservices.com/connect/entry.jspa?externalID=1148
68
67
  #
69
- # sqs = RightAws::SqsGen2Interface.new('1E3GDYEOGFJPIT75KDT40','hgTHt68JY07JKUY08ftHYtERkjgtfERn57DFE379', {:multi_thread => true, :logger => Logger.new('/tmp/x.log')})
68
+ # sqs = RightAws::SqsGen2Interface.new('1E3GDYEOGFJPIT75KDT40','hgTHt68JY07JKUY08ftHYtERkjgtfERn57DFE379', {:logger => Logger.new('/tmp/x.log')})
70
69
  #
71
70
  # Params is a hash:
72
71
  #
73
72
  # {:server => 'queue.amazonaws.com' # Amazon service host: 'queue.amazonaws.com' (default)
74
73
  # :port => 443 # Amazon service port: 80 or 443 (default)
75
- # :multi_thread => true|false # Multi-threaded (connection per each thread): true or false (default)
76
- # :signature_version => '0' # The signature version : '0' or '1'(default)
74
+ # :signature_version => '0' # The signature version : '0', '1' or '2'(default)
77
75
  # :logger => Logger Object} # Logger instance: logs to STDOUT if omitted }
78
76
  #
79
77
  def initialize(aws_access_key_id=nil, aws_secret_access_key=nil, params={})
@@ -99,18 +97,15 @@ module RightAws
99
97
  # fields required in all requests, and then the headers passed in as
100
98
  # params. We sort the header fields alphabetically and then generate the
101
99
  # signature before URL escaping the resulting query and sending it.
102
- queue_uri = param[:queue_url] ? URI(param[:queue_url]).path : '/'
100
+ service = param[:queue_url] ? URI(param[:queue_url]).path : '/'
103
101
  param.each{ |key, value| param.delete(key) if (value.nil? || key.is_a?(Symbol)) }
104
- request_hash = { "Action" => action,
102
+ service_hash = { "Action" => action,
105
103
  "Expires" => (Time.now + REQUEST_TTL).utc.strftime("%Y-%m-%dT%H:%M:%SZ"),
106
104
  "AWSAccessKeyId" => @aws_access_key_id,
107
- "Version" => API_VERSION,
108
- "SignatureVersion" => SIGNATURE_VERSION }
109
- request_hash.update(param)
110
- request_data = request_hash.sort{|a,b| (a[0].to_s.downcase)<=>(b[0].to_s.downcase)}.to_s
111
- request_hash['Signature'] = AwsUtils::sign(@aws_secret_access_key, request_data)
112
- request_params = request_hash.to_a.collect{|key,val| key.to_s + "=" + val.to_s }.join("&")
113
- request = Net::HTTP::Get.new(AwsUtils.URLencode("#{queue_uri}?#{request_params}"))
105
+ "Version" => API_VERSION }
106
+ service_hash.update(param)
107
+ service_params = signed_service_params(@aws_secret_access_key, service_hash, :get, @params[:server], service)
108
+ request = Net::HTTP::Get.new("#{AwsUtils.URLencode(service)}?#{service_params}")
114
109
  # prepare output hash
115
110
  { :request => request,
116
111
  :server => @params[:server],
@@ -119,22 +114,20 @@ module RightAws
119
114
  end
120
115
 
121
116
  def generate_post_request(action, param={}) # :nodoc:
122
- queue_uri = param[:queue_url] ? URI(param[:queue_url]).path : '/'
117
+ service = param[:queue_url] ? URI(param[:queue_url]).path : '/'
123
118
  message = param[:message] # extract message body if nesessary
124
119
  param.each{ |key, value| param.delete(key) if (value.nil? || key.is_a?(Symbol)) }
125
- request_hash = { "Action" => action,
120
+ service_hash = { "Action" => action,
126
121
  "Expires" => (Time.now + REQUEST_TTL).utc.strftime("%Y-%m-%dT%H:%M:%SZ"),
127
122
  "AWSAccessKeyId" => @aws_access_key_id,
128
123
  "MessageBody" => message,
129
- "Version" => API_VERSION,
130
- "SignatureVersion" => SIGNATURE_VERSION }
131
- request_hash.update(param)
132
- request_data = request_hash.sort{|a,b| (a[0].to_s.downcase)<=>(b[0].to_s.downcase)}.to_s
133
- request_hash['Signature'] = AwsUtils::sign(@aws_secret_access_key, request_data)
134
- request_body = request_hash.to_a.collect{|key,val| CGI.escape(key.to_s) + "=" + CGI.escape(val.to_s) }.join("&")
135
- request = Net::HTTP::Post.new(AwsUtils.URLencode(queue_uri))
136
- request['Content-Type'] = 'application/x-www-form-urlencoded'
137
- request.body = request_body
124
+ "Version" => API_VERSION }
125
+ service_hash.update(param)
126
+ #
127
+ service_params = signed_service_params(@aws_secret_access_key, service_hash, :post, @params[:server], service)
128
+ request = Net::HTTP::Post.new(AwsUtils::URLencode(service))
129
+ request['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8'
130
+ request.body = service_params
138
131
  # prepare output hash
139
132
  { :request => request,
140
133
  :server => @params[:server],
@@ -146,15 +139,12 @@ module RightAws
146
139
  # Sends request to Amazon and parses the response
147
140
  # Raises AwsError if any banana happened
148
141
  def request_info(request, parser) # :nodoc:
149
- thread = @params[:multi_thread] ? Thread.current : Thread.main
150
- thread[:sqs_connection] ||= Rightscale::HttpConnection.new(:exception => AwsError, :logger => @logger)
151
- request_info_impl(thread[:sqs_connection], @@bench, request, parser)
142
+ request_info_impl(:sqs_connection, @@bench, request, parser)
152
143
  end
153
144
 
154
-
155
145
  # Creates a new queue, returning its URI.
156
146
  #
157
- # sqs.create_queue('my_awesome_queue') #=> 'http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue'
147
+ # sqs.create_queue('my_awesome_queue') #=> 'https://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue'
158
148
  #
159
149
  def create_queue(queue_name, default_visibility_timeout=nil)
160
150
  req_hash = generate_request('CreateQueue', 'QueueName' => queue_name,
@@ -170,7 +160,7 @@ module RightAws
170
160
  #
171
161
  # sqs.create_queue('my_awesome_queue')
172
162
  # sqs.create_queue('my_awesome_queue_2')
173
- # sqs.list_queues('my_awesome') #=> ['http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue','http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue_2']
163
+ # sqs.list_queues('my_awesome') #=> ['https://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue','https://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue_2']
174
164
  #
175
165
  def list_queues(queue_name_prefix=nil)
176
166
  req_hash = generate_request('ListQueues', 'QueueNamePrefix' => queue_name_prefix)
@@ -185,11 +175,10 @@ module RightAws
185
175
  # may still show the deleted queue. It is not unusual within the 60 s window to see the deleted queue absent from
186
176
  # one list_queues call but present in the subsequent one. Deletion is eventual.
187
177
  #
188
- # sqs.delete_queue('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue_2') #=> true
189
- #
178
+ # sqs.delete_queue('https://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue_2') #=> true
190
179
  #
191
180
  def delete_queue(queue_url)
192
- req_hash = generate_request('DeleteQueue', :queue_url => queue_url)
181
+ req_hash = generate_request('DeleteQueue', :queue_url => queue_url)
193
182
  request_info(req_hash, SqsStatusParser.new(:logger => @logger))
194
183
  rescue
195
184
  on_exception
@@ -197,11 +186,24 @@ module RightAws
197
186
 
198
187
  # Retrieves the queue attribute(s). Returns a hash of attribute(s) or an exception.
199
188
  #
200
- # sqs.get_queue_attributes('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue')
201
- # #=> {"ApproximateNumberOfMessages"=>"0", "VisibilityTimeout"=>"30"}
189
+ # sqs.get_queue_attributes('https://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue') #=>
190
+ # {"ApproximateNumberOfMessages" => "0",
191
+ # "LastModifiedTimestamp" => "1240946032",
192
+ # "CreatedTimestamp" => "1240816887",
193
+ # "VisibilityTimeout" => "30",
194
+ # "Policy" => "{"Version":"2008-10-17","Id":...}"}
195
+ #
196
+ # queue.get_queue_attributes('https://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue', "LastModifiedTimestamp", "VisibilityTimeout") #=>
197
+ # {"LastModifiedTimestamp" => "1240946032",
198
+ # "VisibilityTimeout" => "30"}
202
199
  #
203
- def get_queue_attributes(queue_url, attribute='All')
204
- req_hash = generate_request('GetQueueAttributes', 'AttributeName' => attribute, :queue_url => queue_url)
200
+ # http://docs.amazonwebservices.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/index.html?Query_QueryGetQueueAttributes.html
201
+ def get_queue_attributes(queue_url, *attributes)
202
+ attributes.flatten!
203
+ attributes << 'All' if attributes.right_blank?
204
+ params = amazonize_list('AttributeName', attributes)
205
+ params.merge!(:queue_url => queue_url)
206
+ req_hash = generate_request('GetQueueAttributes', params)
205
207
  request_info(req_hash, SqsGetQueueAttributesParser.new(:logger => @logger))
206
208
  rescue
207
209
  on_exception
@@ -209,48 +211,108 @@ module RightAws
209
211
 
210
212
  # Sets queue attribute. Returns +true+ or an exception.
211
213
  #
212
- # sqs.set_queue_attributes('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue', "VisibilityTimeout", 10) #=> true
214
+ # sqs.set_queue_attributes('https://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue', "VisibilityTimeout", 10) #=> true
213
215
  #
214
216
  # From the SQS Dev Guide:
215
- # "Currently, you can set only the
216
- # VisibilityTimeout attribute for a queue...
217
- # When you change a queue's attributes, the change can take up to 60 seconds to propagate
217
+ # "When you change a queue's attributes, the change can take up to 60 seconds to propagate
218
218
  # throughout the SQS system."
219
219
  #
220
220
  # NB: Attribute values may not be immediately available to other queries
221
221
  # for some time after an update. See the SQS documentation for
222
222
  # semantics, but in general propagation can take up to 60 s.
223
+ #
224
+ # see http://docs.amazonwebservices.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/index.html?Query_QuerySetQueueAttributes.html
223
225
  def set_queue_attributes(queue_url, attribute, value)
224
- req_hash = generate_request('SetQueueAttributes', 'Attribute.Name' => attribute, 'Attribute.Value' => value, :queue_url => queue_url)
226
+ req_hash = generate_request('SetQueueAttributes',
227
+ 'Attribute.Name' => attribute,
228
+ 'Attribute.Value' => value,
229
+ :queue_url => queue_url)
230
+ request_info(req_hash, SqsStatusParser.new(:logger => @logger))
231
+ rescue
232
+ on_exception
233
+ end
234
+
235
+ # Add permissions to a queue.
236
+ #
237
+ # sqs.add_permissions('https://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue',
238
+ # 'testLabel', ['125074342641','125074342642'],
239
+ # ['SendMessage','SendMessage','ReceiveMessage']) #=> true
240
+ #
241
+ # +permissions+ is a hash of: AccountId => ActionName
242
+ # (valid ActionNames: * | SendMessage | ReceiveMessage | DeleteMessage | ChangeMessageVisibility | GetQueueAttributes )
243
+ #
244
+ # see http://docs.amazonwebservices.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/index.html?Query_QueryAddPermission.html
245
+ # http://docs.amazonwebservices.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/index.html?acp-overview.html
246
+ def add_permissions(queue_url, label, grantees, actions)
247
+ params = amazonize_list('AWSAccountId', Array(grantees))
248
+ params.merge!(amazonize_list('ActionName', Array(actions)))
249
+ params.merge!('Label' => label,
250
+ :queue_url => queue_url )
251
+ req_hash = generate_request('AddPermission', params)
252
+ request_info(req_hash, SqsStatusParser.new(:logger => @logger))
253
+ rescue
254
+ on_exception
255
+ end
256
+
257
+ # Revoke any permissions in the queue policy that matches the +label+ parameter.
258
+ #
259
+ # sqs.remove_permissions('https://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue',
260
+ # 'testLabel') # => true
261
+ #
262
+ # see http://docs.amazonwebservices.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/index.html?Query_QueryRemovePermission.html
263
+ def remove_permissions(queue_url, label)
264
+ req_hash = generate_request('RemovePermission',
265
+ 'Label' => label,
266
+ :queue_url => queue_url )
225
267
  request_info(req_hash, SqsStatusParser.new(:logger => @logger))
226
268
  rescue
227
269
  on_exception
228
270
  end
229
271
 
230
- # Retrieves a list of messages from queue. Returns an array of hashes in format: <tt>{:id=>'message_id', body=>'message_body'}</tt>
272
+ # Retrieves a list of messages from queue. Returns an array of hashes in format: <tt>{:id=>'message_id', :body=>'message_body'}</tt>
231
273
  #
232
- # sqs.receive_message('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue',10, 5) #=>
274
+ # sqs.receive_message('https://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue',10, 5) #=>
233
275
  # [{"ReceiptHandle"=>"Euvo62...kw==", "MD5OfBody"=>"16af2171b5b83cfa35ce254966ba81e3",
234
276
  # "Body"=>"Goodbyte World!", "MessageId"=>"MUM4WlAyR...pYOTA="}, ..., {}]
235
277
  #
236
278
  # Normally this call returns fewer messages than the maximum specified,
237
279
  # even if they are available.
238
280
  #
239
- def receive_message(queue_url, max_number_of_messages=1, visibility_timeout=nil)
281
+ def receive_message(queue_url, max_number_of_messages=1, visibility_timeout=nil, attributes=nil)
240
282
  return [] if max_number_of_messages == 0
241
- req_hash = generate_post_request('ReceiveMessage', 'MaxNumberOfMessages' => max_number_of_messages, 'VisibilityTimeout' => visibility_timeout,
242
- :queue_url => queue_url )
283
+ params = {}
284
+ params.merge!(amazonize_list('AttributeName', Array(attributes))) unless attributes.right_blank?
285
+ params.merge!('MaxNumberOfMessages' => max_number_of_messages,
286
+ 'VisibilityTimeout' => visibility_timeout,
287
+ :queue_url => queue_url )
288
+ req_hash = generate_post_request('ReceiveMessage', params)
243
289
  request_info(req_hash, SqsReceiveMessageParser.new(:logger => @logger))
244
290
  rescue
245
291
  on_exception
246
292
  end
293
+
294
+ # Change the visibility timeout of a specified message in a queue.
295
+ #
296
+ # sqs.change_message_visibility('https://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue', 'Euvo62...kw==', 33) #=> true
297
+ #
298
+ # see http://docs.amazonwebservices.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/index.html?Query_QueryChangeMessageVisibility.html
299
+ def change_message_visibility(queue_url, receipt_handle, visibility_timeout)
300
+ req_hash = generate_request('ChangeMessageVisibility',
301
+ 'ReceiptHandle' => receipt_handle,
302
+ 'VisibilityTimeout' => visibility_timeout,
303
+ :queue_url => queue_url )
304
+ request_info(req_hash, SqsStatusParser.new(:logger => @logger))
305
+ rescue
306
+ on_exception
307
+ end
247
308
 
248
309
  # Sends a new message to a queue. Message size is limited to 8 KB.
249
310
  # If successful, this call returns a hash containing key/value pairs for
250
311
  # "MessageId" and "MD5OfMessageBody":
251
312
  #
252
- # sqs.send_message('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue', 'message_1') #=> "1234567890...0987654321"
253
- # => {"MessageId"=>"MEs4M0JKNlRCRTBBSENaMjROTk58QVFRNzNEREhDVFlFOVJDQ1JKNjF8UTdBRllCUlJUMjhKMUI1WDJSWDE=", "MD5OfMessageBody"=>"16af2171b5b83cfa35ce254966ba81e3"}
313
+ # sqs.send_message('https://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue', 'message_1') #=>
314
+ # {"MessageId"=>"MEs4M0JKNlRCRTBBSENaMjROTk58QVFRNzNEREhDVFlFOVJDQ1JKNjF8UTdBRllCUlJUMjhKMUI1WDJSWDE=",
315
+ # "MD5OfMessageBody"=>"16af2171b5b83cfa35ce254966ba81e3"}
254
316
  #
255
317
  # On failure, send_message raises an exception.
256
318
  #
@@ -277,7 +339,7 @@ module RightAws
277
339
  # you again on a subsequent receive request. You should create your system to be
278
340
  # idempotent so that receiving a particular message more than once is not a problem. "
279
341
  #
280
- # sqs.delete_message('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue', 'Euvo62/1nlIet...ao03hd9Sa0w==') #=> true
342
+ # sqs.delete_message('https://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue', 'Euvo62/1nlIet...ao03hd9Sa0w==') #=> true
281
343
  #
282
344
  def delete_message(queue_url, receipt_handle)
283
345
  req_hash = generate_request('DeleteMessage', 'ReceiptHandle' => receipt_handle, :queue_url => queue_url)
@@ -287,7 +349,7 @@ module RightAws
287
349
  end
288
350
 
289
351
  # Given the queue's short name, this call returns the queue URL or +nil+ if queue is not found
290
- # sqs.queue_url_by_name('my_awesome_queue') #=> 'http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue'
352
+ # sqs.queue_url_by_name('my_awesome_queue') #=> 'https://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue'
291
353
  #
292
354
  def queue_url_by_name(queue_name)
293
355
  return queue_name if queue_name.include?('/')
@@ -302,7 +364,7 @@ module RightAws
302
364
 
303
365
  # Returns short queue name by url.
304
366
  #
305
- # RightSqs.queue_name_by_url('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue') #=> 'my_awesome_queue'
367
+ # RightSqs.queue_name_by_url('https://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue') #=> 'my_awesome_queue'
306
368
  #
307
369
  def self.queue_name_by_url(queue_url)
308
370
  queue_url[/[^\/]*$/]
@@ -312,7 +374,7 @@ module RightAws
312
374
 
313
375
  # Returns short queue name by url.
314
376
  #
315
- # sqs.queue_name_by_url('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue') #=> 'my_awesome_queue'
377
+ # sqs.queue_name_by_url('https://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue') #=> 'my_awesome_queue'
316
378
  #
317
379
  def queue_name_by_url(queue_url)
318
380
  self.class.queue_name_by_url(queue_url)
@@ -322,17 +384,19 @@ module RightAws
322
384
 
323
385
  # Returns approximate number of messages in queue.
324
386
  #
325
- # sqs.get_queue_length('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue') #=> 3
387
+ # sqs.get_queue_length('https://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue') #=> 3
326
388
  #
327
389
  def get_queue_length(queue_url)
328
- get_queue_attributes(queue_url)['ApproximateNumberOfMessages'].to_i
390
+ attrs = get_queue_attributes(queue_url)
391
+ attrs['ApproximateNumberOfMessages'].to_i +
392
+ attrs['ApproximateNumberOfMessagesNotVisible'].to_i
329
393
  rescue
330
394
  on_exception
331
395
  end
332
396
 
333
397
  # Removes all visible messages from queue. Return +true+ or an exception.
334
398
  #
335
- # sqs.clear_queue('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue') #=> true
399
+ # sqs.clear_queue('https://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue') #=> true
336
400
  #
337
401
  def clear_queue(queue_url)
338
402
  while (pop_messages(queue_url, 10).length > 0) ; end # delete all messages in queue
@@ -343,12 +407,12 @@ module RightAws
343
407
 
344
408
  # 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>.
345
409
  #
346
- # sqs.pop_messages('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue', 3) #=>
410
+ # sqs.pop_messages('https://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue', 3) #=>
347
411
  # [{"ReceiptHandle"=>"Euvo62/...+Zw==", "MD5OfBody"=>"16af2...81e3", "Body"=>"Goodbyte World!",
348
412
  # "MessageId"=>"MEZI...JSWDE="}, {...}, ... , {...} ]
349
413
  #
350
- def pop_messages(queue_url, number_of_messages=1)
351
- messages = receive_message(queue_url, number_of_messages)
414
+ def pop_messages(queue_url, number_of_messages=1, attributes=nil)
415
+ messages = receive_message(queue_url, number_of_messages, nil, attributes)
352
416
  messages.each do |message|
353
417
  delete_message(queue_url, message['ReceiptHandle'])
354
418
  end
@@ -359,12 +423,12 @@ module RightAws
359
423
 
360
424
  # Pops (retrieves and deletes) first accessible message from queue. Returns the message in format <tt>{:id=>'message_id', :body=>'message_body'}</tt> or +nil+.
361
425
  #
362
- # sqs.pop_message('http://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue') #=>
426
+ # sqs.pop_message('https://queue.amazonaws.com/ZZ7XXXYYYBINS/my_awesome_queue') #=>
363
427
  # {:id=>"12345678904GEZX9746N|0N9ED344VK5Z3SV1DTM0|1RVYH4X3TJ0987654321", :body=>"message_1"}
364
428
  #
365
- def pop_message(queue_url)
366
- messages = pop_messages(queue_url)
367
- messages.blank? ? nil : messages[0]
429
+ def pop_message(queue_url, attributes=nil)
430
+ messages = pop_messages(queue_url, 1, attributes)
431
+ messages.right_blank? ? nil : messages[0]
368
432
  rescue
369
433
  on_exception
370
434
  end
@@ -406,8 +470,8 @@ module RightAws
406
470
  end
407
471
  def tagend(name)
408
472
  case name
409
- when 'Name' ; @current_attribute = @text
410
- when 'Value' ; @result[@current_attribute] = @text
473
+ when 'Name' then @current_attribute = @text
474
+ when 'Value' then @result[@current_attribute] = @text
411
475
  end
412
476
  end
413
477
  end
@@ -421,14 +485,23 @@ module RightAws
421
485
  @result = []
422
486
  end
423
487
  def tagstart(name, attributes)
424
- @current_message = {} if name == 'Message'
488
+ case name
489
+ when 'Message' then @current_message = { }
490
+ when 'Attribute' then
491
+ @current_message['Attributes'] ||= {}
492
+ @current_attribute_name = ''
493
+ @current_attribute_value = ''
494
+ end
425
495
  end
426
496
  def tagend(name)
427
497
  case name
428
- when 'MessageId' ; @current_message['MessageId'] = @text
429
- when 'ReceiptHandle' ; @current_message['ReceiptHandle'] = @text
430
- when 'MD5OfBody' ; @current_message['MD5OfBody'] = @text
431
- when 'Body'; @current_message['Body'] = @text; @result << @current_message
498
+ when 'MessageId' then @current_message['MessageId'] = @text
499
+ when 'ReceiptHandle' then @current_message['ReceiptHandle'] = @text
500
+ when 'MD5OfBody' then @current_message['MD5OfBody'] = @text
501
+ when 'Name' then @current_attribute_name = @text
502
+ when 'Value' then @current_attribute_value = @text
503
+ when 'Attribute' then @current_message['Attributes'][@current_attribute_name] = @current_attribute_value
504
+ when 'Body' then @current_message['Body'] = @text; @result << @current_message
432
505
  end
433
506
  end
434
507
  end
@@ -439,8 +512,8 @@ module RightAws
439
512
  end
440
513
  def tagend(name)
441
514
  case name
442
- when 'MessageId' ; @result['MessageId'] = @text
443
- when 'MD5OfMessageBody' ; @result['MD5OfMessageBody'] = @text
515
+ when 'MessageId' then @result['MessageId'] = @text
516
+ when 'MD5OfMessageBody' then @result['MD5OfMessageBody'] = @text
444
517
  end
445
518
  end
446
519
  end
@@ -49,14 +49,13 @@ module RightAws
49
49
 
50
50
  # Creates a new SqsInterface instance.
51
51
  #
52
- # sqs = RightAws::SqsInterface.new('1E3GDYEOGFJPIT75KDT40','hgTHt68JY07JKUY08ftHYtERkjgtfERn57DFE379', {:multi_thread => true, :logger => Logger.new('/tmp/x.log')})
52
+ # sqs = RightAws::SqsInterface.new('1E3GDYEOGFJPIT75KDT40','hgTHt68JY07JKUY08ftHYtERkjgtfERn57DFE379', {:logger => Logger.new('/tmp/x.log')})
53
53
  #
54
54
  # Params is a hash:
55
55
  #
56
56
  # {:server => 'queue.amazonaws.com' # Amazon service host: 'queue.amazonaws.com'(default)
57
57
  # :port => 443 # Amazon service port: 80 or 443(default)
58
- # :multi_thread => true|false # Multi-threaded (connection per each thread): true or false(default)
59
- # :signature_version => '0' # The signature version : '0' or '1'(default)
58
+ # :signature_version => '0' # The signature version : '0', '1' or '2'(default)
60
59
  # :logger => Logger Object} # Logger instance: logs to STDOUT if omitted }
61
60
  #
62
61
  def initialize(aws_access_key_id=nil, aws_secret_access_key=nil, params={})
@@ -78,24 +77,17 @@ module RightAws
78
77
  def generate_request(action, params={}) # :nodoc:
79
78
  # Sometimes we need to use queue uri (delete queue etc)
80
79
  # In that case we will use Symbol key: 'param[:queue_url]'
81
- queue_uri = params[:queue_url] ? URI(params[:queue_url]).path : '/'
80
+ service = params[:queue_url] ? URI(params[:queue_url]).path : '/'
82
81
  # remove unset(=optional) and symbolyc keys
83
82
  params.each{ |key, value| params.delete(key) if (value.nil? || key.is_a?(Symbol)) }
84
83
  # prepare output hash
85
84
  service_hash = { "Action" => action,
86
85
  "Expires" => (Time.now + REQUEST_TTL).utc.strftime("%Y-%m-%dT%H:%M:%SZ"),
87
86
  "AWSAccessKeyId" => @aws_access_key_id,
88
- "Version" => API_VERSION,
89
- "SignatureVersion" => signature_version }
87
+ "Version" => API_VERSION }
90
88
  service_hash.update(params)
91
- # prepare string to sight
92
- string_to_sign = case signature_version
93
- when '0' : service_hash["Action"] + service_hash["Expires"]
94
- when '1' : service_hash.sort{|a,b| (a[0].to_s.downcase)<=>(b[0].to_s.downcase)}.to_s
95
- end
96
- service_hash['Signature'] = AwsUtils::sign(@aws_secret_access_key, string_to_sign)
97
- request_params = service_hash.to_a.collect{|key,val| key.to_s + "=" + CGI::escape(val.to_s) }.join("&")
98
- request = Net::HTTP::Get.new("#{queue_uri}?#{request_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}")
99
91
  # prepare output hash
100
92
  { :request => request,
101
93
  :server => @params[:server],
@@ -111,8 +103,8 @@ module RightAws
111
103
  param.each{ |key, value| param.delete(key) if (value.nil? || key.is_a?(Symbol)) }
112
104
  # created request
113
105
  param_to_str = param.to_a.collect{|key,val| key.to_s + "=" + CGI::escape(val.to_s) }.join("&")
114
- param_to_str = "?#{param_to_str}" unless param_to_str.blank?
115
- request = "Net::HTTP::#{method.capitalize}".constantize.new("#{queue_uri}#{param_to_str}")
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}")
116
108
  request.body = message if message
117
109
  # set main headers
118
110
  request['content-md5'] = ''
@@ -135,9 +127,7 @@ module RightAws
135
127
  # Sends request to Amazon and parses the response
136
128
  # Raises AwsError if any banana happened
137
129
  def request_info(request, parser) # :nodoc:
138
- thread = @params[:multi_thread] ? Thread.current : Thread.main
139
- thread[:sqs_connection] ||= Rightscale::HttpConnection.new(:exception => AwsError, :logger => @logger)
140
- request_info_impl(thread[:sqs_connection], @@bench, request, parser)
130
+ request_info_impl(:sqs_connection, @@bench, request, parser)
141
131
  end
142
132
 
143
133
 
@@ -320,7 +310,7 @@ module RightAws
320
310
  def peek_message(queue_url, message_id)
321
311
  req_hash = generate_rest_request('GET', :queue_url => "#{queue_url}/#{CGI::escape message_id}" )
322
312
  messages = request_info(req_hash, SqsReceiveMessagesParser.new(:logger => @logger))
323
- messages.blank? ? nil : messages[0]
313
+ messages.right_blank? ? nil : messages[0]
324
314
  rescue
325
315
  on_exception
326
316
  end
@@ -461,7 +451,7 @@ module RightAws
461
451
  #
462
452
  def receive_message(queue_url, visibility_timeout=nil)
463
453
  result = receive_messages(queue_url, 1, visibility_timeout)
464
- result.blank? ? nil : result[0]
454
+ result.right_blank? ? nil : result[0]
465
455
  rescue
466
456
  on_exception
467
457
  end
@@ -491,7 +481,7 @@ module RightAws
491
481
  #
492
482
  def pop_message(queue_url)
493
483
  messages = pop_messages(queue_url)
494
- messages.blank? ? nil : messages[0]
484
+ messages.right_blank? ? nil : messages[0]
495
485
  rescue
496
486
  on_exception
497
487
  end