sqs_async 0.0.1

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/lib/sqs.rb ADDED
@@ -0,0 +1,162 @@
1
+ require 'uri'
2
+ require 'cgi'
3
+ require 'hmac'
4
+ require 'hmac-sha2'
5
+ require 'base64'
6
+ require 'net/http'
7
+ require 'time'
8
+ require 'nokogiri'
9
+ require 'json'
10
+ require 'eventmachine'
11
+ require 'em-http-request'
12
+ require 'sqs_message'
13
+ require 'sqs_queue'
14
+ require 'sqs_attributes'
15
+ require 'logger'
16
+
17
+ module SQS
18
+ attr_accessor :aws_key, :aws_secret, :regions, :default_parameters, :post_options
19
+
20
+ def list_queues(options={})
21
+ prefix = options.delete(:prefix)
22
+ match = options.delete(:match)
23
+
24
+ options.merge!( "Action" => "ListQueues" )
25
+ options.merge!( "QueueNamePrefix" => encode(prefix) ) if prefix
26
+
27
+ call_amazon(options) do |req|
28
+ queues = SQSQueue.parse(req.response)
29
+ queues.select!{|q| q.queue_url.path.match(match) } if match
30
+ queues
31
+ end
32
+ end
33
+
34
+ def receive_message(options={})
35
+ raise "no target queue specified" unless options[:queue]
36
+ options.merge!("Action" => "ReceiveMessage", "MaxNumberOfMessages" => 10 )
37
+ call_amazon(options){ |req| SQSMessage.parse(req.response) }
38
+ end
39
+
40
+ def delete_message(options={})
41
+ raise "no Message specified" unless options[:message]
42
+ options.merge!("Action" => "DeleteMessage", "ReceiptHandle" => options.delete(:message).receipt_handle)
43
+ call_amazon(options)
44
+ end
45
+
46
+ def get_queue_attributes(options={})
47
+ raise "no target queue specified" unless options[:queue]
48
+ options.merge!( "Action" => "GetQueueAttributes", "AttributeName" => "All" )
49
+ call_amazon(options){ |req| SQSAttributes.parse(req.response) }
50
+ end
51
+
52
+ private
53
+
54
+ def call_amazon(options)
55
+ endpoint = (options[:queue] != nil) ? options.delete(:queue).queue_url : "http://" << ( options.delete(:host) || region_host(:us_east) )
56
+ callbacks = options.delete(:callbacks) || {:success=>nil, :failure =>nil }
57
+
58
+ params = sign_params( endpoint, options )
59
+ req = EM::HttpRequest.new("#{endpoint}?#{params}").get
60
+ req.callback do |req|
61
+ if(req.response.to_s.match(/<ErrorResponse>/i))
62
+ on_failure(req, callbacks)
63
+ else
64
+ result = req
65
+ result = yield req if block_given?
66
+ callbacks[:success].call(result) if callbacks[:success]
67
+ end
68
+ end
69
+ req.errback do |req|
70
+ on_failure(req, callbacks)
71
+ end
72
+ end
73
+
74
+ def on_failure(req, callbacks)
75
+ result = (req.error != nil) ? req.error : req.response
76
+ log result
77
+ callbacks[:failure].call(result) if callbacks[:failure]
78
+ end
79
+
80
+ def sign_params(uri, opts)
81
+ uri = URI.parse(uri) if uri.kind_of? String
82
+ opts = default_paramters.merge(opts)
83
+
84
+ sorted_params = opts.sort {|x,y| x[0] <=> y[0]}
85
+ encoded_params = sorted_params.collect do |p|
86
+ encode(p[0].to_s) << "=" << encode(p[1].to_s)
87
+ end
88
+ params_string = encoded_params.join("&")
89
+
90
+ req_desc = ["GET", uri.host.downcase, uri.request_uri, params_string].join("\n")
91
+ params_string << "&Signature=" << generate_signature(req_desc)
92
+ end
93
+
94
+ def generate_signature(request_description)
95
+ hmac = HMAC::SHA256.new(aws_secret)
96
+ hmac.update(request_description)
97
+ encode(Base64.encode64(hmac.digest).chomp)
98
+ end
99
+
100
+ def encoding_exclusions
101
+ /[^\w\d\-\_\.\~]/
102
+ end
103
+
104
+ def encode(val)
105
+ URI.encode(val, encoding_exclusions)
106
+ end
107
+
108
+ def region_host(key)
109
+ regions[key][:uri]
110
+ end
111
+
112
+ def regions
113
+ @regions ||= Regions
114
+ @regions
115
+ end
116
+
117
+ def default_paramters
118
+ @default_paramters ||= Parameters.merge("AWSAccessKeyId" => aws_key)
119
+ @default_paramters.merge("Expires" => (Time.now+(60*30)).utc.iso8601)
120
+ end
121
+
122
+ def post_options
123
+ @post_options ||= PostOptions
124
+ @post_options
125
+ end
126
+
127
+ def logger
128
+ return @logger if @logger
129
+
130
+ @logger = Logger.new @log_path || "./sqs_async.log"
131
+ @logger.level = @log_level || Logger::WARN
132
+ @logger
133
+ end
134
+
135
+ def log(msg)
136
+ log_msg = ["SERVICE ERROR"]
137
+ log_msg << caller[0..7].join("\n\t")
138
+ log_msg << "-".ljust(80, "-")
139
+ log_msg << msg
140
+ log_msg << "-".ljust(80, "-")
141
+ logger.error(log_msg.join("\n"))
142
+ end
143
+
144
+ Regions = {
145
+ :us_east => { :name => "US-East (Northern Virginia) Region", :uri => "sqs.us-east-1.amazonaws.com"},
146
+ :us_west => { :name => "US-West (Northern California) Region", :uri => "sqs.us-west-1.amazonaws.com"},
147
+ :eu => { :name => "EU (Ireland) Region", :uri => "sqs.eu-west-1.amazonaws.com"},
148
+ :asia_singapore => { :name => "Asia Pacific (Singapore) Region", :uri => "sqs.ap-southeast-1.amazonaws.com"},
149
+ :asia_tokyo => { :name => "Asia Pacific (Tokyo) Region", :uri => "sqs.ap-northeast-1.amazonaws.com"}
150
+ }
151
+
152
+
153
+ Parameters = {
154
+ "Version" => "2009-02-01",
155
+ "SignatureVersion"=>"2",
156
+ "SignatureMethod"=>"HmacSHA256",
157
+ }
158
+
159
+ PostOptions = {
160
+ "Content-Type" => "application/x-www-form-urlencoded"
161
+ }
162
+ end
@@ -0,0 +1,38 @@
1
+ require 'nokogiri'
2
+ require 'json'
3
+ require 'base64'
4
+ require 'ostruct'
5
+
6
+ class SQSAttributes
7
+ attr_accessor :approximate_number_of_messages,
8
+ :approximate_number_of_messages_not_visible,
9
+ :visibility_timeout,
10
+ :create_timestamp,
11
+ :last_modified_timestamp,
12
+ :policy,
13
+ :maximum_message_size,
14
+ :message_retention_period,
15
+ :queue_arn
16
+
17
+ def self.parse(xml)
18
+ doc = Nokogiri::XML(xml)
19
+ queue_data = SQSAttributes.new
20
+ doc.search("Attribute").each do |attribute|
21
+ meth = underscore(attribute.at("Name").text)
22
+ if queue_data.respond_to? meth.to_sym
23
+ queue_data.send "#{meth}=", attribute.at("Value").text
24
+ end
25
+ end
26
+ queue_data
27
+ end
28
+
29
+ # Taken from ActiveSupport. License information can be found at rubyonrails.org
30
+ def self.underscore(camel_cased_word)
31
+ word = camel_cased_word.to_s.dup
32
+ word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
33
+ word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
34
+ word.tr!("-", "_")
35
+ word.downcase!
36
+ word
37
+ end
38
+ end
@@ -0,0 +1,22 @@
1
+ require 'nokogiri'
2
+ require 'json'
3
+ require 'base64'
4
+ require 'ostruct'
5
+
6
+ class SQSMessage
7
+ attr_accessor :body, :md5_of_body, :message_id, :receipt_handle
8
+
9
+ def self.parse(xml)
10
+ doc = Nokogiri::XML(xml)
11
+ messages = []
12
+ doc.search("Message").each do |message_element|
13
+ s = SQSMessage.new
14
+ s.body = message_element.at("Body").text
15
+ s.md5_of_body = message_element.at("MD5OfBody").text
16
+ s.message_id = message_element.at("MessageId").text
17
+ s.receipt_handle = message_element.at("ReceiptHandle").text.strip
18
+ messages << s
19
+ end
20
+ messages
21
+ end
22
+ end
data/lib/sqs_queue.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'nokogiri'
2
+ require 'json'
3
+ require 'base64'
4
+
5
+ class SQSQueue
6
+ attr_accessor :queue_url
7
+
8
+ def self.parse(xml)
9
+ doc = Nokogiri::XML(xml)
10
+ queues = []
11
+ doc.search("QueueUrl").each do |element|
12
+ s = SQSQueue.new
13
+ s.queue_url = URI.parse(element.text)
14
+ queues << s
15
+ end
16
+ queues
17
+ end
18
+ end
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <DeleteQueueResponse>
3
+ <ResponseMetadata>
4
+ <RequestId>
5
+ 6fde8d1e-52cd-4581-8cd9-c512f4c64223
6
+ </RequestId>
7
+ </ResponseMetadata>
8
+ </DeleteQueueResponse>
@@ -0,0 +1,18 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <ErrorResponse>
3
+ <Error>
4
+ <Type>
5
+ Sender
6
+ </Type>
7
+ <Code>
8
+ AuthFailure
9
+ </Code>
10
+ <Message>
11
+ The provided signature is not valid for this access token
12
+ </Message>
13
+ <Detail/>
14
+ </Error>
15
+ <RequestId>
16
+ ef3aba6a-dc84-4937-91bf-cef2ddd6775a
17
+ </RequestId>
18
+ </ErrorResponse>
@@ -0,0 +1,13 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <ListQueuesResponse>
3
+ <ListQueuesResult>
4
+ <QueueUrl>
5
+ http://sqs.us-east-1.amazonaws.com/123456789012/testQueue
6
+ </QueueUrl>
7
+ </ListQueuesResult>
8
+ <ResponseMetadata>
9
+ <RequestId>
10
+ 725275ae-0b9b-4762-b238-436d7c65a1ac
11
+ </RequestId>
12
+ </ResponseMetadata>
13
+ </ListQueuesResponse>
@@ -0,0 +1,40 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <GetQueueAttributesResponse>
3
+ <GetQueueAttributesResult>
4
+ <Attribute>
5
+ <Name>VisibilityTimeout</Name>
6
+ <Value>30</Value>
7
+ </Attribute>
8
+ <Attribute>
9
+ <Name>ApproximateNumberOfMessages</Name>
10
+ <Value>0</Value>
11
+ </Attribute>
12
+ <Attribute>
13
+ <Name>ApproximateNumberOfMessagesNotVisible</Name>
14
+ <Value>0</Value>
15
+ </Attribute>
16
+ <Attribute>
17
+ <Name>CreatedTimestamp</Name>
18
+ <Value>1286771522</Value>
19
+ </Attribute>
20
+ <Attribute>
21
+ <Name>LastModifiedTimestamp</Name>
22
+ <Value>1286771522</Value>
23
+ </Attribute>
24
+ <Attribute>
25
+ <Name>QueueArn</Name>
26
+ <Value>arn:aws:sqs:us-east-1:123456789012:qfoo</Value>
27
+ </Attribute>
28
+ <Attribute>
29
+ <Name>MaximumMessageSize</Name>
30
+ <Value>8192</Value>
31
+ </Attribute>
32
+ <Attribute>
33
+ <Name>MessageRetentionPeriod</Name>
34
+ <Value>345600</Value>
35
+ </Attribute>
36
+ </GetQueueAttributesResult>
37
+ <ResponseMetadata>
38
+ <RequestId>1ea71be5-b5a2-4f9d-b85a-945d8d08cd0b</RequestId>
39
+ </ResponseMetadata>
40
+ </GetQueueAttributesResponse>
@@ -0,0 +1,40 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <ReceiveMessageResponse>
3
+ <ReceiveMessageResult>
4
+ <Message>
5
+ <MessageId>
6
+ 5fea7756-0ea4-451a-a703-a558b933e274
7
+ </MessageId>
8
+ <ReceiptHandle>
9
+ MbZj6wDWli+JvwwJaBV+3dcjk2YW2vA3+STFFljTM8tJJg6HRG6PYSasuWXPJB+Cw
10
+ Lj1FjgXUv1uSj1gUPAWV66FU/WeR4mq2OKpEGYWbnLmpRCJVAyeMjeU5ZBdtcQ+QE
11
+ auMZc8ZRv37sIW2iJKq3M9MFx1YvV11A2x/KSbkJ0=
12
+ </ReceiptHandle>
13
+ <MD5OfBody>
14
+ fafb00f5732ab283681e124bf8747ed1
15
+ </MD5OfBody>
16
+ <Body>This is a test message</Body>
17
+ <Attribute>
18
+ <Name>SenderId</Name>
19
+ <Value>195004372649</Value>
20
+ </Attribute>
21
+ <Attribute>
22
+ <Name>SentTimestamp</Name>
23
+ <Value>1238099229000</Value>
24
+ </Attribute>
25
+ <Attribute>
26
+ <Name>ApproximateReceiveCount</Name>
27
+ <Value>5</Value>
28
+ </Attribute>
29
+ <Attribute>
30
+ <Name>ApproximateFirstReceiveTimestamp</Name>
31
+ <Value>1250700979248</Value>
32
+ </Attribute>
33
+ </Message>
34
+ </ReceiveMessageResult>
35
+ <ResponseMetadata>
36
+ <RequestId>
37
+ b6633655-283d-45b4-aee4-4e84e0ae6afa
38
+ </RequestId>
39
+ </ResponseMetadata>
40
+ </ReceiveMessageResponse>
@@ -0,0 +1,100 @@
1
+ ENV["BUBBLE_ENV"] = "test"
2
+
3
+ $:.unshift(File.dirname(__FILE__))
4
+ %w{ ../ lib config vendor/sqs_async/lib }.each do |d|
5
+ $:.unshift(File.dirname(__FILE__)+"/#{d}/")
6
+ end
7
+
8
+ require 'bundler/setup'
9
+ require 'rspec'
10
+ require 'timecop'
11
+ require 'em-http-request'
12
+
13
+ require 'sqs'
14
+ require 'sqs_message'
15
+ require 'sqs_queue'
16
+ require 'sqs_attributes'
17
+
18
+
19
+ RSpec.configure do |config|
20
+ config.mock_framework = :mocha
21
+
22
+ def xml_fixture(name)
23
+ File.read(File.dirname(__FILE__)+"/fixtures/#{name}.xml")
24
+ end
25
+ end
26
+
27
+ module EventMachine
28
+ class MockHttpRequest
29
+ def initialize *args
30
+ @callbacks = []
31
+ @errbacks = []
32
+ end
33
+
34
+ def get *args
35
+ return self
36
+ end
37
+
38
+ def post *args
39
+ return self
40
+ end
41
+
42
+ def callback &block
43
+ @callbacks << block
44
+ end
45
+
46
+ def errback &block
47
+ @errbacks << block
48
+ end
49
+
50
+ def succeed(response)
51
+ @callbacks.each {|c| c.call(response)}
52
+ reset
53
+ end
54
+
55
+ def error(response)
56
+ @errbacks.each {|c| c.call(response)}
57
+ reset
58
+ end
59
+
60
+ def reset
61
+ @callbacks = []
62
+ @errbacks = []
63
+ end
64
+ end
65
+
66
+ class HttpRequest
67
+ def self.new *args
68
+ request = MockHttpRequest.new
69
+ connection_instances << request
70
+ request
71
+ end
72
+
73
+ def self.connection_instances
74
+ @connection_instances ||= []
75
+ end
76
+
77
+ def self.succeed(response)
78
+ connection_instances.each do |conn|
79
+ conn.succeed(response)
80
+ end
81
+ end
82
+
83
+ def self.error(response)
84
+ connection_instances.each do |conn|
85
+ conn.error(response)
86
+ end
87
+ end
88
+ end
89
+
90
+ class MockResponse
91
+ def initialize(body)
92
+ @body = body
93
+ end
94
+
95
+ def response
96
+ @body
97
+ end
98
+ alias :error :response
99
+ end
100
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe "SQSAttributes" do
4
+ describe ".parse" do
5
+ let(:attributes_obj) { SQSAttributes.parse(xml_fixture(:queue_attributes)) }
6
+
7
+ it "returns SQSAttributes objects" do
8
+ attributes_obj.should be_a_kind_of(SQSAttributes)
9
+ end
10
+
11
+ it "parses attributes" do
12
+ attributes_obj.approximate_number_of_messages.should == "0"
13
+ attributes_obj.approximate_number_of_messages_not_visible.should == "0"
14
+ attributes_obj.visibility_timeout.should == "30"
15
+ attributes_obj.create_timestamp.should == nil
16
+ attributes_obj.last_modified_timestamp.should == "1286771522"
17
+ attributes_obj.policy.should == nil
18
+ attributes_obj.maximum_message_size.should == "8192"
19
+ attributes_obj.message_retention_period.should == "345600"
20
+ attributes_obj.queue_arn.should == "arn:aws:sqs:us-east-1:123456789012:qfoo"
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe "SQSMessage" do
4
+ describe ".parse" do
5
+ let(:messages) { SQSMessage.parse(xml_fixture(:receive_message)) }
6
+
7
+ it "returns SQSMessage objects" do
8
+ messages.length.should == 1
9
+ messages.first.should be_a_kind_of(SQSMessage)
10
+ end
11
+
12
+ it "parses attributes" do
13
+ message = messages.first
14
+ message.body.should == "This is a test message"
15
+ message.receipt_handle.should match /MbZj6wDWli.+?/im
16
+ message.md5_of_body.should == "\n fafb00f5732ab283681e124bf8747ed1\n "
17
+ message.message_id.should == "\n 5fea7756-0ea4-451a-a703-a558b933e274\n "
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+ require 'sqs_message'
3
+
4
+ describe "SQSQueue" do
5
+ describe ".parse" do
6
+ let(:queues) { SQSQueue.parse(xml_fixture(:list_queues)) }
7
+
8
+ it "returns SQSQueue objects" do
9
+ queues.length.should == 1
10
+ queues.first.should be_a_kind_of(SQSQueue)
11
+ end
12
+
13
+ it "parses attributes" do
14
+ queue = queues.first
15
+ queue.queue_url.should == URI.parse("http://sqs.us-east-1.amazonaws.com/123456789012/testQueue")
16
+ end
17
+ end
18
+ end
data/spec/sqs_spec.rb ADDED
@@ -0,0 +1,152 @@
1
+ require 'spec_helper'
2
+ require 'sqs'
3
+
4
+ class MySQSClient
5
+ include SQS
6
+ def initialize
7
+ self.aws_key = 'adsf'
8
+ self.aws_secret = 'adsffasdf'
9
+ end
10
+ end
11
+
12
+ describe "SQS" do
13
+ let(:client) { MySQSClient.new }
14
+ let(:queue) { SQSQueue.new.tap { |q| q.queue_url = URI.parse("http://sqs.us-east-1.amazonaws.com/123456789012/testQueue") } }
15
+ let(:message) { SQSMessage.new.tap {|msg| msg.receipt_handle = "foo" } }
16
+
17
+ # we are testing private members because the
18
+ # interaction with Amazon is stubbed. Therefore
19
+ # we want to ensure that these perform as expected
20
+ # even though they would normally be encapsulated by
21
+ # calls to amazon.
22
+ #
23
+ # Leon and John 5-31-11
24
+ context "Private member testing" do
25
+
26
+ before(:all) do
27
+ MySQSClient.send :public, :sign_params
28
+ MySQSClient.send :public, :generate_signature
29
+ end
30
+
31
+ after(:all) do
32
+ MySQSClient.send :private, :sign_params
33
+ MySQSClient.send :private, :generate_signature
34
+ end
35
+
36
+ it "signs requests prior to sending" do
37
+ Timecop.freeze(Time.parse("2011-04-20T00:00:00")) do
38
+ client.sign_params("http://edgecase.com/mysevice", {}).should == "AWSAccessKeyId=adsf&Expires=2011-04-20T04%3A30%3A00Z&SignatureMethod=HmacSHA256&SignatureVersion=2&Version=2009-02-01&Signature=oKFwSahHQIMKiSOabVZqwcZEFowOdqyyj2gamyjJ3oU%3D"
39
+ end
40
+ end
41
+
42
+ it "generates valid signatures based on params" do
43
+ req_desc = ["GET", 'foo', '/', "foo=bar&baz=fellini"].join("\n")
44
+ client.generate_signature(req_desc).should == "WHmv1xv6iqPMw6kaw0sXVlqXfmoqkFpkKqBi2ONpAa4%3D"
45
+ end
46
+ end
47
+
48
+ context "calls Amazon Endpoints asynchronously to" do
49
+ it "list available queues" do
50
+ client.list_queues(
51
+ :callbacks => {
52
+ :success => lambda{|queues|
53
+ queues.length.should == 1
54
+ queues.first.queue_url.to_s.should == "http://sqs.us-east-1.amazonaws.com/123456789012/testQueue"
55
+ }
56
+ }
57
+ )
58
+ EM::HttpRequest.succeed(EM::MockResponse.new(xml_fixture(:list_queues)))
59
+ end
60
+
61
+ it "pull a message from the queue" do
62
+ queue.queue_url = URI.parse("http://sqs.us-east-1.amazonaws.com/123456789012/testQueue")
63
+ client.receive_message(
64
+ :queue => queue,
65
+ :callbacks => {
66
+ :success => lambda{|messages|
67
+ messages.kind_of?(Enumerable).should == true
68
+ messages.length.should == 1
69
+ messages.first.kind_of?(SQSMessage).should == true
70
+ }
71
+ }
72
+ )
73
+
74
+ EM::HttpRequest.succeed(EM::MockResponse.new(xml_fixture(:receive_message)))
75
+ end
76
+
77
+ it "delete a message from the queue" do
78
+ mock_obj = mock();
79
+ mock_obj.expects(:call).once
80
+ client.delete_message(
81
+ :queue => queue,
82
+ :message => message,
83
+ :callbacks => { :success => mock_obj }
84
+ )
85
+
86
+ EM::HttpRequest.succeed(EM::MockResponse.new(xml_fixture(:delete_message)))
87
+ end
88
+
89
+ it "gets the queue's attributes" do
90
+ client.get_queue_attributes(
91
+ :queue => queue,
92
+ :callbacks => {
93
+ :success => lambda{|attr_obj|
94
+ attr_obj.kind_of?(SQSAttributes).should == true
95
+ }
96
+ }
97
+ )
98
+
99
+ EM::HttpRequest.succeed(EM::MockResponse.new(xml_fixture(:queue_attributes)))
100
+ end
101
+ end
102
+ context "error result" do
103
+ let(:fail_mock) do
104
+ fail_mock = mock
105
+ fail_mock.expects(:call).once
106
+ fail_mock
107
+ end
108
+
109
+ let(:error_result) do
110
+ EM::MockResponse.new(xml_fixture(:error_response))
111
+ end
112
+
113
+ it "list_queues failure" do
114
+ client.list_queues(
115
+ :callbacks => {
116
+ :failure => fail_mock
117
+ }
118
+ )
119
+ EM::HttpRequest.succeed(error_result)
120
+ end
121
+
122
+ it "list_queues failure on misc http error not related to amazon" do
123
+ client.list_queues(
124
+ :callbacks => {
125
+ :failure => fail_mock
126
+ }
127
+ )
128
+ EM::HttpRequest.error(error_result)
129
+ end
130
+
131
+ it "receive_message failure" do
132
+ client.receive_message(
133
+ :queue => queue,
134
+ :callbacks => {
135
+ :failure => fail_mock
136
+ }
137
+ )
138
+ EM::HttpRequest.succeed(error_result)
139
+ end
140
+
141
+ it "delete_message failure" do
142
+ client.delete_message(
143
+ :queue => queue,
144
+ :message => message,
145
+ :callbacks => {
146
+ :failure => fail_mock
147
+ }
148
+ )
149
+ EM::HttpRequest.succeed(error_result)
150
+ end
151
+ end
152
+ end
metadata ADDED
@@ -0,0 +1,240 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sqs_async
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - EdgeCase <contact@edgecase.com>
14
+ - John Andrews <john@edgecase.com>
15
+ - Leon Gersing <leon@edgecase.com>
16
+ autorequire:
17
+ bindir: bin
18
+ cert_chain: []
19
+
20
+ date: 2011-05-31 00:00:00 -04:00
21
+ default_executable:
22
+ dependencies:
23
+ - !ruby/object:Gem::Dependency
24
+ name: eventmachine
25
+ prerelease: false
26
+ requirement: &id001 !ruby/object:Gem::Requirement
27
+ none: false
28
+ requirements:
29
+ - - ~>
30
+ - !ruby/object:Gem::Version
31
+ hash: 62196357
32
+ segments:
33
+ - 1
34
+ - 0
35
+ - 0
36
+ - beta
37
+ - 3
38
+ version: 1.0.0.beta.3
39
+ type: :runtime
40
+ version_requirements: *id001
41
+ - !ruby/object:Gem::Dependency
42
+ name: em-http-request
43
+ prerelease: false
44
+ requirement: &id002 !ruby/object:Gem::Requirement
45
+ none: false
46
+ requirements:
47
+ - - ~>
48
+ - !ruby/object:Gem::Version
49
+ hash: 62196363
50
+ segments:
51
+ - 1
52
+ - 0
53
+ - 0
54
+ - beta
55
+ - 4
56
+ version: 1.0.0.beta.4
57
+ type: :runtime
58
+ version_requirements: *id002
59
+ - !ruby/object:Gem::Dependency
60
+ name: nokogiri
61
+ prerelease: false
62
+ requirement: &id003 !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ hash: 3
68
+ segments:
69
+ - 0
70
+ version: "0"
71
+ type: :runtime
72
+ version_requirements: *id003
73
+ - !ruby/object:Gem::Dependency
74
+ name: json
75
+ prerelease: false
76
+ requirement: &id004 !ruby/object:Gem::Requirement
77
+ none: false
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ hash: 3
82
+ segments:
83
+ - 0
84
+ version: "0"
85
+ type: :runtime
86
+ version_requirements: *id004
87
+ - !ruby/object:Gem::Dependency
88
+ name: ruby-hmac
89
+ prerelease: false
90
+ requirement: &id005 !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ hash: 3
96
+ segments:
97
+ - 0
98
+ version: "0"
99
+ type: :runtime
100
+ version_requirements: *id005
101
+ - !ruby/object:Gem::Dependency
102
+ name: rspec
103
+ prerelease: false
104
+ requirement: &id006 !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ hash: 23
110
+ segments:
111
+ - 2
112
+ - 6
113
+ - 0
114
+ version: 2.6.0
115
+ type: :development
116
+ version_requirements: *id006
117
+ - !ruby/object:Gem::Dependency
118
+ name: rspec-core
119
+ prerelease: false
120
+ requirement: &id007 !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ hash: 3
126
+ segments:
127
+ - 0
128
+ version: "0"
129
+ type: :development
130
+ version_requirements: *id007
131
+ - !ruby/object:Gem::Dependency
132
+ name: rspec-expectations
133
+ prerelease: false
134
+ requirement: &id008 !ruby/object:Gem::Requirement
135
+ none: false
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ hash: 3
140
+ segments:
141
+ - 0
142
+ version: "0"
143
+ type: :development
144
+ version_requirements: *id008
145
+ - !ruby/object:Gem::Dependency
146
+ name: mocha
147
+ prerelease: false
148
+ requirement: &id009 !ruby/object:Gem::Requirement
149
+ none: false
150
+ requirements:
151
+ - - ">="
152
+ - !ruby/object:Gem::Version
153
+ hash: 3
154
+ segments:
155
+ - 0
156
+ version: "0"
157
+ type: :development
158
+ version_requirements: *id009
159
+ - !ruby/object:Gem::Dependency
160
+ name: timecop
161
+ prerelease: false
162
+ requirement: &id010 !ruby/object:Gem::Requirement
163
+ none: false
164
+ requirements:
165
+ - - ">="
166
+ - !ruby/object:Gem::Version
167
+ hash: 3
168
+ segments:
169
+ - 0
170
+ version: "0"
171
+ type: :development
172
+ version_requirements: *id010
173
+ description: A simple library that leverages Event Machine to issue requests to the Amazon SQS service while blocking as little as possible
174
+ email: contact@edgecase.com
175
+ executables: []
176
+
177
+ extensions: []
178
+
179
+ extra_rdoc_files: []
180
+
181
+ files:
182
+ - lib/sqs.rb
183
+ - lib/sqs_attributes.rb
184
+ - lib/sqs_message.rb
185
+ - lib/sqs_queue.rb
186
+ - spec/fixtures/delete_message.xml
187
+ - spec/fixtures/error_response.xml
188
+ - spec/fixtures/list_queues.xml
189
+ - spec/fixtures/queue_attributes.xml
190
+ - spec/fixtures/receive_message.xml
191
+ - spec/spec_helper.rb
192
+ - spec/sqs_attributes_spec.rb
193
+ - spec/sqs_message_spec.rb
194
+ - spec/sqs_queue_spec.rb
195
+ - spec/sqs_spec.rb
196
+ has_rdoc: true
197
+ homepage: https://github.com/edgecase/sqs_async
198
+ licenses: []
199
+
200
+ post_install_message:
201
+ rdoc_options: []
202
+
203
+ require_paths:
204
+ - lib
205
+ required_ruby_version: !ruby/object:Gem::Requirement
206
+ none: false
207
+ requirements:
208
+ - - ">="
209
+ - !ruby/object:Gem::Version
210
+ hash: 3
211
+ segments:
212
+ - 0
213
+ version: "0"
214
+ required_rubygems_version: !ruby/object:Gem::Requirement
215
+ none: false
216
+ requirements:
217
+ - - ">="
218
+ - !ruby/object:Gem::Version
219
+ hash: 3
220
+ segments:
221
+ - 0
222
+ version: "0"
223
+ requirements: []
224
+
225
+ rubyforge_project: sqs_async
226
+ rubygems_version: 1.5.0
227
+ signing_key:
228
+ specification_version: 3
229
+ summary: Non-Blocking SQS library.
230
+ test_files:
231
+ - spec/fixtures/delete_message.xml
232
+ - spec/fixtures/error_response.xml
233
+ - spec/fixtures/list_queues.xml
234
+ - spec/fixtures/queue_attributes.xml
235
+ - spec/fixtures/receive_message.xml
236
+ - spec/spec_helper.rb
237
+ - spec/sqs_attributes_spec.rb
238
+ - spec/sqs_message_spec.rb
239
+ - spec/sqs_queue_spec.rb
240
+ - spec/sqs_spec.rb