Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

implementing (loosly) the rest of the API and doing a gem version bump

  • Loading branch information...
commit 3ffded0f730717784ddfb32f5724e924b8972ec0 1 parent 85fba6d
@leongersing leongersing authored
View
27 README.md
@@ -38,6 +38,33 @@ is a hash of callbacks. Currently supported are :success and :failure. You can a
client.list_queues( :success => lambda {|queues| puts queues } )
+# Known Issues
+
+At the moment, there is very little validation. So, it's important to validate your
+data prior to placing submitting it to Amazon. Some bits that are important to the
+success of sending a message (for example) are validated (signatures, keys, etc) but
+items like Policies on set_queue_attributes are assumed "good" by the time you pass it in.
+
+This is something that will be added in a future release... Stay Tuned or get your patch on. :)
+
+# Changes
+
+## 0.0.2
+Implicit evaluation of expected actions
+Base implementations of all SQS API methods.
+
+## 0.0.1
+Initial release. Only 3 endpoints supported.
+
+# Long Term Goals
+* Global Error Handling
+* Include Message/AWS specific meta-data to response objects.
+* Async support for other services in the AWS stack.
+* Allow for drop-in alternatives to EventMachine
+
+# Not interested in implementing...
+* Backwards compatibility with past AWS APIs.
+
# Fork it.
We love to write and maintain code but there are only so many hours in a day! :) We encourage others to pick up where we left off and issue pull
View
58 lib/sqs.rb
@@ -18,20 +18,26 @@
module SQS
include SQS::Utilities
-
attr_accessor :aws_key, :aws_secret, :regions, :default_parameters, :post_options
def change_message_visibility(options={})
raise "no Message specified" unless options[:message]
raise "no new visibility_timeout specified" unless options[:visibility_timeout]
- options.merge!(:action => "ChangeMessageVisibility",
- :receipt_handle => options.delete(:message).receipt_handle,
- :visibility_timeout => options.delete(:visibility_timeout).to_i)
+ options.merge!( :receipt_handle => options.delete(:message).receipt_handle,
+ :visibility_timeout => options.delete(:visibility_timeout).to_i)
call_amazon(options)
end
def set_queue_attributes(options={})
- raise "Not Implemented Yet."
+ raise "no target queue specified" unless options[:queue]
+ %w[ :visibility_timeout :policy :maximum_message_size :message_retention_period ].each do |attr_type|
+ if options[attr_type]
+ val = options.delete(attr_type)
+ options.merge! "Attribute.Name" => camelize(attr_type), "Attribute.Value" => val
+ end
+ end
+
+ call_amazon(options)
end
def send_message(options={})
@@ -52,7 +58,6 @@ def add_permission(options={})
end
options.delete(:permissions)
- options.merge!( :action => "AddPermission" )
call_amazon(options)
end
@@ -67,7 +72,6 @@ def remove_permission(options={})
end
options.delete(:permissions)
- options.merge!( :action => "RemovePermission" )
call_amazon(options)
end
@@ -76,7 +80,6 @@ def list_queues(options={})
prefix = options.delete(:prefix)
match = options.delete(:match)
- options.merge!( :action => "ListQueues" )
options.merge!( :queue_name_prefix => encode(prefix) ) if prefix
call_amazon(options) do |req|
@@ -89,33 +92,29 @@ def list_queues(options={})
def receive_message(options={})
raise "no target queue specified" unless options[:queue]
options = { :max_number_of_messages => 10 }.merge(options)
- options.merge!(:action => "ReceiveMessage")
call_amazon(options){ |req| SQSMessage.parse(req.response) }
end
def delete_message(options={})
raise "no Message specified" unless options[:message]
- options.merge!(:action => "DeleteMessage", :receipt_handle => options.delete(:message).receipt_handle)
+ options.merge!(:receipt_handle => options.delete(:message).receipt_handle)
call_amazon(options)
end
def get_queue_attributes(options={})
raise "no target queue specified" unless options[:queue]
options = {:attribute_name => "All" }.merge(options)
- options.merge!(:action => "GetQueueAttributes")
call_amazon(options){ |req| SQSAttributes.parse(req.response) }
end
def delete_queue(options={})
raise "no target queue specified" unless options[:queue]
- options.merge!( :action => "DeleteQueue")
call_amazon(options)
end
def create_queue(options={})
raise "no queue name specified" unless options[:queue_name]
options[:default_visibility_timeout] = 30 unless options[:default_visibility_timeout]
- options.merge!( :action => "CreateQueue" )
call_amazon(options){ |req| SQSQueue.parse(req.response) }
end
@@ -125,21 +124,24 @@ def call_amazon(options)
endpoint = (options[:queue] != nil) ? options.delete(:queue).queue_url : "http://" << ( options.delete(:host) || region_host(:us_east) )
callbacks = options.delete(:callbacks) || {:success=>nil, :failure =>nil }
+ if( who_called_us = caller(0)[1] )
+ options = {:action => action_from_caller(who_called_us)}.merge(options)
+ end
+
options.amazonize_keys!
+
params = sign_params( endpoint, options )
req = EM::HttpRequest.new("#{endpoint}?#{params}").get
- req.callback do |req|
- if(req.response.to_s.match(/<ErrorResponse>/i))
- on_failure(req, callbacks)
+ req.callback do |req_ref|
+ if(req_ref.response.to_s.match(/<ErrorResponse>/i))
+ on_failure(req_ref, callbacks)
else
- result = req
- result = yield req if block_given?
+ result = req_ref
+ result = yield req_ref if block_given?
callbacks[:success].call(result) if callbacks[:success]
end
end
- req.errback do |req|
- on_failure(req, callbacks)
- end
+ req.errback { |req_ref| on_failure(req_ref, callbacks) }
end
def on_failure(req, callbacks)
@@ -169,7 +171,7 @@ def generate_signature(request_description)
end
def encoding_exclusions
- /[^\w\d\-\_\.\~]/
+ /[^\w\d\-_\.~]/
end
def encode(val)
@@ -181,17 +183,17 @@ def region_host(key)
end
def regions
- @regions ||= Regions
+ @regions ||= REGIONS
@regions
end
def default_paramters
- @default_paramters ||= Parameters.merge("AWSAccessKeyId" => aws_key)
+ @default_paramters ||= PARAMETERS.merge("AWSAccessKeyId" => aws_key)
@default_paramters.merge("Expires" => (Time.now+(60*30)).utc.iso8601)
end
def post_options
- @post_options ||= PostOptions
+ @post_options ||= POSTOPTIONS
@post_options
end
@@ -212,7 +214,7 @@ def log(msg)
logger.error(log_msg.join("\n"))
end
- Regions = {
+ REGIONS = {
:us_east => { :name => "US-East (Northern Virginia) Region", :uri => "sqs.us-east-1.amazonaws.com"},
:us_west => { :name => "US-West (Northern California) Region", :uri => "sqs.us-west-1.amazonaws.com"},
:eu => { :name => "EU (Ireland) Region", :uri => "sqs.eu-west-1.amazonaws.com"},
@@ -221,13 +223,13 @@ def log(msg)
}
- Parameters = {
+ PARAMETERS = {
"Version" => "2009-02-01",
"SignatureVersion"=>"2",
"SignatureMethod"=>"HmacSHA256",
}
- PostOptions = {
+ POSTOPTIONS = {
"Content-Type" => "application/x-www-form-urlencoded"
}
end
View
31 lib/sqs_permission.rb
@@ -1,30 +1,27 @@
module SQS
module Permissions
- All = "*"
- SendMessage = "SendMessage"
- ReceiveMessage = "ReceiveMessage"
- DeleteMessage = "DeleteMessage"
- ChangeMessageVisibility = "ChangeMessageVisibility"
- GetQueueAttributes = "GetQueueAttributes"
-
- def send_message
- SendMessage
+ def self.all
+ "*"
end
- def receive_message
- ReceiveMessage
+ def self.send_message
+ "SendMessage"
end
- def delete_message
- DeleteMessage
+ def self.receive_message
+ "ReceiveMessage"
end
- def change_message_visibility
- ChangeMessageVisibility
+ def self.delete_message
+ "DeleteMessage"
end
- def get_queue_attributes
- GetQueueAttributes
+ def self.change_message_visibility
+ "ChangeMessageVisibility"
+ end
+
+ def self.get_queue_attributes
+ "GetQueueAttributes"
end
end
end
View
6 lib/sqs_utilities.rb
@@ -4,7 +4,11 @@
module SQS
module Utilities
- def camelize(str, first_letter_in_uppercase = true)
+ def action_from_caller(first_element_in_caller)
+ camelize(first_element_in_caller.scan(/\`(\w+)\'/).flatten.first)
+ end
+
+ def camelize(str)
str.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
end
View
2  spec/fixtures/set_queue_attributes.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<SetQueueAttributesResponse><ResponseMetadata><RequestId>e5cca473-4fc0-4198-a451-8abb94d02c75</RequestId></ResponseMetadata></SetQueueAttributesResponse>
View
4 spec/spec_helper.rb
@@ -28,11 +28,11 @@ def initialize *args
end
def get *args
- return self
+ self
end
def post *args
- return self
+ self
end
def callback &block
View
2  spec/sqs_attributes_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe "SQSAttributes" do
- describe ".parse" do
+ context ".parse" do
let(:attributes_obj) { SQSAttributes.parse(xml_fixture(:queue_attributes)) }
it "returns SQSAttributes objects" do
View
2  spec/sqs_message_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe "SQSMessage" do
- describe ".parse" do
+ context ".parse" do
let(:messages) { SQSMessage.parse(xml_fixture(:receive_message)) }
it "returns SQSMessage objects" do
View
2  spec/sqs_queue_spec.rb
@@ -2,7 +2,7 @@
require 'sqs_message'
describe "SQSQueue" do
- describe ".parse" do
+ context ".parse" do
let(:queues) { SQSQueue.parse(xml_fixture(:list_queues)) }
it "returns SQSQueue objects" do
View
21 spec/sqs_spec.rb
@@ -48,7 +48,7 @@ def initialize
context "calls Amazon Endpoints asynchronously to" do
it "change_message_visibility" do
- mock_obj = mock();
+ mock_obj = mock()
mock_obj.expects(:call).once
client.change_message_visibility(
:queue => queue,
@@ -59,7 +59,17 @@ def initialize
EM::HttpRequest.succeed(EM::MockResponse.new(xml_fixture(:change_message_visibility)))
end
- it "set_queue_attributes"
+ it "set_queue_attributes" do
+ mock_obj = mock()
+ mock_obj.expects(:call).once
+ client.set_queue_attributes(
+ :queue => queue,
+ :visibility_timeout => Time.now.to_i + (30*60),
+ :callbacks => { :success => mock_obj }
+ )
+ EM::HttpRequest.succeed(EM::MockResponse.new(xml_fixture(:set_queue_attributes)))
+ end
+
context "putting a message on the queue" do
it "send_message with SQSMessage object" do
msg = SQSMessage.new
@@ -76,6 +86,7 @@ def initialize
)
EM::HttpRequest.succeed(EM::MockResponse.new(xml_fixture(:send_message)))
end
+
it "send_message with message body" do
client.send_message(
:queue => queue,
@@ -120,11 +131,11 @@ def initialize
let(:permissions) do
leon = SQSPermission.new
leon.aws_account_id = "a12digitcode"
- leon.permission = SQS::Permissions::All
+ leon.permission = SQS::Permissions.all
john = SQSPermission.new
john.aws_account_id = "b12digitcode"
- john.permission = SQS::Permissions::SendMessage
+ john.permission = SQS::Permissions.send_message
[leon, john]
end
@@ -171,7 +182,7 @@ def initialize
end
it "delete a message from the queue" do
- mock_obj = mock();
+ mock_obj = mock()
mock_obj.expects(:call).once
client.delete_message(
:queue => queue,
View
12 spec/sqs_utilities_spec.rb
@@ -8,4 +8,16 @@
hash.amazonize_keys!
hash["QueueName"].should == "foo"
end
+
+ it "infers an amazonized action from the calling context" do
+ def this_would_be_the_same_as_an_action_name
+ sample_target
+ end
+
+ def sample_target
+ action_from_caller(caller(0)[1]).should == "ThisWouldBeTheSameAsAnActionName"
+ end
+
+ this_would_be_the_same_as_an_action_name
+ end
end
View
2  sqs_async.gemspec
@@ -1,7 +1,7 @@
require 'rake'
Gem::Specification.new do |s|
s.name = 'sqs_async'
- s.version = '0.0.1'
+ s.version = '0.0.2'
s.summary = 'Non-Blocking SQS library.'
s.description = 'A simple library that leverages Event Machine to issue requests to the Amazon SQS service while blocking as little as possible'
s.authors = "EdgeCase <contact@edgecase.com>", "John Andrews <john@edgecase.com>", "Leon Gersing <leon@edgecase.com>"
Please sign in to comment.
Something went wrong with that request. Please try again.