warren 0.8.9
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +14 -0
- data/LICENSE +11 -0
- data/Manifest +32 -0
- data/Rakefile +23 -0
- data/examples/authed/receiver.rb +25 -0
- data/examples/authed/secret.rb +1 -0
- data/examples/authed/sender.rb +40 -0
- data/examples/simple/amqp_mass_sender.rb +21 -0
- data/examples/simple/amqp_receiver.rb +18 -0
- data/examples/simple/amqp_sender.rb +36 -0
- data/examples/simple/bunny_receiver.rb +18 -0
- data/examples/simple/bunny_sender.rb +36 -0
- data/lib/warren/adapters/amqp_adapter.rb +87 -0
- data/lib/warren/adapters/bunny_adapter.rb +93 -0
- data/lib/warren/adapters/dummy_adapter.rb +12 -0
- data/lib/warren/adapters/test_adapter.rb +27 -0
- data/lib/warren/connection.rb +140 -0
- data/lib/warren/filters/shared_secret.rb +70 -0
- data/lib/warren/filters/yaml.rb +20 -0
- data/lib/warren/message_filter.rb +76 -0
- data/lib/warren/queue.rb +89 -0
- data/lib/warren.rb +23 -0
- data/readme.rdoc +46 -0
- data/spec/spec.opts +3 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/warren/adapters/test_adapter_spec.rb +29 -0
- data/spec/warren/connection_spec.rb +122 -0
- data/spec/warren/queue_spec.rb +91 -0
- data/spec/warren/warren_spec.rb +9 -0
- data/tasks/rdoc.rake +7 -0
- data/tasks/rspec.rake +24 -0
- data/warren.gemspec +33 -0
- metadata +113 -0
@@ -0,0 +1,70 @@
|
|
1
|
+
begin
|
2
|
+
require "hmac-sha2"
|
3
|
+
rescue LoadError => e
|
4
|
+
puts "Error loading the `ruby-hmac` gem."
|
5
|
+
exit!
|
6
|
+
end
|
7
|
+
|
8
|
+
module Warren
|
9
|
+
class MessageFilter
|
10
|
+
# Hashes the message using a secret salt, stores the hash
|
11
|
+
# in the message and then checks its the same when pulled
|
12
|
+
# off the other end.
|
13
|
+
#
|
14
|
+
# Basic trust implementation to make sure the message
|
15
|
+
# hasn't been tampered with in transit and came from
|
16
|
+
# an "authorised" app.
|
17
|
+
#
|
18
|
+
# Make sure both the publisher and subscriber use the same
|
19
|
+
# key else you'll get KeyValidationError error raised.
|
20
|
+
#
|
21
|
+
class SharedSecret
|
22
|
+
# Raised when no key (salt) is provided
|
23
|
+
class NoKeyError < Exception; end
|
24
|
+
# Raised when there is a key mismatch error
|
25
|
+
class KeyValidationError < Exception; end
|
26
|
+
|
27
|
+
# Sets the key to use
|
28
|
+
def self.key= key
|
29
|
+
@@key = key
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns the current key
|
33
|
+
# Raises NoKeyError if no key has been assigned yet
|
34
|
+
def self.key
|
35
|
+
raise NoKeyError if @@key.nil?
|
36
|
+
@@key
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns the hashed message
|
40
|
+
#
|
41
|
+
# Expects that msg#to_s returns a string
|
42
|
+
# to hash against.
|
43
|
+
#
|
44
|
+
def self.secret msg
|
45
|
+
HMAC::SHA256.hexdigest(self.key, msg.to_s)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Called when the message is being packed for
|
49
|
+
# transit. Returns a hash.
|
50
|
+
def self.pack msg
|
51
|
+
# Make sure its a hash
|
52
|
+
msg = {:secret_msg => msg} unless msg.is_a? Hash
|
53
|
+
# And add our secret into the hash
|
54
|
+
msg[:secret] = self.secret(msg.to_s)
|
55
|
+
msg
|
56
|
+
end
|
57
|
+
|
58
|
+
# Called when unpacking the message from transit.
|
59
|
+
# Returns the original object.
|
60
|
+
def self.unpack msg
|
61
|
+
# Check the secret exists in the msg and matches the secret_string
|
62
|
+
raise KeyValidationError unless msg.delete(:secret) == self.secret(msg)
|
63
|
+
# see if its a hash we created, it'll only contain the key "secret_msg" if it is
|
64
|
+
msg = msg[:secret_msg] if msg.keys == [:secret_msg]
|
65
|
+
msg
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "yaml"
|
2
|
+
|
3
|
+
module Warren
|
4
|
+
class MessageFilter
|
5
|
+
# Packs the message into a YAML string
|
6
|
+
# for transferring safely across the wire
|
7
|
+
class Yaml < MessageFilter
|
8
|
+
|
9
|
+
# Returns a YAML string
|
10
|
+
def self.pack msg
|
11
|
+
YAML.dump(msg)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Returns original message
|
15
|
+
def self.unpack msg
|
16
|
+
YAML.load(msg)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Warren
|
2
|
+
# Handles filtering messages going onto/coming off the queue
|
3
|
+
class MessageFilter
|
4
|
+
# Array of filters to be run on the message before its
|
5
|
+
# pushed to rabbit.
|
6
|
+
#
|
7
|
+
# NB: These get called in reverse order from the array -
|
8
|
+
# the last filter to be added gets called first.
|
9
|
+
@@filters = []
|
10
|
+
|
11
|
+
class << self
|
12
|
+
# Adds a filter to the list
|
13
|
+
#
|
14
|
+
# A valid filter is just a class that defines
|
15
|
+
# <tt>self.pack</tt> and <tt>self.unpack</tt>
|
16
|
+
# methods, which both accept a single argument,
|
17
|
+
# act upon it, and return the output.
|
18
|
+
#
|
19
|
+
# Example filter class (See also message_filters/*.rb)
|
20
|
+
#
|
21
|
+
# class Foo
|
22
|
+
# def self.pack msg
|
23
|
+
# msg.reverse # Assumes msg responds to reverse
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# def self.unpack msg
|
27
|
+
# msg.reverse # Does the opposite of Foo#pack
|
28
|
+
# end
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
def << filter
|
32
|
+
@@filters << filter
|
33
|
+
end
|
34
|
+
alias :add_filter :<<
|
35
|
+
end
|
36
|
+
|
37
|
+
# Called when a subclass is created, adds the subclass to the queue
|
38
|
+
def self.inherited klass
|
39
|
+
add_filter klass
|
40
|
+
end
|
41
|
+
|
42
|
+
# Returns current array of filters
|
43
|
+
def self.filters
|
44
|
+
@@filters
|
45
|
+
end
|
46
|
+
|
47
|
+
# Resets the filters to default
|
48
|
+
def self.reset_filters
|
49
|
+
@@filters = [Warren::MessageFilter::Yaml]
|
50
|
+
end
|
51
|
+
|
52
|
+
# Runs the raw message through all the filters
|
53
|
+
# and returns the filtered version
|
54
|
+
def self.pack msg
|
55
|
+
@@filters.reverse.each do |f|
|
56
|
+
# puts "Packing with #{f}"
|
57
|
+
msg = f.send(:pack, msg)
|
58
|
+
end
|
59
|
+
msg
|
60
|
+
end
|
61
|
+
|
62
|
+
# Runs the filtered message through all the
|
63
|
+
# filters and returns the raw version
|
64
|
+
def self.unpack msg
|
65
|
+
@@filters.each do |f|
|
66
|
+
# puts "Unpacking with #{f}"
|
67
|
+
msg = f.unpack(msg)
|
68
|
+
end
|
69
|
+
msg
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Make sure the YAML filter is added first
|
76
|
+
require File.expand_path(File.dirname(__FILE__) + "/filters/yaml")
|
data/lib/warren/queue.rb
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
module Warren
|
2
|
+
class Queue
|
3
|
+
@@connection = nil
|
4
|
+
@@adapter = nil
|
5
|
+
|
6
|
+
#
|
7
|
+
# Raised if no connection has been defined yet.
|
8
|
+
#
|
9
|
+
NoConnectionDetails = Class.new(Exception)
|
10
|
+
|
11
|
+
#
|
12
|
+
# Raised if a block is expected by the method but none is given.
|
13
|
+
#
|
14
|
+
NoBlockGiven = Class.new(Exception)
|
15
|
+
|
16
|
+
#
|
17
|
+
# Raised if an adapter isn't set
|
18
|
+
#
|
19
|
+
NoAdapterSet = Class.new(Exception)
|
20
|
+
|
21
|
+
#
|
22
|
+
# Raised if the adapter is missing a method
|
23
|
+
# Check the message for details of the missing method.
|
24
|
+
#
|
25
|
+
InvalidAdapter = Class.new(Exception)
|
26
|
+
|
27
|
+
#
|
28
|
+
# Sets the current connection
|
29
|
+
#
|
30
|
+
def self.connection= conn
|
31
|
+
@@connection = (conn.is_a?(Warren::Connection) ? conn : Warren::Connection.new(conn) )
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# Returns the current connection details
|
36
|
+
#
|
37
|
+
def self.connection
|
38
|
+
@@connection ||= Warren::Connection.new
|
39
|
+
end
|
40
|
+
|
41
|
+
#
|
42
|
+
# Sets the adapter when this class is subclassed.
|
43
|
+
#
|
44
|
+
def self.inherited klass
|
45
|
+
@@adapter = klass
|
46
|
+
end
|
47
|
+
|
48
|
+
#
|
49
|
+
# Sets the adapter manually
|
50
|
+
#
|
51
|
+
def self.adapter= klass
|
52
|
+
@@adapter = klass
|
53
|
+
end
|
54
|
+
|
55
|
+
#
|
56
|
+
# Returns the current adapter or raises NoAdapterSet exception
|
57
|
+
#
|
58
|
+
def self.adapter
|
59
|
+
@@adapter || raise(NoAdapterSet)
|
60
|
+
end
|
61
|
+
|
62
|
+
#
|
63
|
+
# Publishes the message to the queue
|
64
|
+
#
|
65
|
+
def self.publish *args, &blk
|
66
|
+
raise(InvalidAdapter, "publish method missing") unless @@adapter.respond_to?(:publish)
|
67
|
+
self.adapter.publish(*args, &blk)
|
68
|
+
end
|
69
|
+
|
70
|
+
#
|
71
|
+
# Sends the subscribe message to the adapter class
|
72
|
+
#
|
73
|
+
def self.subscribe *args, &blk
|
74
|
+
raise(InvalidAdapter.new("subscribe method missing")) unless @@adapter.respond_to?(:subscribe)
|
75
|
+
self.adapter.subscribe(*args, &blk)
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.logger
|
79
|
+
unless @@logger
|
80
|
+
@@logger = Logger.new(nil)
|
81
|
+
end
|
82
|
+
@@logger
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.logger=(l)
|
86
|
+
@@logger = l
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
data/lib/warren.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require "yaml"
|
2
|
+
require "logger"
|
3
|
+
#
|
4
|
+
# Library for pushing messages onto RabbitMQ queues,
|
5
|
+
# and receiving them at the other end.
|
6
|
+
#
|
7
|
+
# It handles authentication + filtering messages with custom
|
8
|
+
# classes if needed.
|
9
|
+
#
|
10
|
+
# Start with Warren::Queue for details and see also
|
11
|
+
# examples/
|
12
|
+
#
|
13
|
+
module Warren
|
14
|
+
end
|
15
|
+
|
16
|
+
WARREN_ENV = ENV['WARREN_ENV'] || ((defined?(RAILS_ENV) ? RAILS_ENV : "development")) unless defined?(WARREN_ENV)
|
17
|
+
WARREN_ROOT = (defined?(RAILS_ROOT) ? RAILS_ROOT : File.dirname($0)) unless defined?(WARREN_ROOT)
|
18
|
+
WARREN_LIB_ROOT = File.expand_path(File.dirname(__FILE__)) unless defined? WARREN_LIB_ROOT
|
19
|
+
|
20
|
+
# Require everything in the lib folder
|
21
|
+
Dir["#{WARREN_LIB_ROOT}/warren/*.rb"].each do |file|
|
22
|
+
require file
|
23
|
+
end
|
data/readme.rdoc
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
= Warren
|
2
|
+
|
3
|
+
Library for sending and receiving messages, complete with en/decrypting messages on either side of the transport.
|
4
|
+
|
5
|
+
It was written to handle sending messages between two nodes using RabbitMQ, which is why the two default adapters are for synchronous and asynchronous rabbitmq client libraries. You can delegate the sending & receiving to any custom class you want, simply by subclassing Warren::Queue. (Isn't ruby magic marvelous!)
|
6
|
+
|
7
|
+
The filtering works in much the same way as the adapter class. There is a default YAML filter that is always called last before sending the message and first when receiving the message, simply to make sure the message is a string when sent + received. You can then add custom classes onto the stack in any order you want, simply by subclassing Warren::MessageFilter. Add them in the same order on the receiving side and warren takes care of calling them in reverse order.
|
8
|
+
|
9
|
+
Start by looking at examples/ to see how to use it, and then lib/warren/adapters/ to see how to implement your own adapter class and lib/warren/filters to see how to implement your own filters.
|
10
|
+
|
11
|
+
== Installation
|
12
|
+
|
13
|
+
gem install brightbox-warren
|
14
|
+
|
15
|
+
== Usage
|
16
|
+
|
17
|
+
require "rubygems"
|
18
|
+
require "warren"
|
19
|
+
# Use the bunny adapter to connect to RabbitMQ (Bunny is an AMQP client that works with Rails/Passenger apps)
|
20
|
+
require "warren/adapters/bunny_adapter"
|
21
|
+
# If you're running in development and don't want to actually push messages onto the queue then instead of loading the bunny adapter use the dummy adapter
|
22
|
+
require "warren/adapters/dummy_adapter"
|
23
|
+
|
24
|
+
# See examples/ for more
|
25
|
+
|
26
|
+
== Rails
|
27
|
+
|
28
|
+
Add this to your environment.rb
|
29
|
+
|
30
|
+
config.gem "brightbox-warren", :lib => "warren", :version => ">= 0.8"
|
31
|
+
|
32
|
+
Add the config into config/warren.yml with the details for each environment. Works just the same as database.yml:
|
33
|
+
|
34
|
+
development:
|
35
|
+
user: rabbit
|
36
|
+
pass: carrots53
|
37
|
+
host: rabbit.warren
|
38
|
+
logging: false
|
39
|
+
|
40
|
+
And then in an initializer file (or bottom of environment.rb) require the adapter you want to use (for rabbitmq I suggest bunny - amqp uses eventmachine and was giving me issues under passenger.) And then any filters you want to use.
|
41
|
+
|
42
|
+
require "warren/adapters/bunny_adapter"
|
43
|
+
|
44
|
+
== License
|
45
|
+
|
46
|
+
Licensed under the MIT license. See LICENSE for more details.
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__) + "/../lib/warren")
|
2
|
+
|
3
|
+
# Hacky and I hate it, but needed to
|
4
|
+
# change constants in tests
|
5
|
+
# from http://is.gd/12JVp
|
6
|
+
def silently(&block)
|
7
|
+
warn_level = $VERBOSE
|
8
|
+
$VERBOSE = nil
|
9
|
+
result = block.call
|
10
|
+
$VERBOSE = warn_level
|
11
|
+
result
|
12
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
require "#{File.dirname(__FILE__)}/../../../lib/warren/adapters/test_adapter.rb"
|
3
|
+
|
4
|
+
describe TestAdapter do
|
5
|
+
|
6
|
+
before(:all) do
|
7
|
+
@file_name = "#{WARREN_ROOT}/tmp/warren.txt"
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should return true from publish without a tmp file" do
|
11
|
+
TestAdapter.publish(:queue_name, :payload).should == true
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should return true from publish with a tmp file which doesn't say \"FAIL\"" do
|
15
|
+
File.should_receive(:exists?).with(@file_name).and_return(true)
|
16
|
+
File.should_receive(:read).with(@file_name, 4).and_return("blah")
|
17
|
+
|
18
|
+
TestAdapter.publish(:queue_name, :payload).should == true
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should raise an error when tmp file exists and says \"FAIL\"" do
|
22
|
+
File.should_receive(:exists?).with(@file_name).and_return(true)
|
23
|
+
File.should_receive(:read).with(@file_name, 4).and_return("FAIL")
|
24
|
+
|
25
|
+
lambda { TestAdapter.publish(:queue_name, :payload) }.
|
26
|
+
should raise_error(TestAdapter::ConnectionFailed)
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Warren::Connection do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
setup_adapter
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should read from warren.yml" do
|
10
|
+
setup_config_file
|
11
|
+
|
12
|
+
Warren::Connection.new
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should read from an arbitrary file" do
|
16
|
+
File.should_receive(:exists?).with("my_awesome_config.yml").and_return(true)
|
17
|
+
YAML.should_receive(:load_file).with("my_awesome_config.yml").and_return({"development" => {}})
|
18
|
+
|
19
|
+
Warren::Connection.new("my_awesome_config.yml")
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "parsing config with file" do
|
23
|
+
|
24
|
+
before do
|
25
|
+
setup_config_file
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should parse the right config out" do
|
29
|
+
conn = Warren::Connection.new
|
30
|
+
WARREN_ENV.should == "development"
|
31
|
+
conn.instance_variable_get("@options").should == {
|
32
|
+
:user => "rspec",
|
33
|
+
:pass => "password",
|
34
|
+
:host => "localhost",
|
35
|
+
:logging => false,
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should raise if no details for current environment" do
|
40
|
+
silently { WARREN_ENV = "rspec" }
|
41
|
+
|
42
|
+
lambda { Warren::Connection.new }.
|
43
|
+
should raise_error(
|
44
|
+
Warren::Connection::InvalidConnectionDetails,
|
45
|
+
"No details for current environment 'rspec'"
|
46
|
+
)
|
47
|
+
|
48
|
+
silently { WARREN_ENV = "development" }
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should symbolize keys in a hash" do
|
52
|
+
conn = Warren::Connection.new
|
53
|
+
hash = {"one" => "two", "three" => {"four" => 7}, :five => "six"}
|
54
|
+
conn.send(:symbolize_keys, hash).should == {
|
55
|
+
:one => "two",
|
56
|
+
:three => {:four => 7},
|
57
|
+
:five => "six"
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should raise if no adapter set to check against" do
|
62
|
+
Warren::Queue.adapter = nil
|
63
|
+
lambda { Warren::Connection.new }.
|
64
|
+
should raise_error(Warren::Queue::NoAdapterSet)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should successfully check against adapter" do
|
68
|
+
_adapter = mock 'queue', :check_connection_details => true
|
69
|
+
_adapter.should_receive(:check_connection_details)
|
70
|
+
Warren::Queue.adapter = _adapter
|
71
|
+
|
72
|
+
Warren::Connection.new
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should raise errors for missing connection details" do
|
76
|
+
_adapter = stub 'queue', :check_connection_details => ["one", "two"]
|
77
|
+
|
78
|
+
Warren::Connection.new
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should raise errors for other prerequisits in the adapter" do
|
82
|
+
Adapter = Class.new(Warren::Queue) do
|
83
|
+
def self.check_connection_details params
|
84
|
+
raise Warren::Connection::InvalidConnectionDetails, "Missing prerequisites"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
lambda { Warren::Connection.new }.
|
89
|
+
should raise_error(Warren::Connection::InvalidConnectionDetails, "Missing prerequisites")
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
def setup_config_file
|
95
|
+
config_file = "#{File.dirname($0)}/config/warren.yml"
|
96
|
+
File.should_receive(:exists?).with(config_file).and_return(true)
|
97
|
+
YAML.should_receive(:load_file).with(config_file).and_return(yaml_data)
|
98
|
+
end
|
99
|
+
|
100
|
+
def setup_adapter
|
101
|
+
_adapter = stub 'queue'
|
102
|
+
Warren::Queue.adapter = _adapter
|
103
|
+
end
|
104
|
+
|
105
|
+
def yaml_data
|
106
|
+
{
|
107
|
+
"development" => {
|
108
|
+
"host" => "localhost",
|
109
|
+
"user" => "rspec",
|
110
|
+
"pass" => "password",
|
111
|
+
"logging" => false
|
112
|
+
},
|
113
|
+
"test" => {
|
114
|
+
"host" => "localhost-test",
|
115
|
+
"user" => "rspec-test",
|
116
|
+
"pass" => "password-test",
|
117
|
+
"logging" => true
|
118
|
+
}
|
119
|
+
}
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Warren::Queue do
|
4
|
+
|
5
|
+
describe "connection" do
|
6
|
+
|
7
|
+
before(:all) do
|
8
|
+
@conn = stub 'connection'
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should create a new Warren::Connection if one doesn't exist" do
|
12
|
+
Warren::Connection.should_receive(:new).and_return(@conn)
|
13
|
+
|
14
|
+
Warren::Queue.connection.should == @conn
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should only create a connection once" do
|
18
|
+
# Already created the connection object in the first it
|
19
|
+
Warren::Connection.should_not_receive(:new)
|
20
|
+
|
21
|
+
Warren::Queue.connection.should == @conn
|
22
|
+
Warren::Queue.connection.should == @conn
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "adapter" do
|
27
|
+
|
28
|
+
before(:each) do
|
29
|
+
@adapter = mock 'adapter', :publish => "publish", :subscribe => "subscribe"
|
30
|
+
Warren::Queue.adapter = @adapter
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should have an adapter set" do
|
34
|
+
Warren::Queue.adapter.should == @adapter
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should have a publish method" do
|
38
|
+
my_adapter = mock 'adapter'
|
39
|
+
Warren::Queue.adapter = my_adapter
|
40
|
+
|
41
|
+
lambda { Warren::Queue.publish }.should \
|
42
|
+
raise_error(Warren::Queue::InvalidAdapter, "publish method missing")
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should have a subscribe method" do
|
46
|
+
my_adapter = mock 'adapter'
|
47
|
+
Warren::Queue.adapter = my_adapter
|
48
|
+
|
49
|
+
Warren::Queue.adapter.should == my_adapter
|
50
|
+
|
51
|
+
lambda { Warren::Queue.subscribe}.should \
|
52
|
+
raise_error(Warren::Queue::InvalidAdapter, "subscribe method missing")
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should pass publish through to the adapter" do
|
56
|
+
@adapter.should_receive(:publish)
|
57
|
+
Warren::Queue.publish.should == "publish"
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should pass arguments through to adapter#publish" do
|
61
|
+
@adapter.should_receive(:publish).with("foo", "bar")
|
62
|
+
|
63
|
+
Warren::Queue.publish("foo", "bar").should == "publish"
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should pass a block through to adapter#publish" do
|
67
|
+
block = lambda { true }
|
68
|
+
@adapter.should_receive(:publish).with("foo", "bar", block)
|
69
|
+
|
70
|
+
Warren::Queue.publish("foo", "bar", block).should == "publish"
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should pass subscribe through to the adapter" do
|
74
|
+
@adapter.should_receive(:subscribe)
|
75
|
+
Warren::Queue.subscribe.should == "subscribe"
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should pass arguments through to adapter#subscribe" do
|
79
|
+
@adapter.should_receive(:subscribe).with("foo", "bar")
|
80
|
+
|
81
|
+
Warren::Queue.subscribe("foo", "bar").should == "subscribe"
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should pass a block through to adapter#subscribe" do
|
85
|
+
block = lambda { true }
|
86
|
+
@adapter.should_receive(:subscribe).with("foo", "bar", block)
|
87
|
+
|
88
|
+
Warren::Queue.subscribe("foo", "bar", block).should == "subscribe"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
data/tasks/rdoc.rake
ADDED
data/tasks/rspec.rake
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# Borrowed from http://github.com/rsim/ruby-plsql/tree/master/tasks/rspec.rake
|
2
|
+
# Github++
|
3
|
+
begin
|
4
|
+
require "spec"
|
5
|
+
rescue LoadError
|
6
|
+
require "rubygems"
|
7
|
+
require "spec"
|
8
|
+
end
|
9
|
+
|
10
|
+
begin
|
11
|
+
require "spec/rake/spectask"
|
12
|
+
rescue LoadError
|
13
|
+
puts <<-EOS
|
14
|
+
To use rspec for testing you must install rspec gem:
|
15
|
+
[sudo] gem install rspec
|
16
|
+
EOS
|
17
|
+
exit(0)
|
18
|
+
end
|
19
|
+
|
20
|
+
desc "Run the specs under spec/*"
|
21
|
+
Spec::Rake::SpecTask.new do |t|
|
22
|
+
t.spec_opts = ["--options", "spec/spec.opts"]
|
23
|
+
t.spec_files = FileList["spec/**/*_spec.rb"]
|
24
|
+
end
|
data/warren.gemspec
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{warren}
|
5
|
+
s.version = "0.8.9"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Caius Durling, David Smalley"]
|
9
|
+
s.date = %q{2009-10-15}
|
10
|
+
s.description = %q{Library for pushing messages onto and off RabbitMQ queues}
|
11
|
+
s.email = %q{support@brightbox.co.uk}
|
12
|
+
s.extra_rdoc_files = ["CHANGELOG", "lib/warren/adapters/amqp_adapter.rb", "lib/warren/adapters/bunny_adapter.rb", "lib/warren/adapters/dummy_adapter.rb", "lib/warren/adapters/test_adapter.rb", "lib/warren/connection.rb", "lib/warren/filters/shared_secret.rb", "lib/warren/filters/yaml.rb", "lib/warren/message_filter.rb", "lib/warren/queue.rb", "lib/warren.rb", "LICENSE", "tasks/rdoc.rake", "tasks/rspec.rake"]
|
13
|
+
s.files = ["CHANGELOG", "examples/authed/receiver.rb", "examples/authed/secret.rb", "examples/authed/sender.rb", "examples/simple/amqp_mass_sender.rb", "examples/simple/amqp_receiver.rb", "examples/simple/amqp_sender.rb", "examples/simple/bunny_receiver.rb", "examples/simple/bunny_sender.rb", "lib/warren/adapters/amqp_adapter.rb", "lib/warren/adapters/bunny_adapter.rb", "lib/warren/adapters/dummy_adapter.rb", "lib/warren/adapters/test_adapter.rb", "lib/warren/connection.rb", "lib/warren/filters/shared_secret.rb", "lib/warren/filters/yaml.rb", "lib/warren/message_filter.rb", "lib/warren/queue.rb", "lib/warren.rb", "LICENSE", "Manifest", "Rakefile", "readme.rdoc", "spec/spec.opts", "spec/spec_helper.rb", "spec/warren/adapters/test_adapter_spec.rb", "spec/warren/connection_spec.rb", "spec/warren/queue_spec.rb", "spec/warren/warren_spec.rb", "tasks/rdoc.rake", "tasks/rspec.rake", "warren.gemspec"]
|
14
|
+
s.homepage = %q{http://github.com/brightbox/warren}
|
15
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Warren", "--main", "readme.rdoc"]
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
s.rubyforge_project = %q{warren}
|
18
|
+
s.rubygems_version = %q{1.3.5}
|
19
|
+
s.summary = %q{Library for pushing messages onto and off RabbitMQ queues}
|
20
|
+
|
21
|
+
if s.respond_to? :specification_version then
|
22
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
23
|
+
s.specification_version = 3
|
24
|
+
|
25
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
26
|
+
s.add_runtime_dependency(%q<amqp>, [">= 0.6.0"])
|
27
|
+
else
|
28
|
+
s.add_dependency(%q<amqp>, [">= 0.6.0"])
|
29
|
+
end
|
30
|
+
else
|
31
|
+
s.add_dependency(%q<amqp>, [">= 0.6.0"])
|
32
|
+
end
|
33
|
+
end
|