lsqs 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.
- checksums.yaml +7 -0
- data/.gitignore +7 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +54 -0
- data/Rakefile +1 -0
- data/bin/console +6 -0
- data/bin/lsqs-server +4 -0
- data/config/template.xml.liquid +9 -0
- data/config.ru +4 -0
- data/lib/lsqs/action_router.rb +35 -0
- data/lib/lsqs/actions/base.rb +51 -0
- data/lib/lsqs/actions/change_message_visibility.rb +23 -0
- data/lib/lsqs/actions/create_queue.rb +22 -0
- data/lib/lsqs/actions/delete_message.rb +22 -0
- data/lib/lsqs/actions/delete_message_batch.rb +36 -0
- data/lib/lsqs/actions/delete_queue.rb +18 -0
- data/lib/lsqs/actions/get_queue_url.rb +23 -0
- data/lib/lsqs/actions/list_queues.rb +22 -0
- data/lib/lsqs/actions/purge_queue.rb +19 -0
- data/lib/lsqs/actions/receive_message.rb +27 -0
- data/lib/lsqs/actions/send_message.rb +21 -0
- data/lib/lsqs/actions/send_message_batch.rb +42 -0
- data/lib/lsqs/error_handler.rb +65 -0
- data/lib/lsqs/message.rb +49 -0
- data/lib/lsqs/queue.rb +176 -0
- data/lib/lsqs/queue_list.rb +90 -0
- data/lib/lsqs/server.rb +59 -0
- data/lib/lsqs/version.rb +3 -0
- data/lib/lsqs/xml_template.rb +54 -0
- data/lib/lsqs.rb +45 -0
- data/lsqs.gemspec +31 -0
- data/spec/lsqs/action_router_spec.rb +21 -0
- data/spec/lsqs/aws_sdk_actions_spec.rb +346 -0
- data/spec/lsqs/message_spec.rb +61 -0
- data/spec/lsqs/queue_list_spec.rb +99 -0
- data/spec/lsqs/queue_spec.rb +192 -0
- data/spec/lsqs/xml_template_spec.rb +64 -0
- data/spec/spec_helper.rb +24 -0
- metadata +232 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7ffe37c92591bcb25697b60e65c4786ec81443ad
|
4
|
+
data.tar.gz: 3030401e3eea31364806a2c77412381e69eba483
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bd0452e069a1c855dd6439e9076e81cb1a213a53b3741f4c001c39aa7111676beb3a23ecf957068646a091e71c4022bdfba445940c0e55b3b89b5afa8e4454dc
|
7
|
+
data.tar.gz: 2ebb96c28769c1df0b2b21a43595eea9ba1a9687ec837bded0ec8a0604adf8bf889e36fb3099a3d2f33f4c8385c07390283b2e6f5000e1298322f03dd6b0bf47
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 giannismelidis
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# README
|
2
|
+
|
3
|
+
This is a Sinatra server (using Puma) that mimics basic functionality of the
|
4
|
+
Amazon SQS Service (for development purposes).
|
5
|
+
|
6
|
+
The messages are stored in hashes therefore they are not persisted. When you
|
7
|
+
shut down the server, the messages are lost.
|
8
|
+
|
9
|
+
There is no authentication mechanism in place (yet), so no access key id and
|
10
|
+
secret key are needed.
|
11
|
+
|
12
|
+
At the moment these types of transactions are implemented:
|
13
|
+
`CreateQueue`
|
14
|
+
`PurgeQueue`
|
15
|
+
`ListQueues`
|
16
|
+
`DeleteQueue`
|
17
|
+
`GetQueueUrl`
|
18
|
+
`ReceiveMessage`
|
19
|
+
`SendMessage`
|
20
|
+
`SendMessageBatch`
|
21
|
+
`DeleteMessage`
|
22
|
+
`DeleteMessageBatch`
|
23
|
+
`ChangeMessageVisibility`
|
24
|
+
|
25
|
+
## Requirements
|
26
|
+
|
27
|
+
* Ruby 2.2 or newer
|
28
|
+
|
29
|
+
## Installation
|
30
|
+
|
31
|
+
Just install the gem:
|
32
|
+
|
33
|
+
gem install lsqs
|
34
|
+
|
35
|
+
It doesn't require the `aws-sdk` itself.
|
36
|
+
|
37
|
+
## Usage
|
38
|
+
|
39
|
+
Run `lsqs-server` in the console.
|
40
|
+
|
41
|
+
In your application set the AWS configuration like this (change `base_url` and
|
42
|
+
`port` number if you are not using the default ones):
|
43
|
+
|
44
|
+
```
|
45
|
+
|
46
|
+
require 'aws-sdk' # version 2
|
47
|
+
|
48
|
+
# it requires a dot in the URI when polling (to retrieve the region)
|
49
|
+
# so 'localhost' won't work.
|
50
|
+
base_url = '127.0.0.1'
|
51
|
+
port = 9292
|
52
|
+
|
53
|
+
Aws.config.update(:endpoint => "http://#{base_url}:#{port}")
|
54
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
data/bin/console
ADDED
data/bin/lsqs-server
ADDED
data/config.ru
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
module LSQS
|
2
|
+
class ActionRouter
|
3
|
+
class ActionError < NameError; end
|
4
|
+
attr_reader :queue_list
|
5
|
+
|
6
|
+
##
|
7
|
+
# @param [LSQS::QueueList] queue_list
|
8
|
+
#
|
9
|
+
def initialize(queue_list)
|
10
|
+
@queue_list = queue_list
|
11
|
+
end
|
12
|
+
|
13
|
+
##
|
14
|
+
# Distributes an action to the appropriate class. If an action does not
|
15
|
+
# exist, it throws an error.
|
16
|
+
#
|
17
|
+
# @param [String] action_name
|
18
|
+
# @param [Hash] options
|
19
|
+
#
|
20
|
+
# @return [LSQS::Actions::Base]
|
21
|
+
#
|
22
|
+
def distribute(action_name, options)
|
23
|
+
if LSQS::Actions.const_defined?(action_name)
|
24
|
+
action = LSQS::Actions.const_get(action_name).new(queue_list)
|
25
|
+
queue_list.query do
|
26
|
+
action.perform(options)
|
27
|
+
end
|
28
|
+
|
29
|
+
return action
|
30
|
+
else
|
31
|
+
raise ActionError, "undefined action `#{action_name}`"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end # ActionRouter
|
35
|
+
end # LSQS
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module LSQS
|
2
|
+
module Actions
|
3
|
+
class Base
|
4
|
+
attr_accessor :queue_list
|
5
|
+
attr_reader :builder
|
6
|
+
|
7
|
+
def initialize(queue_list)
|
8
|
+
@queue_list = queue_list
|
9
|
+
end
|
10
|
+
|
11
|
+
##
|
12
|
+
# Returns the name of the class without namespacing.
|
13
|
+
#
|
14
|
+
# @return [String]
|
15
|
+
#
|
16
|
+
def name
|
17
|
+
return self.class.name.split('::').last
|
18
|
+
end
|
19
|
+
|
20
|
+
##
|
21
|
+
# Initializes a XML builder.
|
22
|
+
#
|
23
|
+
# @return [Builder::XmlMarkup]
|
24
|
+
#
|
25
|
+
def builder
|
26
|
+
@builder ||= Builder::XmlMarkup.new(:indent => 2)
|
27
|
+
end
|
28
|
+
|
29
|
+
##
|
30
|
+
# Outputs XML from the builder as a string.
|
31
|
+
#
|
32
|
+
# @return [String]
|
33
|
+
#
|
34
|
+
def to_xml
|
35
|
+
builder.target!
|
36
|
+
end
|
37
|
+
|
38
|
+
##
|
39
|
+
# Builds the URL of the queue.
|
40
|
+
#
|
41
|
+
# @param [String] base_url
|
42
|
+
# @param [String] queue_name
|
43
|
+
|
44
|
+
# @return [String]
|
45
|
+
#
|
46
|
+
def build_url(base_url, queue_name)
|
47
|
+
return "#{base_url}/#{queue_name}"
|
48
|
+
end
|
49
|
+
end # Base
|
50
|
+
end # Actions
|
51
|
+
end # LSQS
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module LSQS
|
2
|
+
module Actions
|
3
|
+
class ChangeMessageVisibility < Base
|
4
|
+
##
|
5
|
+
# Performs the specific action.
|
6
|
+
#
|
7
|
+
# @param [Hash] params
|
8
|
+
#
|
9
|
+
# @return [String]
|
10
|
+
#
|
11
|
+
def perform(params)
|
12
|
+
name = params['QueueName']
|
13
|
+
visibility = params['VisibilityTimeout']
|
14
|
+
receipt = params['ReceiptHandle']
|
15
|
+
queue = queue_list.find(name)
|
16
|
+
|
17
|
+
queue.change_message_visibility(receipt, visibility.to_i)
|
18
|
+
|
19
|
+
return
|
20
|
+
end
|
21
|
+
end # ChangeMessageVisibility
|
22
|
+
end # Actions
|
23
|
+
end # LSQS
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module LSQS
|
2
|
+
module Actions
|
3
|
+
class CreateQueue < Base
|
4
|
+
##
|
5
|
+
# Performs the specific action.
|
6
|
+
#
|
7
|
+
# @param [Hash] params
|
8
|
+
#
|
9
|
+
# @return [String]
|
10
|
+
#
|
11
|
+
def perform(params)
|
12
|
+
name = params['QueueName']
|
13
|
+
queue = queue_list.create(name, params)
|
14
|
+
|
15
|
+
base_url = params['base_url']
|
16
|
+
url = build_url(base_url, name)
|
17
|
+
|
18
|
+
builder.QueueUrl build_url(base_url, name)
|
19
|
+
end
|
20
|
+
end # CreateQueue
|
21
|
+
end # Actions
|
22
|
+
end # LSQS
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module LSQS
|
2
|
+
module Actions
|
3
|
+
class DeleteMessage < Base
|
4
|
+
##
|
5
|
+
# Performs the specific action.
|
6
|
+
#
|
7
|
+
# @param [Hash] params
|
8
|
+
#
|
9
|
+
# @return [String]
|
10
|
+
#
|
11
|
+
def perform(params)
|
12
|
+
name = params['QueueName']
|
13
|
+
|
14
|
+
queue = queue_list.find(name)
|
15
|
+
|
16
|
+
receipt = params['ReceiptHandle']
|
17
|
+
queue.delete_message(receipt)
|
18
|
+
return
|
19
|
+
end
|
20
|
+
end # DeleteMessage
|
21
|
+
end # Actions
|
22
|
+
end # LSQS
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module LSQS
|
2
|
+
module Actions
|
3
|
+
class DeleteMessageBatch < Base
|
4
|
+
##
|
5
|
+
# Performs the specific action.
|
6
|
+
#
|
7
|
+
# @param [Hash] params
|
8
|
+
#
|
9
|
+
# @return [String]
|
10
|
+
#
|
11
|
+
def perform(params)
|
12
|
+
name = params['QueueName']
|
13
|
+
queue = queue_list.find(name)
|
14
|
+
|
15
|
+
queue = queue_list.find(name)
|
16
|
+
receipts = params.select do |key, value|
|
17
|
+
key.match(/DeleteMessageBatchRequestEntry\.\d+\.ReceiptHandle/)
|
18
|
+
end
|
19
|
+
|
20
|
+
deleted = []
|
21
|
+
|
22
|
+
receipts.each do |key, value|
|
23
|
+
id = key.split('.')[1]
|
24
|
+
queue.delete_message(value)
|
25
|
+
deleted << params["DeleteMessageBatchRequestEntry.#{id}.Id"]
|
26
|
+
end
|
27
|
+
|
28
|
+
deleted.compact.each do |id|
|
29
|
+
builder.DeleteMessageBatchResultEntry do
|
30
|
+
builder.Id id
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end # DeleteMessageBatch
|
35
|
+
end # Actions
|
36
|
+
end # LSQS
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module LSQS
|
2
|
+
module Actions
|
3
|
+
class DeleteQueue < Base
|
4
|
+
##
|
5
|
+
# Performs the specific action.
|
6
|
+
#
|
7
|
+
# @param [Hash] params
|
8
|
+
#
|
9
|
+
# @return [String]
|
10
|
+
#
|
11
|
+
def perform(params)
|
12
|
+
name = params['QueueName']
|
13
|
+
queue = queue_list.delete(name)
|
14
|
+
return
|
15
|
+
end
|
16
|
+
end # DeleteQueue
|
17
|
+
end # Actions
|
18
|
+
end # LSQS
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module LSQS
|
2
|
+
module Actions
|
3
|
+
class GetQueueUrl < Base
|
4
|
+
##
|
5
|
+
# Performs the specific action.
|
6
|
+
#
|
7
|
+
# @param [Hash] params
|
8
|
+
#
|
9
|
+
# @return [String]
|
10
|
+
#
|
11
|
+
def perform(params)
|
12
|
+
base_url = params['base_url']
|
13
|
+
name = params['QueueName']
|
14
|
+
|
15
|
+
queue = queue_list.delete(name)
|
16
|
+
|
17
|
+
url = build_url(base_url, name)
|
18
|
+
|
19
|
+
builder.QueueUrl build_url(base_url, name)
|
20
|
+
end
|
21
|
+
end # GetQueueUrl
|
22
|
+
end # Actions
|
23
|
+
end # LSQS
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module LSQS
|
2
|
+
module Actions
|
3
|
+
class ListQueues < Base
|
4
|
+
##
|
5
|
+
# Performs the specific action.
|
6
|
+
#
|
7
|
+
# @param [Hash] params
|
8
|
+
#
|
9
|
+
# @return [String]
|
10
|
+
#
|
11
|
+
def perform(params)
|
12
|
+
base_url = params['base_url']
|
13
|
+
|
14
|
+
queues = queue_list.inspect(params)
|
15
|
+
|
16
|
+
queues.each do |queue|
|
17
|
+
builder.QueueUrl build_url(base_url, queue)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end # ListQueues
|
21
|
+
end # Actions
|
22
|
+
end # LSQS
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module LSQS
|
2
|
+
module Actions
|
3
|
+
class PurgeQueue < Base
|
4
|
+
##
|
5
|
+
# Performs the specific action.
|
6
|
+
#
|
7
|
+
# @param [Hash] params
|
8
|
+
#
|
9
|
+
# @return [String]
|
10
|
+
#
|
11
|
+
def perform(params)
|
12
|
+
name = params['QueueName']
|
13
|
+
queue = queue_list.find(name)
|
14
|
+
queue.purge
|
15
|
+
return
|
16
|
+
end
|
17
|
+
end # PurgeQueue
|
18
|
+
end # Actions
|
19
|
+
end # LSQS
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module LSQS
|
2
|
+
module Actions
|
3
|
+
class ReceiveMessage < Base
|
4
|
+
##
|
5
|
+
# Performs the specific action.
|
6
|
+
#
|
7
|
+
# @param [Hash] params
|
8
|
+
#
|
9
|
+
# @return [String]
|
10
|
+
#
|
11
|
+
def perform(params)
|
12
|
+
name = params['QueueName']
|
13
|
+
queue = queue_list.find(name)
|
14
|
+
messages = queue.get_messages(params)
|
15
|
+
|
16
|
+
messages.each do |receipt, message|
|
17
|
+
builder.Message do
|
18
|
+
builder.MessageId message.id
|
19
|
+
builder.ReceiptHandle receipt
|
20
|
+
builder.MD5OfBody message.md5
|
21
|
+
builder.Body message.body
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end # ReceiveMessage
|
26
|
+
end # Actions
|
27
|
+
end # LSQS
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module LSQS
|
2
|
+
module Actions
|
3
|
+
class SendMessage < Base
|
4
|
+
##
|
5
|
+
# Performs the specific action.
|
6
|
+
#
|
7
|
+
# @param [Hash] params
|
8
|
+
#
|
9
|
+
# @return [String]
|
10
|
+
#
|
11
|
+
def perform(params)
|
12
|
+
name = params['QueueName']
|
13
|
+
queue = queue_list.find(name)
|
14
|
+
message = queue.create_message(params)
|
15
|
+
|
16
|
+
builder.MD5OfMessageBody message.md5
|
17
|
+
builder.MessageId message.id
|
18
|
+
end
|
19
|
+
end # SendMessage
|
20
|
+
end # Actions
|
21
|
+
end # LSQS
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module LSQS
|
2
|
+
module Actions
|
3
|
+
class SendMessageBatch < Base
|
4
|
+
##
|
5
|
+
# Performs the specific action.
|
6
|
+
#
|
7
|
+
# @param [Hash] params
|
8
|
+
#
|
9
|
+
# @return [String]
|
10
|
+
#
|
11
|
+
def perform(params)
|
12
|
+
name = params['QueueName']
|
13
|
+
queue = queue_list.find(name)
|
14
|
+
|
15
|
+
messages = params.select do |key, value|
|
16
|
+
key.match(/SendMessageBatchRequestEntry\.\d+\.MessageBody/)
|
17
|
+
end
|
18
|
+
|
19
|
+
result = {}
|
20
|
+
|
21
|
+
messages.each do |key, value|
|
22
|
+
id = key.split('.')[1]
|
23
|
+
msg_id = params["SendMessageBatchRequestEntry.#{id}.Id"]
|
24
|
+
delay = params["SendMessageBatchRequestEntry.#{id}.DelaySeconds"]
|
25
|
+
message = queue.create_message(
|
26
|
+
'MessageBody' => value,
|
27
|
+
'DelaySeconds' => delay
|
28
|
+
)
|
29
|
+
result[msg_id] = message
|
30
|
+
end
|
31
|
+
|
32
|
+
result.each do |msg_id, message|
|
33
|
+
builder.SendMessageBatchResultEntry do
|
34
|
+
builder.MD5OfMessageBody message.md5
|
35
|
+
builder.MessageId message.id
|
36
|
+
builder.Id msg_id
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end # SendMessageBatch
|
41
|
+
end # Actions
|
42
|
+
end # LSQS
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module LSQS
|
2
|
+
class ErrorHandler
|
3
|
+
ERROR_LIST = {
|
4
|
+
'AccessDenied' => 403,
|
5
|
+
'AuthFailure' => 401,
|
6
|
+
'ConflictingQueryParameter' => 400,
|
7
|
+
'InternalError' => 500,
|
8
|
+
'InvalidAccessKeyId' => 401,
|
9
|
+
'InvalidAction' => 400,
|
10
|
+
'InvalidAddress' => 404,
|
11
|
+
'InvalidAttributeName' => 400,
|
12
|
+
'InvalidHttpRequest' => 400,
|
13
|
+
'InvalidMessageContents' => 400,
|
14
|
+
'InvalidParameterCombination' => 400,
|
15
|
+
'InvalidParameterValue' => 400,
|
16
|
+
'InvalidQueryParameter' => 400,
|
17
|
+
'InvalidRequest' => 400,
|
18
|
+
'InvalidSecurity' => 403,
|
19
|
+
'InvalidSecurityToken' => 400,
|
20
|
+
'MalformedVersion' => 400,
|
21
|
+
'MessageTooLong' => 400,
|
22
|
+
'MessageNotInflight' => 400,
|
23
|
+
'MissingClientTokenId' => 403,
|
24
|
+
'MissingCredentials' => 401,
|
25
|
+
'MissingParameter' => 400,
|
26
|
+
'NoSuchVersion' => 400,
|
27
|
+
'NonExistentQueue' => 400,
|
28
|
+
'NotAuthorizedToUseVersion' => 401,
|
29
|
+
'QueueDeletedRecently' => 400,
|
30
|
+
'QueueNameExists' => 400,
|
31
|
+
'ReadCountOutOfRange' => 400,
|
32
|
+
'ReceiptHandleIsInvalid' => 400,
|
33
|
+
'RequestExpired' => 400,
|
34
|
+
'RequestThrottled' => 403,
|
35
|
+
'ServiceUnavailable' => 503,
|
36
|
+
'X509ParseError' => 400
|
37
|
+
}
|
38
|
+
|
39
|
+
def initialize(app)
|
40
|
+
@app = app
|
41
|
+
end
|
42
|
+
|
43
|
+
def call(env)
|
44
|
+
begin
|
45
|
+
@app.call env
|
46
|
+
rescue => error
|
47
|
+
xml = Builder::XmlMarkup.new(:index => 2)
|
48
|
+
|
49
|
+
status = ERROR_LIST[error.message] || 500
|
50
|
+
|
51
|
+
|
52
|
+
xml.ErrorResponse do
|
53
|
+
xml.Error do
|
54
|
+
xml.Type error.message
|
55
|
+
xml.Code status
|
56
|
+
xml.Message error.to_s
|
57
|
+
xml.Detail
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
[status, {}, [LSQS.template.render_error(xml)]]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end # ErrorHandler
|
65
|
+
end # LSQS
|
data/lib/lsqs/message.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
module LSQS
|
2
|
+
class Message
|
3
|
+
attr_reader :body, :id, :md5
|
4
|
+
attr_accessor :visibility_timeout
|
5
|
+
|
6
|
+
def initialize(options = {})
|
7
|
+
@body = options['MessageBody'] || ''
|
8
|
+
@id = options.fetch('Id') { SecureRandom.uuid }
|
9
|
+
@md5 = options.fetch('MD5') { Digest::MD5.hexdigest(body) }
|
10
|
+
end
|
11
|
+
|
12
|
+
def attributes
|
13
|
+
{
|
14
|
+
"MessageBody" => body,
|
15
|
+
"Id" => id,
|
16
|
+
"MD5" => md5,
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
##
|
21
|
+
# Check if a message's visibility has timed out.
|
22
|
+
#
|
23
|
+
# @return [TrueClass|FalseClass]
|
24
|
+
#
|
25
|
+
def expired?
|
26
|
+
visibility_timeout.nil? || visibility_timeout < Time.now
|
27
|
+
end
|
28
|
+
|
29
|
+
##
|
30
|
+
# Sets the time when the message should expire.
|
31
|
+
#
|
32
|
+
# @param [Fixnum] seconds
|
33
|
+
#
|
34
|
+
# @return [Time]
|
35
|
+
#
|
36
|
+
def expire_in(seconds)
|
37
|
+
@visibility_timeout = Time.now + seconds
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
# Resets the visibility time of the message.
|
42
|
+
#
|
43
|
+
# @return [NilClass]
|
44
|
+
#
|
45
|
+
def expire
|
46
|
+
@visibility_timeout = nil
|
47
|
+
end
|
48
|
+
end # Message
|
49
|
+
end # LSQS
|