sqs_transport 1.0.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/LICENSE +20 -0
- data/README +24 -0
- data/lib/sqs/config.rb +32 -0
- data/lib/sqs/message.rb +132 -0
- data/lib/sqs/message_size_error.rb +4 -0
- data/lib/sqs/queue.rb +17 -0
- data/lib/sqs/transport.rb +176 -0
- data/lib/sqs_transport.rb +9 -0
- data/test/mock_queue.rb +13 -0
- data/test/test_helper.rb +15 -0
- data/test/test_sqs_config.rb +57 -0
- data/test/test_sqs_message.rb +221 -0
- data/test/test_sqs_queue.rb +52 -0
- data/test/test_sqs_transport.rb +186 -0
- metadata +87 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 Ben Koski
|
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
@@ -0,0 +1,24 @@
|
|
1
|
+
= sqs_transport
|
2
|
+
|
3
|
+
== OVERVIEW
|
4
|
+
|
5
|
+
sqs_transport is a wrapper around RightScale's excellent {RightAws::SqsGen2 library}[http://rightscale.rubyforge.org/right_aws_gem_doc/]
|
6
|
+
to facilitate simple queue and receive operations.
|
7
|
+
|
8
|
+
sqs_transport has four major components:
|
9
|
+
|
10
|
+
* SQS::Config, a class to hold AWS credentials. You'll need to define credential values for queueing to actually work.
|
11
|
+
* SQS::Queue, a class to easily create RightAws::SqsGen2 instances, given a queue name
|
12
|
+
* SQS::Message, a class allowing arbitrary contents (strings, hashes, arrays) to be queued and dequeued from SQS
|
13
|
+
* SQS::Transport, a mixin to quickly add <tt>queue!</tt>, <tt>dequeue!</tt>, and <tt>receive!</tt> methods to push class data through SQS.
|
14
|
+
|
15
|
+
See class docs for specific examples.
|
16
|
+
|
17
|
+
== LINKS
|
18
|
+
|
19
|
+
* Source code: http://github.com/bkoski/sqs_transport
|
20
|
+
* Documentation: http://sqs-transport.rubyforge.org
|
21
|
+
|
22
|
+
== AUTHOR
|
23
|
+
|
24
|
+
Ben Koski, http://github.com/bkoski, ben.koski (at) gmail.com
|
data/lib/sqs/config.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'facets'
|
2
|
+
|
3
|
+
|
4
|
+
module SQS
|
5
|
+
|
6
|
+
# SQS::Config stores your AWS access_key and secret_access_key. These attributes raise exceptions
|
7
|
+
# if they are checked but have not been set.
|
8
|
+
class Config
|
9
|
+
|
10
|
+
@@access_key = nil
|
11
|
+
@@secret_access_key = nil
|
12
|
+
|
13
|
+
cattr_writer :access_key, :secret_access_key
|
14
|
+
|
15
|
+
def self.access_key
|
16
|
+
raise ArgumentError, "No access key defined!" if @@access_key.nil?
|
17
|
+
return @@access_key
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.secret_access_key
|
21
|
+
raise ArgumentError, "No secret access key defined!" if @@secret_access_key.nil?
|
22
|
+
return @@secret_access_key
|
23
|
+
end
|
24
|
+
|
25
|
+
# Load configuration from a YAML::load-generated hash
|
26
|
+
def self.parse yaml_hash
|
27
|
+
self.access_key = yaml_hash['access_key'] unless yaml_hash['access_key'].nil? || yaml_hash['access_key'].empty?
|
28
|
+
self.secret_access_key = yaml_hash['secret_access_key'] unless yaml_hash['secret_access_key'].nil? || yaml_hash['secret_access_key'].empty?
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
data/lib/sqs/message.rb
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
module SQS
|
2
|
+
|
3
|
+
# SQS::Message provides a light wrapper over the RightAWS SQS API. It embeds the message payload
|
4
|
+
# in a JSON container to allow enqueue time and time_in_queue calculations.
|
5
|
+
#
|
6
|
+
# Note that by default, JSON serialization is used to encode <tt>contents</tt>. This means that
|
7
|
+
# <tt>contents</tt> must be JSON-serializable (i.e. no cyclical objects, singleton strings, etc.)
|
8
|
+
# If this is problematic, the serialization mechanism can be customized by overriding the <tt>serialize</tt>
|
9
|
+
# and <tt>self.deserialize</tt> methods.
|
10
|
+
#
|
11
|
+
# To use, simply instantiate, set the <tt>contents</tt> and call queue!
|
12
|
+
# For example:
|
13
|
+
#
|
14
|
+
# m = SQS::Message.new 'my_test_queue'
|
15
|
+
# m.contents = {:var1 => 1, :var2 => 2}
|
16
|
+
# m.queue!
|
17
|
+
#
|
18
|
+
# pushes a message containing {:var1 => 1, :var2 => 2} to the 'my_test_queue' queue on SQS
|
19
|
+
#
|
20
|
+
# To retrieve the message, simply call:
|
21
|
+
# m = SQS::Message.receive 'my_test_queue'
|
22
|
+
#
|
23
|
+
# You can then inspect the contents
|
24
|
+
# m.contents # returns {'var1' => 1, 'var2' => 2 }
|
25
|
+
# remove from the SQS queue
|
26
|
+
# m.dequeue!
|
27
|
+
# or check the time in queue
|
28
|
+
# m.time_in_queue
|
29
|
+
# You can also retrieve the SQS id for the message with the <tt>id</tt> method.
|
30
|
+
#
|
31
|
+
class Message
|
32
|
+
|
33
|
+
# The raw RightAws message retrieved from SQS
|
34
|
+
attr_accessor :raw_message
|
35
|
+
|
36
|
+
# Payload to be sent across the wire
|
37
|
+
attr_accessor :contents
|
38
|
+
|
39
|
+
attr_accessor :enqueued_at, :received_at, :queue_name
|
40
|
+
|
41
|
+
# Retrieves one or more Message objects from an SQS queue
|
42
|
+
# * <tt>queue_name</tt> is the name of the SQS queue
|
43
|
+
# * <tt>number_to_receive</tt> sets the maximum number of messages to return. If set to 1, a single instance is returned; if > 1 an array is returned. Defaults to 1.
|
44
|
+
#
|
45
|
+
# Valid options:
|
46
|
+
# * <tt>:visiblity</tt> - sets the visiblity timeout on the message in seconds
|
47
|
+
def self.receive queue_name, number_to_receive=1, opts={}
|
48
|
+
messages = SQS::Queue[queue_name].receive_messages(number_to_receive, opts[:visibility])
|
49
|
+
received_at = Time.now.utc
|
50
|
+
messages.map! { |m| self.create_from_raw_message(queue_name, m, received_at) }
|
51
|
+
|
52
|
+
number_to_receive == 1 ? messages.first : messages
|
53
|
+
end
|
54
|
+
|
55
|
+
# Retrives one or more messages from the queue, but sets their visiblity to zero so that
|
56
|
+
# they can immediately be picked up by another worker. Useful for previewing messages on the queue.
|
57
|
+
# * <tt>queue_name</tt> is the name of the SQS queue
|
58
|
+
# * <tt>number_to_view</tt> sets the maximum number of messages to return. If set to 1, a single instance is returned; if > 1 an array is returned. Defaults to 1.
|
59
|
+
# No options at this time.
|
60
|
+
def self.peek queue_name, number_to_view=1, opts={}
|
61
|
+
self.receive(queue_name, number_to_view, :visibility => 0)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Initialize with the name of the name of the SQS queue. When queue! is called on an instance,
|
65
|
+
# data will be pushed to this queue.
|
66
|
+
def initialize new_queue_name
|
67
|
+
@queue_name = new_queue_name
|
68
|
+
end
|
69
|
+
|
70
|
+
# Returns the SQS id for this message; nil if the message has not yet been queued.
|
71
|
+
def id
|
72
|
+
raw_message ? raw_message.id : nil
|
73
|
+
end
|
74
|
+
|
75
|
+
# Serializes <tt>contents</tt> and pushes data onto the SQS queue.
|
76
|
+
def queue!
|
77
|
+
@enqueued_at = Time.now.utc
|
78
|
+
raise SQS::MessageSizeError, "Message exceeds 8k limit by #{sqs_message_body.size - 8_000} bytes" if sqs_message_body.size > 8_000
|
79
|
+
raw_message = SQS::Queue[queue_name].push(sqs_message_body)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Call after retrieving to delete the message from SQS so that it cannot be retrieved by another client.
|
83
|
+
def dequeue!
|
84
|
+
raw_message.delete
|
85
|
+
end
|
86
|
+
|
87
|
+
# Returns time message spent on queue in seconds.
|
88
|
+
# Raises an ArgumentError if called on a message that has not been dequeued.
|
89
|
+
def time_in_queue
|
90
|
+
raise ArgumentError, "This message has not been dequeued properly; either enqueued_at or received_at is nil" if enqueued_at.nil? || received_at.nil?
|
91
|
+
enqueued_at - received_at
|
92
|
+
end
|
93
|
+
|
94
|
+
# Given an object, serialize it to a string. By default, this simply calls to_json
|
95
|
+
# on the object, but could be overriden to serialize using YAML or Marshal.dump.
|
96
|
+
def serialize object
|
97
|
+
object.to_json
|
98
|
+
end
|
99
|
+
|
100
|
+
# Given a string, deserialize an object. By default this calls JSON.parse
|
101
|
+
# but could be overriden to use another deserialization method.
|
102
|
+
def self.deserialize str
|
103
|
+
str.nil? ? nil : JSON.parse(str)
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
# Build the message to send to SQS
|
108
|
+
def sqs_message_body
|
109
|
+
{:contents => self.serialize(contents), :enqueued_at => enqueued_at}.to_json
|
110
|
+
end
|
111
|
+
|
112
|
+
# Create a SQSMessage instance from its compnent parts
|
113
|
+
def self.create_from_raw_message queue_name, raw_message, received_at
|
114
|
+
message = self.new(queue_name)
|
115
|
+
data = self.parse_sqs_message_body(raw_message.body)
|
116
|
+
|
117
|
+
message.contents = data['contents']
|
118
|
+
message.raw_message = raw_message
|
119
|
+
message.enqueued_at = data['enqueued_at']
|
120
|
+
message.received_at = received_at
|
121
|
+
|
122
|
+
return message
|
123
|
+
end
|
124
|
+
|
125
|
+
# Parse a RightAws SQS message body to the :contents, :enqueued_at hash needed to create a new message
|
126
|
+
def self.parse_sqs_message_body message_string
|
127
|
+
message = message_string.blank? ? {} : JSON.parse(message_string)
|
128
|
+
message['contents'] = self.deserialize(message['contents'])
|
129
|
+
return message
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
data/lib/sqs/queue.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
module SQS
|
2
|
+
|
3
|
+
# Call SQS::Queue['queue_name'] to retrieve a RightAws::SqsGen2 queue instance
|
4
|
+
module Queue
|
5
|
+
|
6
|
+
def self.[] queue_name
|
7
|
+
@sqs ||= RightAws::SqsGen2.new(SQS::Config.access_key, SQS::Config.secret_access_key, :logger => self.logger)
|
8
|
+
@sqs.queue(queue_name, true)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.logger
|
12
|
+
logger = Logger.new(STDOUT)
|
13
|
+
logger.level = Logger::FATAL
|
14
|
+
return logger
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,176 @@
|
|
1
|
+
module SQS
|
2
|
+
|
3
|
+
# Include the SQS::Transport mixin in a class to add SQS enqueue and dequeue capabilities.
|
4
|
+
#
|
5
|
+
# After including, call <tt>set_queue_name</tt> to specify which SQS queue will receive messages.
|
6
|
+
#
|
7
|
+
# There are two ways to define the data that will be included in queued messages:
|
8
|
+
# * call <tt>include_in_sqs_message</tt> with an array of attributes to include
|
9
|
+
# * implement <tt>to_sqs_message</tt> and return an :attr => value hash
|
10
|
+
#
|
11
|
+
# <tt>validate_message</tt> can be implemented to validate message data before it is pushed to SQS.
|
12
|
+
# If this method raises an exception, the message will not be queued.
|
13
|
+
#
|
14
|
+
# As an example:
|
15
|
+
#
|
16
|
+
# class MyMessage
|
17
|
+
# include SQS::Transport
|
18
|
+
#
|
19
|
+
# set_queue_name :widgets
|
20
|
+
#
|
21
|
+
# attr_accessor :color, :size
|
22
|
+
# include_in_sqs_message :color, :size
|
23
|
+
#
|
24
|
+
# def validate_message
|
25
|
+
# raise "Must have both size and color" if color.nil? || size.nil?
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# creates a class that would then allow:
|
31
|
+
#
|
32
|
+
# message = MyMessage.new
|
33
|
+
# message.color = 'red'
|
34
|
+
# message.size = 'xtrasmall'
|
35
|
+
# message.queue!
|
36
|
+
#
|
37
|
+
# at which point a :size => trasmall, :color => red message would be pushed onto the "widgets" SQS queue
|
38
|
+
#
|
39
|
+
# A client using the same class could then call:
|
40
|
+
#
|
41
|
+
# incoming = MyMessage.receive
|
42
|
+
# puts incoming.color # "red"
|
43
|
+
# puts incoming.size # "xtrasmall"
|
44
|
+
# incoming.dequeue! # message is removed from SQS queue
|
45
|
+
#
|
46
|
+
# Note that by default JSON serializtion is used, so some type semanitics are not preseved.
|
47
|
+
# For example, if you set <tt>incoming.color</tt> to <tt>{:shade => :red}</tt> the data would be received as a string (<tt>{'shade' => 'red'}</tt>)
|
48
|
+
# The serialization method is customizable by overriding <tt>serialize</tt> on SQS::Message.
|
49
|
+
#
|
50
|
+
# SQS::Transport stamps the enqueue and dequeue times, which can be used to calculate time in queue
|
51
|
+
#
|
52
|
+
# puts incoming.enqueued_at # Mon Jul 06 22:16:15 UTC 2009
|
53
|
+
# puts incoming.dequeued_at # Mon Jul 06 22:16:25 UTC 2009
|
54
|
+
# puts incoming.time_in_queue # 10
|
55
|
+
#
|
56
|
+
# In addition, the class includes a <tt>peek</tt> method that can be used to inspect queued messages without removing them from the queue.
|
57
|
+
#
|
58
|
+
module Transport
|
59
|
+
|
60
|
+
def self.included(base) # :nodoc:
|
61
|
+
base.extend ClassMethods
|
62
|
+
end
|
63
|
+
|
64
|
+
module ClassMethods
|
65
|
+
|
66
|
+
# Defines associated SQS queue
|
67
|
+
def set_queue_name name
|
68
|
+
@sqs_queue_name = name.to_s
|
69
|
+
end
|
70
|
+
|
71
|
+
# Returns name of associated SQS Queue; raises exception if name has not yet been defined
|
72
|
+
def sqs_queue_name
|
73
|
+
raise "undefined queue name!" if @sqs_queue_name.nil?
|
74
|
+
@sqs_queue_name
|
75
|
+
end
|
76
|
+
|
77
|
+
# Defines the attributes to be included in the message sent to SQS. Not necessary if <tt>to_sqs_message</tt> is overridden.
|
78
|
+
def include_in_sqs_message *attrs_to_include
|
79
|
+
@attrs_for_sqs_message = attrs_to_include
|
80
|
+
end
|
81
|
+
|
82
|
+
# Returns the list of attrs to be sent to SQS; raises an exception if attrs have not yet been defined.
|
83
|
+
def attrs_for_sqs_message
|
84
|
+
raise "Message requires at least one attribute. Call include_in_sqs_message to define which attributes are included in SQS message" if @attrs_for_sqs_message.nil? || @attrs_for_sqs_message.empty?
|
85
|
+
@attrs_for_sqs_message
|
86
|
+
end
|
87
|
+
|
88
|
+
# Pops one or more messages off the SQS queue, parses the contents, and returns them as instances of the class.
|
89
|
+
# * <tt>number_to_recieve</tt> is optional. If not passed, a single message will be returned. If number_to_receive == 1, a single instance will be returned; otherwise an array will be returned.
|
90
|
+
#
|
91
|
+
# Valid options:
|
92
|
+
# * <tt>:visiblity</tt> - sets the visiblity timeout on the message in seconds
|
93
|
+
def receive number_to_receive=1, opts={}
|
94
|
+
result = SQS::Message.receive(self.sqs_queue_name, number_to_receive, opts)
|
95
|
+
|
96
|
+
if number_to_receive == 1
|
97
|
+
reconstitute_instance(result)
|
98
|
+
else
|
99
|
+
result.map {|m| reconstitute_instance(m)}
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def reconstitute_instance sqs_message
|
104
|
+
new_instance = self.new
|
105
|
+
sqs_message.contents.each { |field, value| new_instance.send("#{field}=", value) }
|
106
|
+
new_instance.sqs_message = sqs_message
|
107
|
+
return new_instance
|
108
|
+
end
|
109
|
+
|
110
|
+
# Retrives one or more messages from the queue, but sets their visiblity to zero so that
|
111
|
+
# they can immediately be picked up by another worker. Useful for previewing messages on the queue.
|
112
|
+
# * <tt>queue_name</tt> is the name of the SQS queue
|
113
|
+
# * <tt>number_to_view</tt> sets the maximum number of messages to return. If set to 1, a single instance is returned; if > 1 an array is returned. Defaults to 1.
|
114
|
+
# No options at this time.
|
115
|
+
def peek number_to_view=1, opts={}
|
116
|
+
self.receive(number_to_view, opts.merge(:visibility => 0))
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
attr_writer :sqs_message
|
122
|
+
|
123
|
+
# Returns a hash that will be serialized and sent to SQS. By default, returns a <tt>{'attr' => 'value'}</tt>
|
124
|
+
# hash containing all attributes defined by the <tt>include_in_sqs_message</tt> call.
|
125
|
+
#
|
126
|
+
# Override this to return a custom {'attr' => 'value'} hash for more control over serialization.
|
127
|
+
def to_sqs_message
|
128
|
+
Hash[*self.class.attrs_for_sqs_message.collect {|a| [a, self.send(a)]}.flatten]
|
129
|
+
end
|
130
|
+
|
131
|
+
# Implement <tt>validate_message</tt> to check message data before it is sent to SQS.
|
132
|
+
# If this method raises an exception, message will not be queued.
|
133
|
+
def validate_message
|
134
|
+
end
|
135
|
+
|
136
|
+
# Validates the message, then pushes it onto the associated queue.
|
137
|
+
# If validation raises an exception, the message will not be queued and the exception will bubble up.
|
138
|
+
def queue!
|
139
|
+
validate_message
|
140
|
+
sqs_message.contents = to_sqs_message
|
141
|
+
sqs_message.queue!
|
142
|
+
end
|
143
|
+
|
144
|
+
# Removes a retrieved instance from the SQS queue.
|
145
|
+
def dequeue!
|
146
|
+
sqs_message.dequeue!
|
147
|
+
end
|
148
|
+
|
149
|
+
# Returns the associated SQS::Message instance
|
150
|
+
def sqs_message
|
151
|
+
@sqs_message ||= SQS::Message.new(self.class.sqs_queue_name)
|
152
|
+
return @sqs_message
|
153
|
+
end
|
154
|
+
|
155
|
+
# Returns the Amazon id for the SQS message.
|
156
|
+
def sqs_message_id
|
157
|
+
sqs_message.id
|
158
|
+
end
|
159
|
+
|
160
|
+
# Returns the time the message was queued
|
161
|
+
def enqueued_at
|
162
|
+
sqs_message.enqueued_at
|
163
|
+
end
|
164
|
+
|
165
|
+
# Returns the time the message was dequeued
|
166
|
+
def dequeued_at
|
167
|
+
sqs_message.dequeued_at
|
168
|
+
end
|
169
|
+
|
170
|
+
# Returns the amount of time a message spent in the queue, in seconds.
|
171
|
+
def time_in_queue
|
172
|
+
sqs_message.time_in_queue
|
173
|
+
end
|
174
|
+
|
175
|
+
end
|
176
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'json/add/core'
|
3
|
+
require 'right_aws'
|
4
|
+
|
5
|
+
require File.join(File.dirname(__FILE__), 'sqs/config')
|
6
|
+
require File.join(File.dirname(__FILE__), 'sqs/queue')
|
7
|
+
require File.join(File.dirname(__FILE__), 'sqs/message_size_error')
|
8
|
+
require File.join(File.dirname(__FILE__), 'sqs/message')
|
9
|
+
require File.join(File.dirname(__FILE__), 'sqs/transport')
|
data/test/mock_queue.rb
ADDED
data/test/test_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'shoulda'
|
4
|
+
require 'mocha'
|
5
|
+
require 'time_warp' # on github as 'iridesco-time-warp'
|
6
|
+
|
7
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
8
|
+
require 'sqs_transport'
|
9
|
+
require 'mock_queue'
|
10
|
+
|
11
|
+
SQS::Config.access_key = 'test1234'
|
12
|
+
SQS::Config.secret_access_key = 'ASDF KEY'
|
13
|
+
|
14
|
+
class Test::Unit::TestCase
|
15
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
class TestSQSConfig < Test::Unit::TestCase
|
4
|
+
|
5
|
+
context "defaults" do
|
6
|
+
setup do
|
7
|
+
SQS::Config.access_key = nil
|
8
|
+
SQS::Config.secret_access_key = nil
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
should "raise an ArgumentError if access_key is undefined" do
|
13
|
+
assert_raises(ArgumentError) { SQS::Config.access_key }
|
14
|
+
end
|
15
|
+
|
16
|
+
should "raise an ArgumentError if secret_access_key is undefined" do
|
17
|
+
assert_raises(ArgumentError) { SQS::Config.secret_access_key }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context "setters" do
|
22
|
+
should "return value for access_key if defined" do
|
23
|
+
SQS::Config.access_key = 'TeSt'
|
24
|
+
assert_equal 'TeSt', SQS::Config.access_key
|
25
|
+
end
|
26
|
+
|
27
|
+
should "return value for secret_access_key if defined" do
|
28
|
+
SQS::Config.secret_access_key = 'TeStSecr3t'
|
29
|
+
assert_equal 'TeStSecr3t', SQS::Config.secret_access_key
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "parse" do
|
34
|
+
should "set access_key if provided" do
|
35
|
+
SQS::Config.parse({'access_key' => '1234'})
|
36
|
+
assert_equal '1234', SQS::Config.access_key
|
37
|
+
end
|
38
|
+
|
39
|
+
should "not set access_key if provided as blank string" do
|
40
|
+
SQS::Config.parse({'access_key' => '1234'})
|
41
|
+
SQS::Config.parse({'access_key' => ''})
|
42
|
+
assert_equal '1234', SQS::Config.access_key
|
43
|
+
end
|
44
|
+
|
45
|
+
should "set secret_access_key if provided" do
|
46
|
+
SQS::Config.parse({'secret_access_key' => '1234ABC'})
|
47
|
+
assert_equal '1234ABC', SQS::Config.secret_access_key
|
48
|
+
end
|
49
|
+
|
50
|
+
should "not set secret_access_key if provided as blank string" do
|
51
|
+
SQS::Config.parse({'secret_access_key' => '1234ABC'})
|
52
|
+
SQS::Config.parse({'secret_access_key' => ''})
|
53
|
+
assert_equal '1234ABC', SQS::Config.secret_access_key
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
@@ -0,0 +1,221 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
class SQS::Message
|
4
|
+
public :sqs_message_body
|
5
|
+
end
|
6
|
+
|
7
|
+
class TestSQSMessage < Test::Unit::TestCase
|
8
|
+
|
9
|
+
context "self.receive" do
|
10
|
+
setup do
|
11
|
+
@mock_queue = MockQueue.new
|
12
|
+
SQS::Queue.stubs(:[]).with('test_queue').returns(@mock_queue)
|
13
|
+
end
|
14
|
+
|
15
|
+
should "call sqs_queue.recieve_messages for the specified number of messages" do
|
16
|
+
@mock_queue.expects(:receive_messages).with(7, anything).returns([])
|
17
|
+
SQS::Message.receive('test_queue', 7)
|
18
|
+
end
|
19
|
+
|
20
|
+
should "call sqs_queue.receive for a single message if no message count is specified" do
|
21
|
+
@mock_queue.expects(:receive_messages).with(1, anything).returns([])
|
22
|
+
SQS::Message.receive('test_queue')
|
23
|
+
end
|
24
|
+
|
25
|
+
should "call sqs_queue.receive with visibility specified as :visibility in options" do
|
26
|
+
@mock_queue.expects(:receive_messages).with(anything, 23).returns([])
|
27
|
+
SQS::Message.receive('test_queue', 1, :visibility => 23)
|
28
|
+
end
|
29
|
+
|
30
|
+
should "call sqs_queue.receive with nil visiblity if :visiblity not provided in options" do
|
31
|
+
@mock_queue.expects(:receive_messages).with(anything, nil).returns([])
|
32
|
+
SQS::Message.receive('test_queue', 1)
|
33
|
+
end
|
34
|
+
|
35
|
+
should "return a single instance of class if a single message is requested" do
|
36
|
+
@mock_queue.stubs(:receive_messages).returns([mock_message])
|
37
|
+
assert_kind_of SQS::Message, SQS::Message.receive('test_queue', 1)
|
38
|
+
end
|
39
|
+
|
40
|
+
should "return an array of objects if multiple messages are requested" do
|
41
|
+
message_array = [mock_message, mock_message, mock_message]
|
42
|
+
@mock_queue.stubs(:receive_messages).returns(message_array)
|
43
|
+
assert_equal message_array, SQS::Message.receive('test_queue', 7)
|
44
|
+
end
|
45
|
+
|
46
|
+
should "return an array of objects if multiple messages are requested, even if there is only a single message in the queue" do
|
47
|
+
message_array = [mock_message]
|
48
|
+
@mock_queue.stubs(:receive_messages).returns(message_array)
|
49
|
+
assert_equal message_array, SQS::Message.receive('test_queue', 7)
|
50
|
+
end
|
51
|
+
|
52
|
+
should "set received_at on returned messages to the time dequeue! was invoked" do
|
53
|
+
message_array = [mock_message]
|
54
|
+
@mock_queue.stubs(:receive_messages).returns(message_array)
|
55
|
+
|
56
|
+
expected_received_at = Time.now.utc - 5_000
|
57
|
+
received_message = nil
|
58
|
+
|
59
|
+
pretend_now_is(expected_received_at) do
|
60
|
+
received_message = SQS::Message.receive('test_queue')
|
61
|
+
end
|
62
|
+
|
63
|
+
assert_in_delta expected_received_at, received_message.received_at, 0.5
|
64
|
+
end
|
65
|
+
|
66
|
+
should "stamp a consistent received_at across all messages returned" do
|
67
|
+
message_array = [mock_message, mock_message, mock_message]
|
68
|
+
@mock_queue.stubs(:receive_messages).returns(message_array)
|
69
|
+
|
70
|
+
messages = SQS::Message.receive('test_queue', 3)
|
71
|
+
|
72
|
+
assert_equal 1, messages.collect { |m| m.received_at }.uniq.length
|
73
|
+
end
|
74
|
+
|
75
|
+
should "assign the enqueued_at time on returned message" do
|
76
|
+
expected_message = SQS::Message.new 'test_queue'
|
77
|
+
expected_message.contents = {:value_1 => 1}
|
78
|
+
|
79
|
+
@mock_queue.stubs(:receive_messages).returns([mock_message(expected_message.sqs_message_body)])
|
80
|
+
|
81
|
+
message = SQS::Message.receive('test_queue')
|
82
|
+
assert_equal expected_message.enqueued_at, message.enqueued_at
|
83
|
+
end
|
84
|
+
|
85
|
+
should "assign the contents on returned message" do
|
86
|
+
expected_message = SQS::Message.new 'test_queue'
|
87
|
+
expected_message.contents = {'value_1' => 1}
|
88
|
+
|
89
|
+
@mock_queue.stubs(:receive_messages).returns([mock_message(expected_message.sqs_message_body)])
|
90
|
+
|
91
|
+
message = SQS::Message.receive('test_queue')
|
92
|
+
assert_equal expected_message.contents, message.contents
|
93
|
+
end
|
94
|
+
|
95
|
+
should "assign the raw message returned from SQS to raw_message" do
|
96
|
+
expected_message = mock()
|
97
|
+
expected_message.stubs(:body)
|
98
|
+
@mock_queue.stubs(:receive_messages).returns([expected_message])
|
99
|
+
message = SQS::Message.receive('test_queue')
|
100
|
+
assert_equal expected_message.object_id, message.raw_message.object_id
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context "self.peek" do
|
105
|
+
should "receive number_to_view with :visibility => 0" do
|
106
|
+
SQS::Message.expects(:receive).with('test_queue', 10, :visibility => 0)
|
107
|
+
SQS::Message.peek('test_queue', 10)
|
108
|
+
end
|
109
|
+
|
110
|
+
should "receive 1 message with :visiblity => 0 if number_to_view not specified" do
|
111
|
+
SQS::Message.expects(:receive).with('test_queue', 1, :visibility => 0)
|
112
|
+
SQS::Message.peek('test_queue')
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
context "queue!" do
|
117
|
+
setup do
|
118
|
+
@expected_contents = {:value_1 => 1, :value_2 => 2}
|
119
|
+
@mock_queue = MockQueue.new
|
120
|
+
SQS::Queue.stubs(:[]).with('test_queue').returns(@mock_queue)
|
121
|
+
@test_instance = SQS::Message.new 'test_queue'
|
122
|
+
end
|
123
|
+
|
124
|
+
should "push a JSON message containing :content => serialized_content onto queue specified in init" do
|
125
|
+
@test_instance.contents = @expected_contents
|
126
|
+
@test_instance.queue!
|
127
|
+
|
128
|
+
assert_equal @test_instance.serialize(@expected_contents), JSON.parse(@mock_queue.messages.first)['contents']
|
129
|
+
end
|
130
|
+
|
131
|
+
should "push a JSON message containing :enqueue_time => Time.now.utc onto queue specified in init" do
|
132
|
+
enqueue_time = Time.now
|
133
|
+
|
134
|
+
@test_instance.contents = {:value_1 => 1}
|
135
|
+
pretend_now_is(enqueue_time) do
|
136
|
+
@test_instance.queue!
|
137
|
+
end
|
138
|
+
|
139
|
+
assert_equal enqueue_time.to_i, JSON.parse(@mock_queue.messages.first)['enqueued_at'].to_i
|
140
|
+
end
|
141
|
+
|
142
|
+
should "raise a SQS::MessageSizeError if message contents are too big" do
|
143
|
+
@test_instance.stubs(:sqs_message_body).returns('a' * 10_000)
|
144
|
+
assert_raises(SQS::MessageSizeError) { @test_instance.queue! }
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
context "dequeue!" do
|
149
|
+
should "call delete on the raw message" do
|
150
|
+
raw_message = mock()
|
151
|
+
raw_message.expects(:delete)
|
152
|
+
|
153
|
+
instance = SQS::Message.new 'test_queue'
|
154
|
+
instance.stubs(:raw_message).returns(raw_message)
|
155
|
+
instance.dequeue!
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
context "id" do
|
160
|
+
should "return the id from raw_message if it is set" do
|
161
|
+
expected_id = 'ASDF-1234'
|
162
|
+
raw_message = mock()
|
163
|
+
raw_message.stubs(:id).returns(expected_id)
|
164
|
+
|
165
|
+
instance = SQS::Message.new 'test_queue'
|
166
|
+
instance.stubs(:raw_message).returns(raw_message)
|
167
|
+
|
168
|
+
assert_equal expected_id, instance.id
|
169
|
+
end
|
170
|
+
|
171
|
+
should "return nil if raw_message is not set" do
|
172
|
+
instance = SQS::Message.new 'test_queue'
|
173
|
+
instance.stubs(:raw_message).returns(nil)
|
174
|
+
assert_nil instance.id
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
context "queue_name" do
|
179
|
+
should "return the queue name specified at init time" do
|
180
|
+
expected_name = 'test_queue'
|
181
|
+
instance = SQS::Message.new expected_name
|
182
|
+
assert_equal expected_name, instance.queue_name
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
context "time_in_queue" do
|
187
|
+
should "raise an ArgumentError if enqueued_at is nil" do
|
188
|
+
instance = SQS::Message.new 'test_queue'
|
189
|
+
instance.stubs(:enqueued_at).returns(nil)
|
190
|
+
instance.stubs(:received_at).returns(DateTime.now)
|
191
|
+
assert_raises(ArgumentError) { instance.time_in_queue }
|
192
|
+
end
|
193
|
+
|
194
|
+
should "raise an ArgumentError if received_at is nil" do
|
195
|
+
instance = SQS::Message.new 'test_queue'
|
196
|
+
instance.stubs(:enqueued_at).returns(nil)
|
197
|
+
instance.stubs(:received_at).returns(DateTime.now)
|
198
|
+
assert_raises(ArgumentError) { instance.time_in_queue }
|
199
|
+
end
|
200
|
+
|
201
|
+
should "return received_at - enqueued_at" do
|
202
|
+
instance = SQS::Message.new 'test_queue'
|
203
|
+
|
204
|
+
expected_received_at = DateTime.now
|
205
|
+
expected_enqueued_at = expected_received_at - 200
|
206
|
+
|
207
|
+
instance.stubs(:enqueued_at).returns(expected_enqueued_at)
|
208
|
+
instance.stubs(:received_at).returns(expected_received_at)
|
209
|
+
assert_equal expected_enqueued_at - expected_received_at, instance.time_in_queue
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
private
|
214
|
+
def mock_message mock_body=nil
|
215
|
+
message = mock()
|
216
|
+
message.stubs(:body).returns(mock_body)
|
217
|
+
|
218
|
+
return message
|
219
|
+
end
|
220
|
+
|
221
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
# Queue caches its RightAws instance; this needs to be busted between tests
|
4
|
+
module SQS
|
5
|
+
module Queue
|
6
|
+
def self.flush_cache
|
7
|
+
@sqs = nil
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class TestSQSQueue < Test::Unit::TestCase
|
13
|
+
|
14
|
+
def setup
|
15
|
+
@mock_right_aws = mock()
|
16
|
+
@mock_right_aws.stubs(:queue)
|
17
|
+
end
|
18
|
+
|
19
|
+
def teardown
|
20
|
+
SQS::Queue.flush_cache
|
21
|
+
end
|
22
|
+
|
23
|
+
should "instantiate a new RightAws::SQSGen2 using the access key from the SQS::Config" do
|
24
|
+
SQS::Config.access_key = 'ASDF'
|
25
|
+
RightAws::SqsGen2.expects(:new).with(SQS::Config.access_key, anything, anything).returns(@mock_right_aws)
|
26
|
+
SQS::Queue['test_queue']
|
27
|
+
end
|
28
|
+
|
29
|
+
should "instantiate a new RightAws::SQSGen2 using the secret access key from the SQS::Config" do
|
30
|
+
SQS::Config.secret_access_key = 'ASDF123'
|
31
|
+
RightAws::SqsGen2.expects(:new).with(anything, SQS::Config.secret_access_key, anything).returns(@mock_right_aws)
|
32
|
+
SQS::Queue['test_queue']
|
33
|
+
end
|
34
|
+
|
35
|
+
should "make a find/create call for the specified queue" do
|
36
|
+
SQS::Config.secret_access_key = 'ASDF123'
|
37
|
+
RightAws::SqsGen2.stubs(:new).returns(@mock_right_aws)
|
38
|
+
@mock_right_aws.expects(:queue).with('test_queue', true)
|
39
|
+
SQS::Queue['test_queue']
|
40
|
+
end
|
41
|
+
|
42
|
+
should "return a queue object" do
|
43
|
+
SQS::Config.secret_access_key = 'ASDF123'
|
44
|
+
RightAws::SqsGen2.stubs(:new).returns(@mock_right_aws)
|
45
|
+
|
46
|
+
mock_queue = mock()
|
47
|
+
@mock_right_aws.stubs(:queue).returns(mock_queue)
|
48
|
+
|
49
|
+
assert_equal mock_queue.object_id, SQS::Queue['test_queue'].object_id
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,186 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
class TestTransport
|
4
|
+
include SQS::Transport
|
5
|
+
|
6
|
+
attr_reader :source_message # allow source to be read for testing
|
7
|
+
attr_accessor :value1, :value2
|
8
|
+
include_in_sqs_message :value1, :value2
|
9
|
+
|
10
|
+
set_queue_name 'testQ'
|
11
|
+
end
|
12
|
+
|
13
|
+
class TestTransportNoQueue
|
14
|
+
include SQS::Transport
|
15
|
+
|
16
|
+
attr_accessor :value1
|
17
|
+
end
|
18
|
+
|
19
|
+
class TestTransportSymbolQueue
|
20
|
+
include SQS::Transport
|
21
|
+
set_queue_name :testQueue2
|
22
|
+
|
23
|
+
attr_accessor :value1
|
24
|
+
include_in_sqs_message :value1
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
class TestSQSTransport < Test::Unit::TestCase
|
29
|
+
|
30
|
+
context "self.sqs_queue_name" do
|
31
|
+
should "raise an exception if set_queue_name has not been called" do
|
32
|
+
assert_raises(RuntimeError) { TestTransportNoQueue.sqs_queue_name }
|
33
|
+
end
|
34
|
+
|
35
|
+
should "return value set using set_queue_name" do
|
36
|
+
assert_equal 'testQ', TestTransport.sqs_queue_name
|
37
|
+
end
|
38
|
+
|
39
|
+
should "return string, even if set_queue_name awas called with symbol" do
|
40
|
+
assert_equal 'testQueue2', TestTransportSymbolQueue.sqs_queue_name
|
41
|
+
assert_kind_of String, TestTransportSymbolQueue.sqs_queue_name
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "self.attrs_for_sqs_message" do
|
46
|
+
should "raise an exception if include_in_sqs_message has not been called" do
|
47
|
+
assert_raises(RuntimeError) { TestTransportNoQueue.attrs_for_sqs_message }
|
48
|
+
end
|
49
|
+
|
50
|
+
should "return value set using include_in_sqs_message" do
|
51
|
+
assert_equal [:value1, :value2], TestTransport.attrs_for_sqs_message
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context "self.receive" do
|
56
|
+
should "proxy request to SQS::Message.receive" do
|
57
|
+
SQS::Message.expects(:receive).with(TestTransport.sqs_queue_name, 5, :visibility => 10).returns([])
|
58
|
+
TestTransport.receive(5, :visibility => 10)
|
59
|
+
end
|
60
|
+
|
61
|
+
should "return reconstituted instance of original if number_to_receive = 1" do
|
62
|
+
original = TestTransport.new
|
63
|
+
original.value1 = 'test'
|
64
|
+
original.value2 = 10
|
65
|
+
|
66
|
+
SQS::Message.any_instance.stubs(:queue!)
|
67
|
+
original.queue!
|
68
|
+
SQS::Message.stubs(:receive).returns(original.sqs_message)
|
69
|
+
|
70
|
+
new_instance = TestTransport.receive
|
71
|
+
assert_equal original.value1, new_instance.value1
|
72
|
+
assert_equal original.value2, new_instance.value2
|
73
|
+
end
|
74
|
+
|
75
|
+
should "set the new instance's sqs_message = received message" do
|
76
|
+
original = TestTransport.new
|
77
|
+
original.value1 = 'test'
|
78
|
+
original.value2 = 10
|
79
|
+
|
80
|
+
SQS::Message.any_instance.stubs(:queue!)
|
81
|
+
original.queue!
|
82
|
+
SQS::Message.stubs(:receive).returns(original.sqs_message)
|
83
|
+
|
84
|
+
new_instance = TestTransport.receive
|
85
|
+
assert_equal original.sqs_message, new_instance.sqs_message
|
86
|
+
end
|
87
|
+
|
88
|
+
should "return array of reconstituted originals if number_to_receive > 1" do
|
89
|
+
originals = []
|
90
|
+
|
91
|
+
original1 = TestTransport.new
|
92
|
+
original1.value1 = 'test'
|
93
|
+
original1.value2 = 10
|
94
|
+
originals << original1
|
95
|
+
|
96
|
+
original2 = TestTransport.new
|
97
|
+
original2.value1 = 'test2'
|
98
|
+
original2.value2 = 20
|
99
|
+
originals << original2
|
100
|
+
|
101
|
+
SQS::Message.any_instance.stubs(:queue!)
|
102
|
+
originals.each {|o| o.queue!}
|
103
|
+
SQS::Message.stubs(:receive).returns(originals.collect {|o| o.sqs_message})
|
104
|
+
|
105
|
+
instances = TestTransport.receive(3)
|
106
|
+
instances.each_with_index do |actual, i|
|
107
|
+
assert_equal originals[i].value1, actual.value1
|
108
|
+
assert_equal originals[i].value2, actual.value2
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
context "self.peek" do
|
114
|
+
should "call self.receive with :visibility => 0" do
|
115
|
+
TestTransport.expects(:receive).with(5, :visibility => 0)
|
116
|
+
TestTransport.peek(5)
|
117
|
+
end
|
118
|
+
|
119
|
+
should "receive a single instance by default" do
|
120
|
+
TestTransport.expects(:receive).with(1, :visibility => 0)
|
121
|
+
TestTransport.peek
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context "queue!" do
|
126
|
+
setup do
|
127
|
+
@test_instance = TestTransport.new
|
128
|
+
@test_instance.value1 = 'test1'
|
129
|
+
@test_instance.value2 = 'test2'
|
130
|
+
SQS::Message.any_instance.stubs(:queue!)
|
131
|
+
end
|
132
|
+
|
133
|
+
should "call validate_message" do
|
134
|
+
@test_instance.expects(:validate_message)
|
135
|
+
@test_instance.queue!
|
136
|
+
end
|
137
|
+
|
138
|
+
should "not call sqs_message.queue! if validate message throws exception" do
|
139
|
+
@test_instance.stubs(:validate_message).raises(RuntimeError)
|
140
|
+
SQS::Message.any_instance.expects(:queue!).never
|
141
|
+
begin
|
142
|
+
@test_instance.queue!
|
143
|
+
rescue
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
should "set sqs_message.contents = to_sqs_message" do
|
148
|
+
@test_instance.queue!
|
149
|
+
assert_equal @test_instance.to_sqs_message, @test_instance.sqs_message.contents
|
150
|
+
end
|
151
|
+
|
152
|
+
should "invoke queue! on the sqs_message" do
|
153
|
+
@test_instance.sqs_message.expects(:queue!)
|
154
|
+
@test_instance.queue!
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
context "to_sqs_message - default implementation" do
|
159
|
+
should "return attrs_for_sqs_message in hash, with attrs as keys and values as values" do
|
160
|
+
instance = TestTransport.new
|
161
|
+
instance.value1 = '1234'
|
162
|
+
instance.value2 = 'abcd'
|
163
|
+
|
164
|
+
assert_equal({:value1 => '1234', :value2 => 'abcd'}, instance.to_sqs_message)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
context "proxy to SQS::Message instance" do
|
169
|
+
setup do
|
170
|
+
@test_instance = TestTransport.new
|
171
|
+
end
|
172
|
+
|
173
|
+
should "proxy sqs_message_id to sqs_message.id" do
|
174
|
+
@test_instance.sqs_message.expects(:id)
|
175
|
+
@test_instance.sqs_message_id
|
176
|
+
end
|
177
|
+
|
178
|
+
['dequeue!','enqueued_at','dequeued_at','time_in_queue'].each do |proxy_method|
|
179
|
+
should "proxy #{proxy_method} to sqs_message.#{proxy_method}" do
|
180
|
+
@test_instance.sqs_message.expects(proxy_method)
|
181
|
+
@test_instance.send(proxy_method)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
end
|
metadata
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sqs_transport
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ben Koski
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-07-10 00:00:00 -04:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: json
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: right_aws
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
version:
|
35
|
+
description: Provides simple enqueue/dequeue facilities for Amazon SQS.
|
36
|
+
email: gems@benkoski.com
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files: []
|
42
|
+
|
43
|
+
files:
|
44
|
+
- lib/sqs
|
45
|
+
- lib/sqs_transport.rb
|
46
|
+
- lib/sqs/config.rb
|
47
|
+
- lib/sqs/message.rb
|
48
|
+
- lib/sqs/message_size_error.rb
|
49
|
+
- lib/sqs/queue.rb
|
50
|
+
- lib/sqs/transport.rb
|
51
|
+
- test/mock_queue.rb
|
52
|
+
- test/test_helper.rb
|
53
|
+
- test/test_sqs_config.rb
|
54
|
+
- test/test_sqs_message.rb
|
55
|
+
- test/test_sqs_queue.rb
|
56
|
+
- test/test_sqs_transport.rb
|
57
|
+
- README
|
58
|
+
- LICENSE
|
59
|
+
has_rdoc: true
|
60
|
+
homepage: http://github.com/bkoski/sqs_transport
|
61
|
+
post_install_message:
|
62
|
+
rdoc_options:
|
63
|
+
- --inline-source
|
64
|
+
- --charset=UTF-8
|
65
|
+
require_paths:
|
66
|
+
- lib
|
67
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: "0"
|
72
|
+
version:
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: "0"
|
78
|
+
version:
|
79
|
+
requirements: []
|
80
|
+
|
81
|
+
rubyforge_project:
|
82
|
+
rubygems_version: 1.3.1
|
83
|
+
signing_key:
|
84
|
+
specification_version: 2
|
85
|
+
summary: Provides simple enqueue/dequeue facilities for Amazon SQS.
|
86
|
+
test_files: []
|
87
|
+
|