euston-rabbitmq 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +2 -0
- data/Rakefile +0 -21
- data/euston-rabbitmq.gemspec +26 -37
- data/lib/euston-rabbitmq/{bindings → euston}/command_handler_binder.rb +2 -2
- data/lib/euston-rabbitmq/{errors.rb → euston/errors.rb} +1 -1
- data/lib/euston-rabbitmq/{bindings → euston}/event_handler_binder.rb +4 -4
- data/lib/euston-rabbitmq/{exchanges.rb → euston/exchanges.rb} +1 -1
- data/lib/euston-rabbitmq/{bindings → euston}/handler_binder.rb +2 -1
- data/lib/euston-rabbitmq/{queues.rb → euston/queues.rb} +1 -1
- data/lib/euston-rabbitmq/{subscriptions/retriable_subscription.rb → euston/retrying_subscription.rb} +17 -16
- data/lib/euston-rabbitmq/rabbitmq_client/queue.rb +70 -0
- data/lib/euston-rabbitmq/rabbitmq_client/reactive_message.rb +15 -0
- data/lib/euston-rabbitmq/{constant_loader.rb → reflection/constant_loader.rb} +0 -0
- data/lib/euston-rabbitmq/{handler_finder.rb → reflection/handler_finder.rb} +0 -0
- data/lib/euston-rabbitmq/{handler_reference.rb → reflection/handler_reference.rb} +0 -0
- data/lib/euston-rabbitmq/version.rb +1 -1
- data/lib/euston-rabbitmq.rb +8 -22
- data/spec/euston/command_handler_binder_spec.rb +24 -0
- data/spec/euston/event_handler_binder_spec.rb +36 -0
- data/spec/euston/exchanges_spec.rb +27 -0
- data/spec/euston/queues_spec.rb +24 -0
- data/spec/euston/retrying_subscription_spec.rb +74 -0
- data/spec/rabbitmq_client/queue_spec.rb +69 -0
- data/spec/{constant_loader_spec.rb → reflection/constant_loader_spec.rb} +3 -1
- data/spec/{handler_finder_spec.rb → reflection/handler_finder_spec.rb} +3 -1
- data/spec/spec_helper.rb +19 -52
- data/spec/support/filters.rb +10 -0
- data/spec/support/queue_subscription_thread_harness.rb +29 -0
- data/spec/support/rabbitmqadmin.rb +74 -0
- metadata +58 -117
- data/lib/euston-rabbitmq/command_handlers/retry_failed_message.rb +0 -29
- data/lib/euston-rabbitmq/event_handlers/message_failure.rb +0 -27
- data/lib/euston-rabbitmq/message_buffer.rb +0 -67
- data/lib/euston-rabbitmq/message_logger.rb +0 -50
- data/lib/euston-rabbitmq/queue.rb +0 -30
- data/lib/euston-rabbitmq/read_model/failed_message.rb +0 -36
- data/lib/euston-rabbitmq/read_model/message_buffer.rb +0 -57
- data/lib/euston-rabbitmq/read_model/message_log.rb +0 -37
- data/spec/command_buffer_spec.rb +0 -69
- data/spec/event_buffer_spec.rb +0 -69
- data/spec/exchange_declaration_spec.rb +0 -28
- data/spec/message_failure_spec.rb +0 -77
- data/spec/mt_safe_queue_subscription_spec.rb +0 -72
- data/spec/safe_queue_subscription_spec.rb +0 -50
- data/spec/support/factories.rb +0 -18
@@ -0,0 +1,24 @@
|
|
1
|
+
require File.expand_path('../../spec_helper.rb', __FILE__)
|
2
|
+
if jruby?
|
3
|
+
|
4
|
+
module CommandHandlerBinderTesting
|
5
|
+
class AbcHandler
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
describe 'command handler binder', :rabbitmq do
|
10
|
+
include Euston::RabbitMq::Exchanges
|
11
|
+
include Euston::RabbitMq::Queues
|
12
|
+
|
13
|
+
let(:handler) { CommandHandlerBinderTesting::AbcHandler }
|
14
|
+
let(:handler_finder) { Euston::RabbitMq::HandlerFinder.new.tap { |f| f.namespaces.push 'CommandHandlerBinderTesting' } }
|
15
|
+
let(:binder) { Euston::RabbitMq::CommandHandlerBinder.new handler_finder.find }
|
16
|
+
let(:bindings) { @rabbitmqadmin.list_bindings AMQP_OPTS[:vhost] }
|
17
|
+
|
18
|
+
before { binder.ensure_bindings_exist }
|
19
|
+
|
20
|
+
subject { bindings }
|
21
|
+
|
22
|
+
it { should satisfy { |bindings| bindings.any? { |b| b[:routing_key] == 'commands.abc_handler' && b[:destination] == 'command_handlers' } } }
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require File.expand_path('../../spec_helper.rb', __FILE__)
|
2
|
+
if jruby?
|
3
|
+
|
4
|
+
module EventHandlerBinderTesting
|
5
|
+
class XyzHandler
|
6
|
+
include Euston::EventHandler
|
7
|
+
|
8
|
+
consumes :action_abc, 1 do |headers, event| end
|
9
|
+
consumes :action_xyz, 1 do |headers, event| end
|
10
|
+
end
|
11
|
+
|
12
|
+
class ZzzHandler
|
13
|
+
include Euston::EventHandler
|
14
|
+
|
15
|
+
consumes :action_abc, 1 do |headers, event| end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe 'event handler binder', :rabbitmq do
|
20
|
+
include Euston::RabbitMq::Exchanges
|
21
|
+
include Euston::RabbitMq::Queues
|
22
|
+
|
23
|
+
let(:handler) { EventHandlerBinderTesting::XyzHandler }
|
24
|
+
let(:handler_finder) { Euston::RabbitMq::HandlerFinder.new.tap { |f| f.namespaces.push 'EventHandlerBinderTesting' } }
|
25
|
+
let(:binder) { Euston::RabbitMq::EventHandlerBinder.new handler_finder.find }
|
26
|
+
let(:bindings) { @rabbitmqadmin.list_bindings AMQP_OPTS[:vhost] }
|
27
|
+
|
28
|
+
before { binder.ensure_bindings_exist }
|
29
|
+
|
30
|
+
subject { bindings }
|
31
|
+
|
32
|
+
it { should satisfy { |bindings| bindings.any? { |b| b[:routing_key] == 'events.action_abc' && b[:destination] == 'xyz_handler' } } }
|
33
|
+
it { should satisfy { |bindings| bindings.any? { |b| b[:routing_key] == 'events.action_xyz' && b[:destination] == 'xyz_handler' } } }
|
34
|
+
it { should satisfy { |bindings| bindings.any? { |b| b[:routing_key] == 'events.action_abc' && b[:destination] == 'zzz_handler' } } }
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require File.expand_path('../../spec_helper.rb', __FILE__)
|
2
|
+
if jruby?
|
3
|
+
|
4
|
+
describe 'exchanges', :rabbitmq do
|
5
|
+
include Euston::RabbitMq::Exchanges
|
6
|
+
|
7
|
+
context 'creating the commands exchange' do
|
8
|
+
subject { get_exchange @channel, :commands }
|
9
|
+
its(:name) { should == 'commands' }
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'creating the events exchange' do
|
13
|
+
subject { get_exchange @channel, :events }
|
14
|
+
its(:name) { should == 'events' }
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'obtaining the same exchange instance' do
|
18
|
+
let(:name) { "exchange_#{Time.now.to_i}" }
|
19
|
+
let(:instance_1) { get_exchange @channel, name }
|
20
|
+
let(:instance_2) { get_exchange @channel, name }
|
21
|
+
|
22
|
+
subject { instance_1 }
|
23
|
+
|
24
|
+
it { should equal instance_2 }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require File.expand_path('../../spec_helper.rb', __FILE__)
|
2
|
+
if jruby?
|
3
|
+
|
4
|
+
describe 'queues', :rabbitmq do
|
5
|
+
include Euston::RabbitMq::Queues
|
6
|
+
|
7
|
+
let(:name) { "queue_#{Time.now.to_i}" }
|
8
|
+
|
9
|
+
context 'creating a queue' do
|
10
|
+
subject { get_queue @channel, name }
|
11
|
+
|
12
|
+
its(:name) { should == name }
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'obtaining the same queue instance' do
|
16
|
+
let(:instance_1) { get_queue(@channel, name) }
|
17
|
+
let(:instance_2) { get_queue(@channel, name) }
|
18
|
+
|
19
|
+
subject { instance_1 }
|
20
|
+
|
21
|
+
it { should equal instance_2 }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require File.expand_path('../../spec_helper.rb', __FILE__)
|
2
|
+
if jruby?
|
3
|
+
|
4
|
+
describe 'retrying subscription', :rabbitmq do
|
5
|
+
include Euston::RabbitMq::Exchanges
|
6
|
+
include Euston::RabbitMq::Queues
|
7
|
+
|
8
|
+
let(:failing_queue_name) { :failing_handler }
|
9
|
+
let(:failing_message_queue_name) { :failed_message_handler }
|
10
|
+
let(:events_exchange) { get_exchange @channel, :events }
|
11
|
+
let(:failing_handler_queue) { get_queue @channel, failing_queue_name }
|
12
|
+
let(:failed_message_handler_queue) { get_queue @channel, failing_message_queue_name }
|
13
|
+
let(:failing_message_handler_queue_harness) { QueueSubscriptionThreadHarness.new failed_message_handler_queue }
|
14
|
+
let(:outcomes) { { :attempts_to_handle => 0, :failure => nil } }
|
15
|
+
let(:message) { { :x => 123 } }
|
16
|
+
let(:routing_key) { 'events.failing' }
|
17
|
+
let(:error) { 'kablammo' }
|
18
|
+
|
19
|
+
before do
|
20
|
+
failing_handler_queue.bind events_exchange, :routing_key => routing_key
|
21
|
+
failed_message_handler_queue.bind events_exchange, :routing_key => 'events.message_failed'
|
22
|
+
|
23
|
+
@thread = Thread.new(failing_queue_name, fail_limit, outcomes) do |name, fail_limit, outcomes|
|
24
|
+
channel = AMQP::Channel.new
|
25
|
+
subscription = Euston::RabbitMq::RetryingSubscription.new channel, name
|
26
|
+
subscription.when(:message_received => ->(body) { outcomes[:attempts_to_handle] += 1; raise error if outcomes[:attempts_to_handle] <= fail_limit })
|
27
|
+
subscription.subscribe
|
28
|
+
end
|
29
|
+
|
30
|
+
@thread.abort_on_exception = true
|
31
|
+
failing_message_handler_queue_harness.when(:message_received => ->(body) { outcomes[:failure] = body })
|
32
|
+
failing_message_handler_queue_harness.startup
|
33
|
+
|
34
|
+
events_exchange.publish ActiveSupport::JSON.encode(message), { :key => routing_key }
|
35
|
+
|
36
|
+
sleep 0.25
|
37
|
+
end
|
38
|
+
|
39
|
+
after do
|
40
|
+
failing_message_handler_queue_harness.shutdown
|
41
|
+
@thread.kill
|
42
|
+
end
|
43
|
+
|
44
|
+
subject { outcomes }
|
45
|
+
|
46
|
+
context 'when the message fails once but then succeeds on retry' do
|
47
|
+
let (:fail_limit) { 1 }
|
48
|
+
its([:attempts_to_handle]) { should == 2 }
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'when the message fails twice but then succeeds on retry' do
|
52
|
+
let (:fail_limit) { 2 }
|
53
|
+
its([:attempts_to_handle]) { should == 3 }
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'when the message fails 3 times' do
|
57
|
+
let (:fail_limit) { 3 }
|
58
|
+
its([:attempts_to_handle]) { should == 3 }
|
59
|
+
|
60
|
+
describe 'message failure handler' do
|
61
|
+
subject { outcomes[:failure] }
|
62
|
+
it { should_not be_nil }
|
63
|
+
|
64
|
+
describe 'body' do
|
65
|
+
subject { outcomes[:failure][:body] }
|
66
|
+
its([:message]) { should == message }
|
67
|
+
its([:routing_key]) { should == routing_key }
|
68
|
+
its([:error]) { should == error }
|
69
|
+
its([:backtrace]) { should_not be_nil }
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require File.expand_path('../../spec_helper.rb', __FILE__)
|
2
|
+
if jruby?
|
3
|
+
|
4
|
+
PUBLISH_OPTS = { :immediate => false,
|
5
|
+
:mandatory => true,
|
6
|
+
:persistent => true,
|
7
|
+
:routing_key => 'messages.xyz' }
|
8
|
+
|
9
|
+
describe 'queue', :rabbitmq do
|
10
|
+
let(:queue) { @channel.queue "test-#{Time.now.to_i}", :durable => true, :nowait => false }
|
11
|
+
|
12
|
+
context 'queue api' do
|
13
|
+
subject { queue }
|
14
|
+
|
15
|
+
it { should respond_to(:safe_subscribe) }
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'subscription behaviour' do
|
19
|
+
def publish data
|
20
|
+
exchange.publish data, :immediate => false,
|
21
|
+
:mandatory => true,
|
22
|
+
:persistent => true,
|
23
|
+
:routing_key => 'messages.xyz'
|
24
|
+
sleep 0.25
|
25
|
+
end
|
26
|
+
|
27
|
+
let(:exchange) { @channel.topic "test-#{Time.now.to_i - 1}", :durable => true, :nowait => false }
|
28
|
+
let(:harness) { QueueSubscriptionThreadHarness.new queue }
|
29
|
+
|
30
|
+
before do
|
31
|
+
queue.bind exchange, :routing_key => 'messages.#'
|
32
|
+
|
33
|
+
harness.when(:thread_starting => ->{ Thread.current[:failures] = 0; Thread.current[:successes] = 0 },
|
34
|
+
:message_decode_failed => ->(body, error) { Thread.current[:failures] += 1 },
|
35
|
+
:message_failed => ->(body, error, reactive_message) { Thread.current[:failures] += 1 },
|
36
|
+
:message_received => ->(body) { if body[:a] == 'oops'
|
37
|
+
raise 'Something bad happened'
|
38
|
+
else
|
39
|
+
Thread.current[:successes] += 1
|
40
|
+
end })
|
41
|
+
harness.startup
|
42
|
+
end
|
43
|
+
|
44
|
+
after { harness.shutdown }
|
45
|
+
|
46
|
+
subject { harness.thread }
|
47
|
+
|
48
|
+
context 'a non-json message is received' do
|
49
|
+
before { publish ' *897d- -' }
|
50
|
+
|
51
|
+
its([:failures]) { should == 1}
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'a json message is received' do
|
55
|
+
context 'the message is processed successfully' do
|
56
|
+
before { publish JSON.generate({ :a => :b }) }
|
57
|
+
|
58
|
+
its([:successes]) { should == 1 }
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'the message generated an error in the handler' do
|
62
|
+
before { publish JSON.generate({ :a => 'oops' }) }
|
63
|
+
|
64
|
+
its([:failures]) { should == 1 }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
|
-
require File.expand_path('
|
1
|
+
require File.expand_path('../../spec_helper.rb', __FILE__)
|
2
|
+
if jruby?
|
2
3
|
|
3
4
|
module ConstantLoaderTesting
|
4
5
|
module SubNamespace
|
@@ -36,3 +37,4 @@ describe 'constant loader' do
|
|
36
37
|
its([:miss]) { should == true }
|
37
38
|
end
|
38
39
|
end
|
40
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
|
-
require File.expand_path('
|
1
|
+
require File.expand_path('../../spec_helper.rb', __FILE__)
|
2
|
+
if jruby?
|
2
3
|
|
3
4
|
module HandlerFinderTesting
|
4
5
|
module EmptyNamespace; end
|
@@ -46,3 +47,4 @@ describe 'handler finder' do
|
|
46
47
|
it { should have(1).items }
|
47
48
|
end
|
48
49
|
end
|
50
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,65 +1,32 @@
|
|
1
|
-
AMQP_OPTS = { :user => 'euston-rabbitmq-tester',
|
2
|
-
:pass => 'password',
|
3
|
-
:host => 'localhost',
|
4
|
-
:vhost => '/euston-rabbitmq-test' }
|
5
|
-
|
6
1
|
require 'ap'
|
7
2
|
require 'euston-rabbitmq'
|
8
|
-
require 'evented-spec' unless RUBY_PLATFORM == 'java'
|
9
|
-
require 'faker'
|
10
|
-
require_rel 'support'
|
11
3
|
|
12
|
-
def
|
13
|
-
|
14
|
-
array.pop
|
15
|
-
array
|
4
|
+
def jruby?
|
5
|
+
RUBY_PLATFORM.to_s == 'java'
|
16
6
|
end
|
17
7
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
scope.send :include, EventedSpec::AMQPSpec
|
22
|
-
scope.send :default_options, AMQP_OPTS
|
23
|
-
scope.send :default_timeout, 60
|
24
|
-
end
|
25
|
-
|
26
|
-
scope.send :before, :each do
|
27
|
-
vhosts = `rabbitmqctl list_vhosts`.split("\n")
|
28
|
-
vhosts = trim_array_ends vhosts
|
29
|
-
vhost = '/euston-rabbitmq-test'
|
30
|
-
|
31
|
-
`rabbitmqctl delete_vhost #{vhost}` if vhosts.include? vhost
|
32
|
-
`rabbitmqctl add_vhost #{vhost}`
|
8
|
+
Safely.configure do |config|
|
9
|
+
config.strategies = [ Safely::Strategy::Log ]
|
10
|
+
end
|
33
11
|
|
34
|
-
|
35
|
-
|
36
|
-
users = users.map { |u| u.split("\t").shift }
|
12
|
+
if jruby?
|
13
|
+
require_rel 'support'
|
37
14
|
|
38
|
-
|
15
|
+
AMQP_OPTS = { :host => 'localhost',
|
16
|
+
:pass => 'password',
|
17
|
+
:user => 'euston-rabbitmq-test',
|
18
|
+
:vhost => 'euston-rabbitmq-test' }
|
39
19
|
|
40
|
-
|
41
|
-
|
42
|
-
`rabbitmqctl set_permissions -p #{vhost} #{user} ".*" ".*" ".*"`
|
43
|
-
`rabbitmqctl set_permissions -p #{vhost} guest ".*" ".*" ".*"` if users.include? 'guest'
|
44
|
-
end
|
20
|
+
RSpec.configure do |config|
|
21
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
45
22
|
|
46
|
-
|
47
|
-
|
48
|
-
db = connection.db('euston-rabbitmq-test-event-store')
|
49
|
-
db.collections.select { |c| c.name !~ /system/ }.each { |c| db.drop_collection c.name }
|
50
|
-
Euston::RabbitMq.event_store_mongodb = db
|
23
|
+
config.before(:each, :amqp) do
|
24
|
+
initialize_amqp
|
51
25
|
end
|
52
26
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
@channel = AMQP::Channel.new
|
57
|
-
end
|
58
|
-
else
|
59
|
-
scope.send :amqp_before do
|
60
|
-
@channel = AMQP::Channel.new
|
61
|
-
@channel.should be_open
|
62
|
-
end
|
27
|
+
config.before(:each, :rabbitmq) do
|
28
|
+
initialize_rabbitmq
|
29
|
+
initialize_amqp
|
63
30
|
end
|
64
31
|
end
|
65
|
-
end
|
32
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
def initialize_amqp
|
2
|
+
AMQP.settings.merge! AMQP_OPTS
|
3
|
+
@channel = AMQP::Channel.new
|
4
|
+
end
|
5
|
+
|
6
|
+
def initialize_rabbitmq
|
7
|
+
@rabbitmqadmin = RabbitMqAdmin.new
|
8
|
+
@rabbitmqadmin.initialize_vhost AMQP_OPTS[:vhost]
|
9
|
+
@rabbitmqadmin.initialize_user AMQP_OPTS[:vhost], AMQP_OPTS[:user], AMQP_OPTS[:pass]
|
10
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class QueueSubscriptionThreadHarness
|
2
|
+
include Hollywood
|
3
|
+
|
4
|
+
def initialize queue
|
5
|
+
@queue = queue
|
6
|
+
end
|
7
|
+
|
8
|
+
attr_reader :thread
|
9
|
+
|
10
|
+
def startup
|
11
|
+
cb = Hollywood.instance_method(:callback).bind self
|
12
|
+
|
13
|
+
@thread = Thread.new(cb, @queue) do |cb, queue|
|
14
|
+
cb.call :thread_starting
|
15
|
+
|
16
|
+
queue.when(:message_decode_failed => ->(body, error) { cb.call :message_decode_failed, body, error },
|
17
|
+
:message_failed => ->(body, error, reactive_message) { cb.call :message_failed, body, error, reactive_message },
|
18
|
+
:message_received => ->(body) { cb.call :message_received, body })
|
19
|
+
|
20
|
+
queue.safe_subscribe
|
21
|
+
end
|
22
|
+
|
23
|
+
@thread.abort_on_exception = true
|
24
|
+
end
|
25
|
+
|
26
|
+
def shutdown
|
27
|
+
@thread.kill
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
class RabbitMqAdmin
|
2
|
+
def initialize admin_user = 'guest', admin_password = 'guest'
|
3
|
+
@admin_user = admin_user
|
4
|
+
@admin_password = admin_password
|
5
|
+
end
|
6
|
+
|
7
|
+
def delete_exchanges
|
8
|
+
list_exchanges.each { |exchange| `#{run vhost} delete exchange name=#{exchange[:name]}` }
|
9
|
+
end
|
10
|
+
|
11
|
+
def delete_queues
|
12
|
+
list_queues.each { |queue| `#{run vhost} delete queue name=#{queue[:name]}` }
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize_user vhost, user, password, tags = ''
|
16
|
+
`#{run} delete user name=#{user}` if user_exists? user
|
17
|
+
`#{run} declare user name=#{user} password=#{password} tags=#{tags}`
|
18
|
+
add_user_to_vhost vhost, user
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize_vhost vhost
|
22
|
+
`#{run} delete vhost name=#{vhost}` if vhost_exists? vhost
|
23
|
+
`#{run} declare vhost name=#{vhost}`
|
24
|
+
add_user_to_vhost vhost, @admin_user
|
25
|
+
end
|
26
|
+
|
27
|
+
def run vhost = nil
|
28
|
+
vhost_arg = vhost.nil? ? '' : "-V #{vhost}"
|
29
|
+
|
30
|
+
"rabbitmqadmin -u #{@admin_user} -p #{@admin_password} -f raw_json #{vhost_arg}"
|
31
|
+
end
|
32
|
+
|
33
|
+
def list_bindings vhost
|
34
|
+
parse `#{run vhost} list bindings`
|
35
|
+
end
|
36
|
+
|
37
|
+
def list_exchanges vhost
|
38
|
+
parse `#{run vhost} list exchanges`
|
39
|
+
end
|
40
|
+
|
41
|
+
def list_queues vhost
|
42
|
+
parse `#{run vhost} list queues`
|
43
|
+
end
|
44
|
+
|
45
|
+
def list_users
|
46
|
+
parse `#{run} list users`
|
47
|
+
end
|
48
|
+
|
49
|
+
def list_vhosts
|
50
|
+
parse `#{run} list vhosts`
|
51
|
+
end
|
52
|
+
|
53
|
+
def purge_queues
|
54
|
+
list_queues.each { |queue| `#{run vhost} purge queue name=#{queue[:name]}` }
|
55
|
+
end
|
56
|
+
|
57
|
+
def user_exists? user
|
58
|
+
list_users.any? { |u| u[:name] == user }
|
59
|
+
end
|
60
|
+
|
61
|
+
def vhost_exists? vhost
|
62
|
+
list_vhosts.any? { |h| h[:name] == vhost }
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def parse json
|
68
|
+
JSON.parse json, :symbolize_names => true
|
69
|
+
end
|
70
|
+
|
71
|
+
def add_user_to_vhost vhost, user
|
72
|
+
`#{run} -V #{vhost} declare permission vhost=#{vhost} user=#{user} configure=\"\.\*\" write=\"\.\*\" read=\"\.\*\"`
|
73
|
+
end
|
74
|
+
end
|