cwyckoff-rosetta_queue 0.2.2 → 0.3.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/README.rdoc +27 -2
- data/Rakefile +2 -2
- data/lib/rosetta_queue.rb +2 -0
- data/lib/rosetta_queue/adapters/{amqp.rb → amqp_synch.rb} +19 -10
- metadata +2 -2
data/README.rdoc
CHANGED
|
@@ -4,17 +4,21 @@ Rosetta Queue is a messaging gateway API with adapters for many messaging system
|
|
|
4
4
|
|
|
5
5
|
The adapters provided currently are for stomp, amqp, and beanstalk. We would like to add adapters for other messaging gateways. The stomp adapter has been used in production along side with Apache's ActiveMQ. The amqp adapter currently works along side RabbitMQ and passes the acceptance tests but as of yet has not been used in production.
|
|
6
6
|
|
|
7
|
+
|
|
7
8
|
== Quick Tutorial
|
|
9
|
+
|
|
8
10
|
Note: The API will most likely change until we reach 1.0. We will be moving to a more concise API (i.e. queue(:test_queue) << message, etc...) We will also be changing how exceptions are handled.
|
|
9
11
|
|
|
10
12
|
When using Rosetta Queue in an application you will need to configure the queues, adapters, and filters (optional). These configurations should be placed in a file that gets loaded once when your program starts. If you are using Rails then a good place for this is config/initializers/rosetta_queue.rb.
|
|
11
13
|
|
|
12
|
-
|
|
14
|
+
|
|
15
|
+
To set up destinations for producing and consuming messages:
|
|
13
16
|
|
|
14
17
|
RosettaQueue::Destinations.define do |queue|
|
|
15
18
|
queue.map :test_queue, '/queue/my_test_queue'
|
|
16
19
|
end
|
|
17
20
|
|
|
21
|
+
|
|
18
22
|
Defining your adapter:
|
|
19
23
|
|
|
20
24
|
RosettaQueue::Adapter.define do |a|
|
|
@@ -25,6 +29,7 @@ Defining your adapter:
|
|
|
25
29
|
a.type = "stomp"
|
|
26
30
|
end
|
|
27
31
|
|
|
32
|
+
|
|
28
33
|
Define a logger for Rosetta Queue to use. The logger should be a standard ruby logger:
|
|
29
34
|
|
|
30
35
|
RosettaQueue.logger = Logger.new('/my_project/rosetta_queue.log')
|
|
@@ -76,11 +81,31 @@ It is recommended that you set your adapter to the 'null' adapter for your specs
|
|
|
76
81
|
Please look at the publishing matchers for more information. For examples on how to write acceptance tests for your Rosetta Queue's code please see RosettaQueue's own Cucumber features and read this {blog post}[http://www.benmabey.com/2009/02/17/using-cucumber-to-integrate-distributed-systems-and-test-messaging/].
|
|
77
82
|
|
|
78
83
|
|
|
84
|
+
=== AMQP
|
|
85
|
+
|
|
86
|
+
The AMQP adapter is based on the synchronous AMQP ruby client "Bunny" by celldee [http://github.com/celldee/bunny]. The original AMQP adapter for RosettaQueue was the 'evented' client by Aman Gupta [http://github.com/tmm1/amqp], but the evented model posed some problems for our integration tests. That, and the desire to keep things simple led us to use a synchronous AMQP client.
|
|
87
|
+
|
|
88
|
+
==== Configuration
|
|
89
|
+
|
|
90
|
+
If you are using the AMQP adapter, there are some important rules when defining the adapter and mapping your destinations. Two of the basic building blocks of AMQP are queues and exchanges. Queues bind to exchanges in several different ways. A can queue bind to an exchange and requests messages that match a specific routing key, which is called 'direct exchange' and is analogous to the 'point-to-point' messaging pattern. Alternately, queues can bind to an exchange to receive all messages sent to that exchange; this is called 'fanout exchange' and is analogous to the 'publish-subscribe' pattern. So, when you want to define a simple 'direct-exchange' queue, your queue name must begin with the term "queue".
|
|
91
|
+
|
|
92
|
+
RosettaQueue::Destinations.define do |queue|
|
|
93
|
+
queue.map :test_queue, 'queue.my_test_queue'
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
And, when you want to define a queue that will bind to a 'fanout-exchange', your queue name must begin with the term "fanout".
|
|
97
|
+
|
|
98
|
+
RosettaQueue::Destinations.define do |queue|
|
|
99
|
+
queue.map :test_queue, 'fanout.my_test_queue'
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
Oh, and when defining your adapter, be sure to specify the AMQP adapter as :amqp_synch, not :amqp. This way, if we do get around to adding Aman's evented AMQP client, we can distinguish between the synchronous and asynchronous clients (i.e., :amqp_sync vs. :amqp_asynch).
|
|
103
|
+
|
|
79
104
|
|
|
80
105
|
== How to contribute
|
|
81
106
|
----------------------------------------------------------------
|
|
82
107
|
Gems you will need:
|
|
83
|
-
cucumber, rspec, yaml, stomp,
|
|
108
|
+
cucumber, rspec, yaml, stomp, bunny, beanstalk-client
|
|
84
109
|
|
|
85
110
|
You should be able to run the rspec code examples (specs) without any brokers running with autospec or 'rake spec'.
|
|
86
111
|
|
data/Rakefile
CHANGED
|
@@ -18,8 +18,8 @@ begin
|
|
|
18
18
|
s.name = "rosetta_queue"
|
|
19
19
|
s.rubyforge_project = "rosetta-queue"
|
|
20
20
|
s.summary = %Q{Messaging gateway API with adapters for many messaging systems available in Ruby.}
|
|
21
|
-
s.email = "
|
|
22
|
-
s.homepage = "http://github.com/
|
|
21
|
+
s.email = "cbwyckoff@gmail.com"
|
|
22
|
+
s.homepage = "http://github.com/cwyckoff/rosetta_queue"
|
|
23
23
|
s.description = %Q{Messaging gateway API with adapters for many messaging systems available in Ruby. Messaging systems can be easily switched out with a small configuration change. Code for testing on the object and application level is also provided.}
|
|
24
24
|
s.extra_rdoc_files = ["README.rdoc", "MIT-LICENSE.txt"]
|
|
25
25
|
s.files = FileList["[A-Z]*.*", "{bin,generators,lib,features,spec}/**/*", "Rakefile", "cucumber.yml"]
|
data/lib/rosetta_queue.rb
CHANGED
|
@@ -11,6 +11,8 @@ require 'rosetta_queue/filters'
|
|
|
11
11
|
require 'rosetta_queue/logger'
|
|
12
12
|
require 'rosetta_queue/message_handler'
|
|
13
13
|
require 'rosetta_queue/producer'
|
|
14
|
+
require 'rosetta_queue/consumer_managers/base'
|
|
15
|
+
require 'rosetta_queue/consumer_managers/threaded'
|
|
14
16
|
|
|
15
17
|
if defined?(Rails)
|
|
16
18
|
RosettaQueue.logger = RosettaQueue::Logger.new(File.join(Rails.root, 'log', 'rosetta_queue.log'))
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
require '
|
|
1
|
+
require 'bunny'
|
|
2
2
|
|
|
3
3
|
module RosettaQueue
|
|
4
4
|
module Gateway
|
|
5
5
|
|
|
6
|
-
# This AMQP adapter utilizes
|
|
7
|
-
# by
|
|
8
|
-
class
|
|
6
|
+
# This AMQP adapter utilizes the synchronous AMPQ client 'Bunny'
|
|
7
|
+
# by celldee (http://github.com/celldee/bunny)
|
|
8
|
+
class AmqpSynchAdapter < BaseAdapter
|
|
9
9
|
|
|
10
10
|
def initialize(adapter_settings = {})
|
|
11
11
|
raise AdapterException, "Missing adapter settings" if adapter_settings.empty?
|
|
@@ -40,11 +40,11 @@ module RosettaQueue
|
|
|
40
40
|
|
|
41
41
|
def exchange_strategy_for(destination, options)
|
|
42
42
|
case destination
|
|
43
|
-
when
|
|
43
|
+
when /^fanout\./
|
|
44
44
|
@exchange ||= AmqpExchangeStrategies::FanoutExchange.new(@adapter_settings, options)
|
|
45
|
-
when
|
|
45
|
+
when /^topic\./
|
|
46
46
|
raise "Sorry. RosettaQueue can not process AMQP topics yet"
|
|
47
|
-
when
|
|
47
|
+
when /^queue\./
|
|
48
48
|
@exchange ||= AmqpExchangeStrategies::DirectExchange.new(@adapter_settings, options)
|
|
49
49
|
else
|
|
50
50
|
@exchange ||= AmqpExchangeStrategies::DirectExchange.new(@adapter_settings, options)
|
|
@@ -66,12 +66,15 @@ module RosettaQueue
|
|
|
66
66
|
end
|
|
67
67
|
|
|
68
68
|
protected
|
|
69
|
+
|
|
69
70
|
def conn
|
|
70
71
|
vhost = @adapter_settings[:opts][:vhost] || "/"
|
|
71
|
-
@conn ||=
|
|
72
|
+
@conn ||= Bunny.new( :user => @adapter_settings[:user],
|
|
72
73
|
:pass => @adapter_settings[:password],
|
|
73
74
|
:host => @adapter_settings[:host],
|
|
74
75
|
:vhost => vhost)
|
|
76
|
+
@conn.start unless @conn.status == :connected
|
|
77
|
+
@conn
|
|
75
78
|
end
|
|
76
79
|
end
|
|
77
80
|
|
|
@@ -83,15 +86,21 @@ module RosettaQueue
|
|
|
83
86
|
end
|
|
84
87
|
|
|
85
88
|
def receive(destination, message_handler)
|
|
86
|
-
conn.queue(destination, @options)
|
|
89
|
+
queue = conn.queue(destination, @options)
|
|
90
|
+
ack = @options[:ack]
|
|
91
|
+
queue.subscribe(@options) do |msg|
|
|
87
92
|
RosettaQueue.logger.info("Receiving from #{destination} :: #{msg}")
|
|
88
93
|
message_handler.on_message(Filters.process_receiving(msg))
|
|
94
|
+
queue.ack if ack
|
|
89
95
|
end
|
|
90
96
|
end
|
|
91
97
|
|
|
92
98
|
def receive_once(destination, options={})
|
|
93
|
-
|
|
99
|
+
q = conn.queue(destination, @options)
|
|
100
|
+
ack = @options[:ack]
|
|
101
|
+
msg = q.pop(options)
|
|
94
102
|
RosettaQueue.logger.info("Receiving from #{destination} :: #{msg}")
|
|
103
|
+
q.ack if ack
|
|
95
104
|
yield Filters.process_receiving(msg)
|
|
96
105
|
end
|
|
97
106
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cwyckoff-rosetta_queue
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ben Mabey
|
|
@@ -31,7 +31,7 @@ files:
|
|
|
31
31
|
- lib/rosetta_queue
|
|
32
32
|
- lib/rosetta_queue/adapter.rb
|
|
33
33
|
- lib/rosetta_queue/adapters
|
|
34
|
-
- lib/rosetta_queue/adapters/
|
|
34
|
+
- lib/rosetta_queue/adapters/amqp_synch.rb
|
|
35
35
|
- lib/rosetta_queue/adapters/base.rb
|
|
36
36
|
- lib/rosetta_queue/adapters/fake.rb
|
|
37
37
|
- lib/rosetta_queue/adapters/null.rb
|