bmabey-rosetta_queue 0.1.3 → 0.2.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/History.txt +23 -2
- data/README.rdoc +90 -18
- data/Rakefile +2 -2
- data/VERSION.yml +2 -2
- data/examples/sample_amqp_consumer.rb +35 -0
- data/examples/sample_amqp_fanout_consumer.rb +49 -0
- data/examples/sample_amqp_fanout_producer.rb +17 -0
- data/examples/sample_amqp_producer.rb +15 -0
- data/features/filtering.feature +5 -9
- data/features/messaging.feature +40 -0
- data/features/step_definitions/common_messaging_steps.rb +45 -0
- data/features/{messaging/step_definitions → step_definitions}/point_to_point_steps.rb +4 -12
- data/features/{messaging/step_definitions → step_definitions}/publish_subscribe_steps.rb +3 -3
- data/features/support/env.rb +1 -5
- data/lib/rosetta_queue/adapter.rb +14 -8
- data/lib/rosetta_queue/adapters/amqp.rb +21 -142
- data/lib/rosetta_queue/adapters/amqp_evented.rb +132 -0
- data/lib/rosetta_queue/adapters/amqp_synch.rb +117 -0
- data/lib/rosetta_queue/adapters/base.rb +1 -1
- data/lib/rosetta_queue/adapters/beanstalk.rb +3 -3
- data/lib/rosetta_queue/adapters/null.rb +2 -2
- data/lib/rosetta_queue/adapters/stomp.rb +7 -2
- data/lib/rosetta_queue/consumer.rb +8 -1
- data/lib/rosetta_queue/consumer_managers/base.rb +1 -1
- data/lib/rosetta_queue/filters.rb +1 -3
- data/lib/rosetta_queue/logger.rb +1 -1
- data/lib/rosetta_queue/producer.rb +2 -10
- data/lib/rosetta_queue/spec_helpers/helpers.rb +1 -1
- data/lib/rosetta_queue.rb +4 -1
- data/spec/rosetta_queue/adapter_spec.rb +46 -0
- data/spec/rosetta_queue/adapters/{amqp_spec.rb → amqp_synchronous_spec.rb} +109 -121
- data/spec/rosetta_queue/adapters/beanstalk_spec.rb +1 -1
- data/spec/rosetta_queue/adapters/null_spec.rb +1 -1
- data/spec/rosetta_queue/adapters/shared_adapter_behavior.rb +4 -4
- data/spec/rosetta_queue/adapters/shared_fanout_behavior.rb +7 -7
- data/spec/rosetta_queue/adapters/stomp_spec.rb +3 -3
- data/spec/rosetta_queue/consumer_spec.rb +25 -1
- data/spec/spec_helper.rb +3 -1
- metadata +18 -11
- data/features/messaging/point_to_point.feature +0 -30
- data/features/support/common_messaging_steps.rb +0 -28
@@ -1,166 +1,45 @@
|
|
1
|
-
require 'mq'
|
2
|
-
|
3
|
-
# AMQP
|
4
|
-
# connections:
|
5
|
-
# - unlike stomp, we can share one connection across multiple channels
|
6
|
-
# - set host and authorization options on AMQP.connect
|
7
|
-
#
|
8
|
-
# MQ
|
9
|
-
# create new channel for an AMQP connection
|
10
|
-
# options for queue and exchange objects include:
|
11
|
-
# - :durable => true
|
12
|
-
# - :ack => "client" ????
|
13
|
-
|
14
1
|
module RosettaQueue
|
15
2
|
module Gateway
|
16
3
|
|
17
|
-
|
4
|
+
module Fanout
|
5
|
+
def fanout_name_for(destination)
|
6
|
+
fanout_name = destination.gsub(/(topic|fanout)\/(.*)/, '\2')
|
7
|
+
raise AdapterException, "Unable to discover fanout exchange. Cannot bind queue to exchange!" unless fanout_name
|
8
|
+
fanout_name
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class Amqp < BaseAdapter
|
18
13
|
|
19
|
-
def initialize(
|
20
|
-
|
14
|
+
def initialize(adapter_settings = {})
|
15
|
+
raise AdapterException, "Missing adapter settings" if adapter_settings.empty?
|
16
|
+
@adapter_settings = adapter_settings
|
21
17
|
end
|
22
18
|
|
23
|
-
def
|
19
|
+
def delete(destination, opts={})
|
20
|
+
exchange_strategy_for(destination, opts).delete(destination)
|
21
|
+
end
|
22
|
+
|
23
|
+
def disconnect(message_handler); end
|
24
24
|
|
25
25
|
def receive_once(destination, opts={})
|
26
|
-
exchange_strategy_for(destination).
|
26
|
+
exchange_strategy_for(destination, opts).receive_once(destination) do |msg|
|
27
27
|
return msg
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
31
|
def receive_with(message_handler)
|
32
|
+
options = options_for(message_handler)
|
32
33
|
destination = destination_for(message_handler)
|
33
|
-
exchange_strategy_for(destination).
|
34
|
+
exchange_strategy_for(destination, options).receive(destination, message_handler)
|
34
35
|
end
|
35
36
|
|
36
37
|
def send_message(destination, message, options=nil)
|
37
|
-
exchange_strategy_for(destination).
|
38
|
+
exchange_strategy_for(destination, options).publish(destination, message)
|
38
39
|
end
|
39
40
|
|
40
41
|
def unsubscribe; end
|
41
|
-
|
42
|
-
def exchange_strategy_for(destination)
|
43
|
-
case destination
|
44
|
-
when /(topic|fanout)/
|
45
|
-
@exchange ||= FanoutExchange.new(@user, @pass, @host)
|
46
|
-
when /queue/
|
47
|
-
@exchange ||= DirectExchange.new(@user, @pass, @host)
|
48
|
-
else
|
49
|
-
@exchange ||= DirectExchange.new(@user, @pass, @host)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
|
55
|
-
class BaseExchange
|
56
|
-
|
57
|
-
def initialize(user, pass, host)
|
58
|
-
@user, @pass, @host = user, pass, host
|
59
|
-
end
|
60
|
-
|
61
|
-
def publish_to_exchange(destination, message, options={})
|
62
|
-
unless EM.reactor_running?
|
63
|
-
EM.run do
|
64
|
-
publish_message(destination, message, options)
|
65
|
-
EM.add_timer(1) { EM.stop_event_loop }
|
66
|
-
end
|
67
|
-
else
|
68
|
-
publish_message(destination, message, options)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
protected
|
73
|
-
|
74
|
-
def channel
|
75
|
-
@channel ||= MQ.new(conn)
|
76
|
-
end
|
77
|
-
|
78
|
-
def conn
|
79
|
-
# AmqpConnect.connection(@user, @pass, @host)
|
80
|
-
@conn ||= AMQP.connect(:user => @user, :pass => @pass, :host => @host)
|
81
|
-
end
|
82
|
-
|
83
|
-
def publish_message(dest, msg, opts)
|
84
|
-
RosettaQueue.logger.info("Publishing to #{dest} :: #{msg}")
|
85
|
-
channel.queue(dest).publish(msg, opts)
|
86
|
-
channel.queue(dest).unsubscribe
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
|
91
|
-
class DirectExchange < BaseExchange
|
92
|
-
|
93
|
-
def do_exchange(destination, message_handler)
|
94
|
-
channel.queue(destination).subscribe do |msg|
|
95
|
-
RosettaQueue.logger.info("Receiving from #{destination} :: #{msg}")
|
96
|
-
message_handler.on_message(Filters.process_receiving(msg))
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
def do_single_exchange(destination, opts={})
|
101
|
-
EM.run do
|
102
|
-
channel.queue(destination).pop do |msg|
|
103
|
-
RosettaQueue.logger.info("Receiving from #{destination} :: #{msg}")
|
104
|
-
yield Filters.process_receiving(msg)
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
|
111
|
-
class FanoutExchange < BaseExchange
|
112
|
-
|
113
|
-
def do_exchange(destination, message_handler)
|
114
|
-
queue = channel.queue("queue_#{self.object_id}")
|
115
|
-
exchange = channel.fanout(fanout_name_for(destination))
|
116
|
-
|
117
|
-
queue.bind(exchange).subscribe do |msg|
|
118
|
-
# channel.queue("queue_#{rand}").bind(channel.fanout(fanout_name_for(destination))).subscribe do |msg|
|
119
|
-
RosettaQueue.logger.info("Receiving from #{destination} :: #{msg}")
|
120
|
-
message_handler.on_message(Filters.process_receiving(msg))
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
def do_single_exchange(destination, opts={})
|
125
|
-
EM.run do
|
126
|
-
queue = channel.queue("queue_#{self.object_id}")
|
127
|
-
exchange = channel.fanout(fanout_name_for(destination))
|
128
|
-
|
129
|
-
queue.bind(exchange).pop do |msg|
|
130
|
-
# channel.queue("queue_#{rand}").bind(channel.fanout(fanout_name_for(destination)), opts).pop do |msg|
|
131
|
-
RosettaQueue.logger.info("Receiving from #{destination} :: #{msg}")
|
132
|
-
yield Filters.process_receiving(msg)
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
protected
|
138
|
-
|
139
|
-
def publish_message(dest, msg, opts)
|
140
|
-
exchange = channel.fanout(fanout_name_for(dest))
|
141
|
-
exchange.publish(msg, opts)
|
142
|
-
# channel.fanout(fanout_name_for(dest), :durable => true).publish(msg, opts)
|
143
|
-
RosettaQueue.logger.info("Publishing to fanout #{dest} :: #{msg}")
|
144
|
-
end
|
145
|
-
|
146
|
-
private
|
147
42
|
|
148
|
-
def fanout_name_for(destination)
|
149
|
-
fanout_name = destination.gsub(/(topic|fanout)\/(.*)/, '\2')
|
150
|
-
raise "Unable to discover fanout exchange. Cannot bind queue to exchange!" unless fanout_name
|
151
|
-
fanout_name
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
class AmqpConnect
|
156
|
-
|
157
|
-
class << self
|
158
|
-
|
159
|
-
def connection(user, pass, host, port=nil)
|
160
|
-
@conn ||= AMQP.connect(:user => user, :pass => pass, :host => host)
|
161
|
-
end
|
162
|
-
|
163
|
-
end
|
164
43
|
end
|
165
44
|
end
|
166
45
|
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'eventmachine'
|
2
|
+
require 'mq'
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + "/amqp.rb")
|
4
|
+
|
5
|
+
module RosettaQueue
|
6
|
+
module Gateway
|
7
|
+
|
8
|
+
class AmqpEventedAdapter < Amqp
|
9
|
+
private
|
10
|
+
|
11
|
+
def exchange_strategy_for(destination, options)
|
12
|
+
case destination
|
13
|
+
when /^fanout\./
|
14
|
+
@exchange ||= EventedExchange::FanoutExchange.new(@adapter_settings, options)
|
15
|
+
when /^topic\./
|
16
|
+
raise "Sorry. RosettaQueue can not process AMQP topics yet"
|
17
|
+
when /^queue\./
|
18
|
+
@exchange ||= EventedExchange::DirectExchange.new(@adapter_settings, options)
|
19
|
+
else
|
20
|
+
@exchange ||= EventedExchange::DirectExchange.new(@adapter_settings, options)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
module EventedExchange
|
26
|
+
|
27
|
+
class BaseExchange
|
28
|
+
|
29
|
+
def initialize(adapter_settings, options={})
|
30
|
+
@adapter_settings, @options = adapter_settings, options
|
31
|
+
end
|
32
|
+
|
33
|
+
def delete(destination)
|
34
|
+
conn.queue(destination).delete(@options)
|
35
|
+
end
|
36
|
+
|
37
|
+
protected
|
38
|
+
|
39
|
+
def channel
|
40
|
+
@channel ||= MQ.new(conn)
|
41
|
+
end
|
42
|
+
|
43
|
+
def conn
|
44
|
+
vhost = @adapter_settings[:opts][:vhost] || "/"
|
45
|
+
@conn ||= AMQP.connect(:user => @adapter_settings[:user],
|
46
|
+
:pass => @adapter_settings[:password],
|
47
|
+
:host => @adapter_settings[:host],
|
48
|
+
:vhost => vhost)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
class DirectExchange < BaseExchange
|
54
|
+
|
55
|
+
def publish(destination, message, options={})
|
56
|
+
raise AdapterException, "Messages need to be published in an EventMachine run block (e.g., EM.run { RosettaQueue::Producer.publish(:foo, msg) } " unless EM.reactor_running?
|
57
|
+
|
58
|
+
queue = channel.queue(destination, options)
|
59
|
+
queue.publish(message, options)
|
60
|
+
RosettaQueue.logger.info("Publishing to #{destination} :: #{message}")
|
61
|
+
queue.unsubscribe
|
62
|
+
end
|
63
|
+
|
64
|
+
def receive(destination, message_handler)
|
65
|
+
raise AdapterException, "Consumers need to run in an EventMachine 'run' block. Try wrapping them inside the evented consumer manager." unless EM.reactor_running?
|
66
|
+
|
67
|
+
queue = channel.queue(destination, @options)
|
68
|
+
ack = @options[:ack]
|
69
|
+
queue.subscribe(@options) do |header, msg|
|
70
|
+
RosettaQueue.logger.info("Receiving from #{destination} :: #{msg}")
|
71
|
+
message_handler.on_message(Filters.process_receiving(msg))
|
72
|
+
header.ack if ack
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def receive_once(destination, options={})
|
77
|
+
raise AdapterException, "Consumers need to run in an EventMachine 'run' block. (e.g., EM.run { RosettaQueue::Consumer.receive }" unless EM.reactor_running?
|
78
|
+
|
79
|
+
queue = channel.queue(destination, @options)
|
80
|
+
ack = @options[:ack]
|
81
|
+
queue.pop(@options) do |header, msg|
|
82
|
+
RosettaQueue.logger.info("Receiving from #{destination} :: #{msg}")
|
83
|
+
header.ack if ack
|
84
|
+
yield Filters.process_receiving(msg)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
class FanoutExchange < BaseExchange
|
91
|
+
include Fanout
|
92
|
+
|
93
|
+
def publish(dest, msg, opts)
|
94
|
+
raise AdapterException, "Messages need to be published in an EventMachine run block (e.g., EM.run { RosettaQueue::Producer.publish(:foo, msg) } " unless EM.reactor_running?
|
95
|
+
|
96
|
+
exchange = channel.fanout(fanout_name_for(dest), opts)
|
97
|
+
exchange.publish(msg, opts)
|
98
|
+
RosettaQueue.logger.info("Publishing to fanout #{dest} :: #{msg}")
|
99
|
+
end
|
100
|
+
|
101
|
+
def receive(destination, message_handler)
|
102
|
+
raise AdapterException, "Consumers need to run in an EventMachine 'run' block. Try wrapping them inside the evented consumer manager." unless EM.reactor_running?
|
103
|
+
|
104
|
+
queue = channel.queue("queue_#{self.object_id}")
|
105
|
+
exchange = channel.fanout(fanout_name_for(destination), @options)
|
106
|
+
ack = @options[:ack]
|
107
|
+
|
108
|
+
queue.bind(exchange).subscribe(@options) do |header, msg|
|
109
|
+
RosettaQueue.logger.info("Receiving from #{destination} :: #{msg}")
|
110
|
+
message_handler.on_message(Filters.process_receiving(msg))
|
111
|
+
header.ack if ack
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def receive_once(destination, opts={})
|
116
|
+
raise AdapterException, "Consumers need to run in an EventMachine 'run' block. (e.g., EM.run { RosettaQueue::Consumer.receive }" unless EM.reactor_running?
|
117
|
+
|
118
|
+
queue = channel.queue("queue_#{self.object_id}")
|
119
|
+
exchange = channel.fanout(fanout_name_for(destination), opts)
|
120
|
+
ack = @options[:ack]
|
121
|
+
|
122
|
+
queue.bind(exchange).pop(opts) do |header, msg|
|
123
|
+
RosettaQueue.logger.info("Receiving from #{destination} :: #{msg}")
|
124
|
+
header.ack if ack
|
125
|
+
yield Filters.process_receiving(msg)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'bunny'
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + "/amqp.rb")
|
3
|
+
|
4
|
+
module RosettaQueue
|
5
|
+
module Gateway
|
6
|
+
|
7
|
+
# This AMQP adapter utilizes the synchronous AMPQ client 'Bunny'
|
8
|
+
# by celldee (http://github.com/celldee/bunny)
|
9
|
+
class AmqpSynchAdapter < Amqp
|
10
|
+
private
|
11
|
+
|
12
|
+
def exchange_strategy_for(destination, options)
|
13
|
+
case destination
|
14
|
+
when /^fanout\./
|
15
|
+
@exchange ||= SynchExchange::FanoutExchange.new(@adapter_settings, options)
|
16
|
+
when /^topic\./
|
17
|
+
raise "Sorry. RosettaQueue can not process AMQP topics yet"
|
18
|
+
when /^queue\./
|
19
|
+
@exchange ||= SynchExchange::DirectExchange.new(@adapter_settings, options)
|
20
|
+
else
|
21
|
+
@exchange ||= SynchExchange::DirectExchange.new(@adapter_settings, options)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module SynchExchange
|
27
|
+
|
28
|
+
class BaseExchange
|
29
|
+
|
30
|
+
def initialize(adapter_settings, options={})
|
31
|
+
@adapter_settings, @options = adapter_settings, options
|
32
|
+
end
|
33
|
+
|
34
|
+
def delete(destination)
|
35
|
+
conn.queue(destination).delete(@options)
|
36
|
+
end
|
37
|
+
|
38
|
+
protected
|
39
|
+
|
40
|
+
def conn
|
41
|
+
vhost = @adapter_settings[:opts][:vhost] || "/"
|
42
|
+
@conn ||= Bunny.new( :user => @adapter_settings[:user],
|
43
|
+
:pass => @adapter_settings[:password],
|
44
|
+
:host => @adapter_settings[:host],
|
45
|
+
:vhost => vhost)
|
46
|
+
@conn.start unless @conn.status == :connected
|
47
|
+
@conn
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class DirectExchange < BaseExchange
|
52
|
+
|
53
|
+
def publish(destination, message, options={})
|
54
|
+
RosettaQueue.logger.info("Publishing to #{destination} :: #{message}")
|
55
|
+
queue = conn.queue(destination, options)
|
56
|
+
queue.publish(message, options)
|
57
|
+
queue.unsubscribe
|
58
|
+
end
|
59
|
+
|
60
|
+
def receive(destination, message_handler)
|
61
|
+
queue = conn.queue(destination, @options)
|
62
|
+
ack = @options[:ack]
|
63
|
+
queue.subscribe(@options) do |msg|
|
64
|
+
RosettaQueue.logger.info("Receiving from #{destination} :: #{msg}")
|
65
|
+
message_handler.on_message(Filters.process_receiving(msg))
|
66
|
+
queue.ack if ack
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def receive_once(destination)
|
71
|
+
queue = conn.queue(destination, @options)
|
72
|
+
ack = @options[:ack]
|
73
|
+
msg = queue.pop(@options)
|
74
|
+
RosettaQueue.logger.info("Receiving from #{destination} :: #{msg}")
|
75
|
+
queue.ack if ack
|
76
|
+
yield Filters.process_receiving(msg)
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
class FanoutExchange < BaseExchange
|
82
|
+
include Fanout
|
83
|
+
|
84
|
+
def publish(destination, message, options={})
|
85
|
+
exchange = conn.exchange(fanout_name_for(destination), options.merge({:type => :fanout}))
|
86
|
+
exchange.publish(message, options)
|
87
|
+
RosettaQueue.logger.info("Publishing to fanout #{destination} :: #{message}")
|
88
|
+
end
|
89
|
+
|
90
|
+
def receive(destination, message_handler)
|
91
|
+
queue = conn.queue("queue_#{self.object_id}", @options)
|
92
|
+
exchange = conn.exchange(fanout_name_for(destination), @options.merge({:type => :fanout}))
|
93
|
+
queue.bind(exchange)
|
94
|
+
ack = @options[:ack]
|
95
|
+
|
96
|
+
msg = queue.subscribe(@options) do |msg|
|
97
|
+
RosettaQueue.logger.info("Receiving from #{destination} :: #{msg}")
|
98
|
+
message_handler.on_message(Filters.process_receiving(msg))
|
99
|
+
queue.ack if ack
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def receive_once(destination, options={})
|
104
|
+
queue = conn.queue("queue_#{self.object_id}", options)
|
105
|
+
exchange = conn.exchange(fanout_name_for(destination), options.merge({:type => :fanout}))
|
106
|
+
queue.bind(exchange)
|
107
|
+
ack = @options[:ack]
|
108
|
+
msg = queue.pop(@options)
|
109
|
+
RosettaQueue.logger.info("Receiving from #{destination} :: #{msg}")
|
110
|
+
queue.ack if ack
|
111
|
+
yield Filters.process_receiving(msg)
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -9,9 +9,9 @@ module RosettaQueue
|
|
9
9
|
@conn.ack(msg.headers["message-id"])
|
10
10
|
end
|
11
11
|
|
12
|
-
def initialize(
|
13
|
-
@host, @port = host, port
|
14
|
-
@conn = Beanstalk::Pool.new(["#{host}:#{port}"])
|
12
|
+
def initialize(adapter_settings = {})
|
13
|
+
@host, @port = adapter_settings[:host], adapter_settings[:port]
|
14
|
+
@conn = Beanstalk::Pool.new(["#{@host}:#{@port}"])
|
15
15
|
end
|
16
16
|
|
17
17
|
def disconnect; end
|
@@ -23,7 +23,7 @@ module RosettaQueue
|
|
23
23
|
# to set ENV["RUNNING_STORIES"] = "true" in your helper.rb or env.rb file)
|
24
24
|
class NullAdapter
|
25
25
|
|
26
|
-
def initialize(
|
26
|
+
def initialize(adapter_settings)
|
27
27
|
# no-op
|
28
28
|
end
|
29
29
|
|
@@ -54,4 +54,4 @@ module RosettaQueue
|
|
54
54
|
|
55
55
|
end
|
56
56
|
end
|
57
|
-
end
|
57
|
+
end
|
@@ -9,8 +9,13 @@ module RosettaQueue
|
|
9
9
|
@conn.ack(msg.headers["message-id"])
|
10
10
|
end
|
11
11
|
|
12
|
-
def initialize(
|
13
|
-
|
12
|
+
def initialize(adapter_settings = {})
|
13
|
+
raise "Missing adapter settings" if adapter_settings.empty?
|
14
|
+
@conn = Stomp::Connection.open(adapter_settings[:user],
|
15
|
+
adapter_settings[:password],
|
16
|
+
adapter_settings[:host],
|
17
|
+
adapter_settings[:port],
|
18
|
+
true)
|
14
19
|
end
|
15
20
|
|
16
21
|
def disconnect(message_handler)
|
@@ -5,9 +5,16 @@ module RosettaQueue
|
|
5
5
|
RosettaQueue::Adapter.instance.receive_once(Destinations.lookup(destination), options)
|
6
6
|
|
7
7
|
rescue Exception=>e
|
8
|
-
RosettaQueue.logger.error("Caught exception in Consumer
|
8
|
+
RosettaQueue.logger.error("Caught exception in Consumer.receive: #{$!}\n" + e.backtrace.join("\n\t"))
|
9
9
|
end
|
10
10
|
|
11
|
+
def self.delete(destination, options={})
|
12
|
+
RosettaQueue::Adapter.instance.delete(Destinations.lookup(destination), options)
|
13
|
+
|
14
|
+
rescue Exception=>e
|
15
|
+
RosettaQueue.logger.error("Caught exception in Consumer.delete: #{$!}\n" + e.backtrace.join("\n\t"))
|
16
|
+
end
|
17
|
+
|
11
18
|
def initialize(message_handler)
|
12
19
|
@message_handler = message_handler
|
13
20
|
end
|
data/lib/rosetta_queue/logger.rb
CHANGED
@@ -7,16 +7,8 @@ module RosettaQueue
|
|
7
7
|
RosettaQueue::Adapter.instance.send_message(Destinations.lookup(destination), Filters.process_sending(message), options)
|
8
8
|
|
9
9
|
rescue Exception=>e
|
10
|
-
RosettaQueue.logger.error("Caught exception in Consumer
|
10
|
+
RosettaQueue.logger.error("Caught exception in Consumer.publish: #{$!}\n" + e.backtrace.join("\n\t"))
|
11
11
|
end
|
12
12
|
|
13
|
-
# def publish(message)
|
14
|
-
# begin
|
15
|
-
# connection.send_message(publish_destination, message, options)
|
16
|
-
# rescue Exception=>e
|
17
|
-
# RosettaQueue.logger.error("Caught exception in Producer#publish: #{$!}\n" + e.backtrace.join("\n\t"))
|
18
|
-
# end
|
19
|
-
# end
|
20
|
-
|
21
13
|
end
|
22
|
-
end
|
14
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module RosettaQueue
|
2
2
|
# Adds helpful methods when doing application level testing.
|
3
|
-
# If you are using cucumber just include it in your
|
3
|
+
# If you are using cucumber just include it in your World in the env.rb file:
|
4
4
|
# World {|world| world.extend RosettaQueue::SpecHelpers }
|
5
5
|
module SpecHelpers
|
6
6
|
require 'open-uri'
|
data/lib/rosetta_queue.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__))) unless $LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__)))
|
2
2
|
|
3
|
-
require
|
3
|
+
require('rosetta_queue/core_ext/string') unless defined? ActiveSupport
|
4
4
|
|
5
5
|
require 'rosetta_queue/adapter'
|
6
6
|
require 'rosetta_queue/base'
|
@@ -11,8 +11,11 @@ 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'))
|
17
19
|
require('rosetta_queue/spec_helpers') if Rails.env == "test"
|
18
20
|
end
|
21
|
+
|
@@ -51,5 +51,51 @@ module RosettaQueue
|
|
51
51
|
|
52
52
|
end
|
53
53
|
|
54
|
+
describe "adapter instantiation" do
|
55
|
+
|
56
|
+
before(:each) do
|
57
|
+
Adapter.define do |a|
|
58
|
+
a.user = "foo"
|
59
|
+
a.password = "bar"
|
60
|
+
a.host = "localhost"
|
61
|
+
a.port = "9000"
|
62
|
+
a.type = "fake"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def do_process
|
67
|
+
Adapter.instance
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should set opts as an empty has unless variable is set" do
|
71
|
+
during_process {
|
72
|
+
RosettaQueue::Gateway::FakeAdapter.should_receive(:new).with({:user => "foo", :password => "bar", :host => "localhost", :port => "9000", :opts => {}})
|
73
|
+
}
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "when setting options" do
|
77
|
+
before(:each) do
|
78
|
+
Adapter.define { |a| a.options = {:vhost => "baz"} }
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should map adapter_settings to a hash" do
|
82
|
+
during_process {
|
83
|
+
RosettaQueue::Gateway::FakeAdapter.should_receive(:new).with({:user => "foo", :password => "bar", :host => "localhost", :port => "9000", :opts => {:vhost => "baz"}})
|
84
|
+
}
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe "setting options incorrectly (options should always be set as a Hash)" do
|
89
|
+
|
90
|
+
before(:each) do
|
91
|
+
Adapter.define { |a| a.options = "baz" }
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should raise an adapter exception" do
|
95
|
+
running { Adapter.instance }.should raise_error("Adapter options should be a hash")
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
54
100
|
end
|
55
101
|
end
|