amqp 1.2.1 → 1.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.
- checksums.yaml +4 -4
- data/ChangeLog.md +23 -6
- data/lib/amqp/channel.rb +3 -1
- data/lib/amqp/exchange.rb +140 -8
- data/lib/amqp/version.rb +1 -1
- data/spec/integration/exchange_declaration_spec.rb +22 -0
- data/spec/integration/exchange_to_exchange_binding_spec.rb +124 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c7cd9670c82561f472831d5844d8aedf21704384
|
4
|
+
data.tar.gz: 72de0158e4620a8c11468fa6ae141770f5eb5c40
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0590210e5493862466fc7c5bfaae3322f4fcd4c738f57eba25e811d4d76205b51b6bf327c44941f59a6b93a24436d6961baaafefeaf64c88b378a7faa6a24dba
|
7
|
+
data.tar.gz: b579abed8e4432158e908dd6d4e992c17e815029b89b3ccb6b0a7b15483eb2bb21a7dc49df7fe389e4d9adc04660b19d0dd8ef620a15578d880b18181932cfa9
|
data/ChangeLog.md
CHANGED
@@ -1,4 +1,26 @@
|
|
1
|
-
## Changes Between 1.2.
|
1
|
+
## Changes Between 1.2.x and 1.3.0
|
2
|
+
|
3
|
+
### Exchange-to-Exchange Bindings Support
|
4
|
+
|
5
|
+
amqp gem now supports [Exchange-to-Exchange Bindings](http://www.rabbitmq.com/e2e.html), a RabbitMQ
|
6
|
+
extension.
|
7
|
+
|
8
|
+
`AMQP::Exchange#bind` and `AMQP::Exchange#unbind` work very much like `AMQP::Queue#bind` and
|
9
|
+
`AMQP::Queue#unbind`, with the argument exchange being the source one.
|
10
|
+
|
11
|
+
Contributed by Stefan Kaes.
|
12
|
+
|
13
|
+
### Internal Exchange Declaration
|
14
|
+
|
15
|
+
amqp gem now supports declaration of internal exchanges
|
16
|
+
(used via exchange-to-exchange bindings, cannot be published to
|
17
|
+
by clients).
|
18
|
+
|
19
|
+
To declare an exchange as internal, add `:internal => true` to
|
20
|
+
declaration options.
|
21
|
+
|
22
|
+
Contributed by Stefan Kaes.
|
23
|
+
|
2
24
|
|
3
25
|
### Initial Connection Failures Retries
|
4
26
|
|
@@ -7,7 +29,6 @@ means connection retries succeed.
|
|
7
29
|
|
8
30
|
Contributed by Marius Hanne.
|
9
31
|
|
10
|
-
|
11
32
|
## Changes Between 1.1.0 and 1.2.0
|
12
33
|
|
13
34
|
### [Authentication Failure Notification](http://www.rabbitmq.com/auth-notification.html) Support
|
@@ -53,10 +74,6 @@ very short lived channels.
|
|
53
74
|
`ConnectionClosedError` from `amq-client` is now defined again.
|
54
75
|
|
55
76
|
|
56
|
-
### amq-protocol Update
|
57
|
-
|
58
|
-
Minimum `amq-protocol` version is now `1.9.0`.
|
59
|
-
|
60
77
|
### Fixed Exceptions in AMQP::Exchange#handle_declare_ok
|
61
78
|
|
62
79
|
`AMQP::Exchange#handle_declare_ok` no longer raises an exception
|
data/lib/amqp/channel.rb
CHANGED
@@ -172,7 +172,7 @@ module AMQP
|
|
172
172
|
|
173
173
|
attr_reader :id
|
174
174
|
|
175
|
-
attr_reader :exchanges_awaiting_declare_ok, :exchanges_awaiting_delete_ok
|
175
|
+
attr_reader :exchanges_awaiting_declare_ok, :exchanges_awaiting_delete_ok, :exchanges_awaiting_bind_ok, :exchanges_awaiting_unbind_ok
|
176
176
|
attr_reader :queues_awaiting_declare_ok, :queues_awaiting_delete_ok, :queues_awaiting_bind_ok, :queues_awaiting_unbind_ok, :queues_awaiting_purge_ok, :queues_awaiting_get_response
|
177
177
|
attr_reader :consumers_awaiting_consume_ok, :consumers_awaiting_cancel_ok
|
178
178
|
|
@@ -1424,6 +1424,8 @@ module AMQP
|
|
1424
1424
|
|
1425
1425
|
@queues_awaiting_declare_ok = Array.new
|
1426
1426
|
@exchanges_awaiting_declare_ok = Array.new
|
1427
|
+
@exchanges_awaiting_bind_ok = Array.new
|
1428
|
+
@exchanges_awaiting_unbind_ok = Array.new
|
1427
1429
|
|
1428
1430
|
@queues_awaiting_delete_ok = Array.new
|
1429
1431
|
|
data/lib/amqp/exchange.rb
CHANGED
@@ -365,9 +365,9 @@ module AMQP
|
|
365
365
|
end
|
366
366
|
end
|
367
367
|
|
368
|
-
self.exchange_declare(
|
368
|
+
self.exchange_declare(@opts[:passive], @opts[:durable], @opts[:auto_delete], @opts[:internal], @opts[:nowait], @opts[:arguments], &shim)
|
369
369
|
else
|
370
|
-
self.exchange_declare(
|
370
|
+
self.exchange_declare(@opts[:passive], @opts[:durable], @opts[:auto_delete], @opts[:internal], @opts[:nowait], @opts[:arguments])
|
371
371
|
end
|
372
372
|
end
|
373
373
|
end
|
@@ -422,6 +422,10 @@ module AMQP
|
|
422
422
|
@name && ((@name == AMQ::Protocol::EMPTY_STRING) || !!(@name =~ /^amq\.(direct|fanout|topic|headers|match)/i))
|
423
423
|
end # predefined?
|
424
424
|
|
425
|
+
# @return [Boolean] true if this exchange is an internal exchange
|
426
|
+
def internal?
|
427
|
+
@opts[:internal]
|
428
|
+
end
|
425
429
|
|
426
430
|
# Publishes message to the exchange. The message will be routed to queues by the exchange
|
427
431
|
# and distributed to any active consumers. Routing logic is determined by exchange type and
|
@@ -604,14 +608,15 @@ module AMQP
|
|
604
608
|
# @group Declaration
|
605
609
|
|
606
610
|
# @api public
|
607
|
-
def exchange_declare(passive = false, durable = false, auto_delete = false, nowait = false, arguments = nil, &block)
|
611
|
+
def exchange_declare(passive = false, durable = false, auto_delete = false, internal = false, nowait = false, arguments = nil, &block)
|
608
612
|
# for re-declaration
|
609
613
|
@passive = passive
|
610
614
|
@durable = durable
|
611
615
|
@auto_delete = auto_delete
|
612
616
|
@arguments = arguments
|
617
|
+
@internal = internal
|
613
618
|
|
614
|
-
@connection.send_frame(AMQ::Protocol::Exchange::Declare.encode(@channel.id, @name, @type.to_s, passive, durable, auto_delete,
|
619
|
+
@connection.send_frame(AMQ::Protocol::Exchange::Declare.encode(@channel.id, @name, @type.to_s, passive, durable, auto_delete, internal, nowait, arguments))
|
615
620
|
|
616
621
|
unless nowait
|
617
622
|
self.define_callback(:declare, &block)
|
@@ -625,7 +630,7 @@ module AMQP
|
|
625
630
|
# @api public
|
626
631
|
def redeclare(&block)
|
627
632
|
nowait = block.nil?
|
628
|
-
@connection.send_frame(AMQ::Protocol::Exchange::Declare.encode(@channel.id, @name, @type.to_s, @passive, @durable, @auto_delete,
|
633
|
+
@connection.send_frame(AMQ::Protocol::Exchange::Declare.encode(@channel.id, @name, @type.to_s, @passive, @durable, @auto_delete, @internal, nowait, @arguments))
|
629
634
|
|
630
635
|
unless nowait
|
631
636
|
self.define_callback(:declare, &block)
|
@@ -653,6 +658,111 @@ module AMQP
|
|
653
658
|
end # delete(if_unused = false, nowait = false)
|
654
659
|
|
655
660
|
|
661
|
+
# @group Exchange to Exchange Bindings
|
662
|
+
|
663
|
+
# This method binds a source exchange to a destination exchange. Messages
|
664
|
+
# sent to the source exchange are forwarded to the destination exchange, provided
|
665
|
+
# the message routing key matches the routing key specified when binding the
|
666
|
+
# exchanges.
|
667
|
+
#
|
668
|
+
# A valid exchange name (or reference) must be passed as the first
|
669
|
+
# parameter.
|
670
|
+
# @example Binding two source exchanges to a destination exchange
|
671
|
+
#
|
672
|
+
# ch = AMQP::Channel.new(connection)
|
673
|
+
# source1 = ch.fanout('backlog-events-datacenter-1')
|
674
|
+
# source2 = ch.fanout('backlog-events-datacenter-2')
|
675
|
+
# destination = ch.fanout('baklog-events')
|
676
|
+
# destination.bind(source1).bind(source2)
|
677
|
+
#
|
678
|
+
#
|
679
|
+
# @param [Exchange] Exchange to bind to. May also be a string or any object that responds to #name.
|
680
|
+
#
|
681
|
+
# @option opts [String] :routing_key Specifies the routing key for the binding. The routing key is
|
682
|
+
# used for routing messages depending on the exchange configuration.
|
683
|
+
# Not all exchanges use a routing key! Refer to the specific
|
684
|
+
# exchange documentation.
|
685
|
+
#
|
686
|
+
# @option opts [Hash] :arguments (nil) A hash of optional arguments with the declaration. Headers exchange type uses these metadata
|
687
|
+
# attributes for routing matching.
|
688
|
+
# In addition, brokers may implement AMQP extensions using x-prefixed declaration arguments.
|
689
|
+
#
|
690
|
+
# @option opts [Boolean] :nowait (true) If set, the server will not respond to the method. The client should
|
691
|
+
# not wait for a reply method. If the server could not complete the
|
692
|
+
# method it will raise a channel or connection exception.
|
693
|
+
# @return [Exchange] Self
|
694
|
+
#
|
695
|
+
#
|
696
|
+
# @yield [] Since exchange.bind-ok carries no attributes, no parameters are yielded to the block.
|
697
|
+
#
|
698
|
+
|
699
|
+
# @api public
|
700
|
+
def bind(source, opts = {}, &block)
|
701
|
+
source = source.name if source.respond_to?(:name)
|
702
|
+
routing_key = opts[:key] || opts[:routing_key] || AMQ::Protocol::EMPTY_STRING
|
703
|
+
arguments = opts[:arguments] || {}
|
704
|
+
nowait = opts[:nowait] || block.nil?
|
705
|
+
@channel.once_open do
|
706
|
+
@connection.send_frame(AMQ::Protocol::Exchange::Bind.encode(@channel.id, @name, source, routing_key, nowait, arguments))
|
707
|
+
unless nowait
|
708
|
+
self.define_callback(:bind, &block)
|
709
|
+
@channel.exchanges_awaiting_bind_ok.push(self)
|
710
|
+
end
|
711
|
+
end
|
712
|
+
self
|
713
|
+
end
|
714
|
+
|
715
|
+
# This method unbinds a source exchange from a previously bound destination exchange.
|
716
|
+
#
|
717
|
+
# A valid exchange name (or reference) must be passed as the first
|
718
|
+
# parameter.
|
719
|
+
# @example Binding and unbinding two exchanges
|
720
|
+
#
|
721
|
+
# ch = AMQP::Channel.new(connection)
|
722
|
+
# source = ch.fanout('backlog-events')
|
723
|
+
# destination = ch.fanout('backlog-events-copy')
|
724
|
+
# destination.bind(source)
|
725
|
+
# ...
|
726
|
+
# destination.unbind(source)
|
727
|
+
#
|
728
|
+
#
|
729
|
+
# @param [Exchange] Exchange to bind to. May also be a string or any object that responds to #name.
|
730
|
+
#
|
731
|
+
# @option opts [String] :routing_key Specifies the routing key for the binding. The routing key is
|
732
|
+
# used for routing messages depending on the exchange configuration.
|
733
|
+
# Not all exchanges use a routing key! Refer to the specific
|
734
|
+
# exchange documentation.
|
735
|
+
#
|
736
|
+
# @option opts [Hash] :arguments (nil) A hash of optional arguments with the declaration. Headers exchange type uses these metadata
|
737
|
+
# attributes for routing matching.
|
738
|
+
# In addition, brokers may implement AMQP extensions using x-prefixed declaration arguments.
|
739
|
+
#
|
740
|
+
# @option opts [Boolean] :nowait (true) If set, the server will not respond to the method. The client should
|
741
|
+
# not wait for a reply method. If the server could not complete the
|
742
|
+
# method it will raise a channel or connection exception.
|
743
|
+
# @return [Exchange] Self
|
744
|
+
#
|
745
|
+
#
|
746
|
+
# @yield [] Since exchange.unbind-ok carries no attributes, no parameters are yielded to the block.
|
747
|
+
#
|
748
|
+
|
749
|
+
# @api public
|
750
|
+
def unbind(source, opts = {}, &block)
|
751
|
+
source = source.name if source.respond_to?(:name)
|
752
|
+
routing_key = opts[:key] || opts[:routing_key] || AMQ::Protocol::EMPTY_STRING
|
753
|
+
arguments = opts[:arguments] || {}
|
754
|
+
nowait = opts[:nowait] || block.nil?
|
755
|
+
@channel.once_open do
|
756
|
+
@connection.send_frame(AMQ::Protocol::Exchange::Unbind.encode(@channel.id, @name, source, routing_key, nowait, arguments))
|
757
|
+
unless nowait
|
758
|
+
self.define_callback(:unbind, &block)
|
759
|
+
@channel.exchanges_awaiting_unbind_ok.push(self)
|
760
|
+
end
|
761
|
+
end
|
762
|
+
self
|
763
|
+
end
|
764
|
+
|
765
|
+
# @endgroup
|
656
766
|
|
657
767
|
# @group Publishing Messages
|
658
768
|
|
@@ -750,10 +860,17 @@ module AMQP
|
|
750
860
|
self.exec_callback_once_yielding_self(:declare, method)
|
751
861
|
end
|
752
862
|
|
863
|
+
def handle_bind_ok(method)
|
864
|
+
self.exec_callback_once(:bind, method)
|
865
|
+
end
|
866
|
+
|
867
|
+
def handle_unbind_ok(method)
|
868
|
+
self.exec_callback_once(:unbind, method)
|
869
|
+
end
|
870
|
+
|
753
871
|
def handle_delete_ok(method)
|
754
872
|
self.exec_callback_once(:delete, method)
|
755
|
-
end
|
756
|
-
|
873
|
+
end
|
757
874
|
|
758
875
|
|
759
876
|
self.handle(AMQ::Protocol::Exchange::DeclareOk) do |connection, frame|
|
@@ -764,6 +881,21 @@ module AMQP
|
|
764
881
|
exchange.handle_declare_ok(method)
|
765
882
|
end # handle
|
766
883
|
|
884
|
+
self.handle(AMQ::Protocol::Exchange::BindOk) do |connection, frame|
|
885
|
+
method = frame.decode_payload
|
886
|
+
channel = connection.channels[frame.channel]
|
887
|
+
exchange = channel.exchanges_awaiting_bind_ok.shift
|
888
|
+
|
889
|
+
exchange.handle_bind_ok(method)
|
890
|
+
end # handle
|
891
|
+
|
892
|
+
self.handle(AMQ::Protocol::Exchange::UnbindOk) do |connection, frame|
|
893
|
+
method = frame.decode_payload
|
894
|
+
channel = connection.channels[frame.channel]
|
895
|
+
exchange = channel.exchanges_awaiting_unbind_ok.shift
|
896
|
+
|
897
|
+
exchange.handle_unbind_ok(method)
|
898
|
+
end # handle
|
767
899
|
|
768
900
|
self.handle(AMQ::Protocol::Exchange::DeleteOk) do |connection, frame|
|
769
901
|
channel = connection.channels[frame.channel]
|
@@ -789,7 +921,7 @@ module AMQP
|
|
789
921
|
|
790
922
|
# @private
|
791
923
|
def self.add_default_options(type, name, opts, block)
|
792
|
-
{ :exchange => name, :type => type, :nowait => block.nil
|
924
|
+
{ :exchange => name, :type => type, :nowait => block.nil?, :internal => false }.merge(opts)
|
793
925
|
end
|
794
926
|
end # Exchange
|
795
927
|
end # AMQP
|
data/lib/amqp/version.rb
CHANGED
@@ -472,6 +472,28 @@ describe AMQP::Channel do
|
|
472
472
|
end # it
|
473
473
|
end # context
|
474
474
|
|
475
|
+
context "when exchange is declared with or without :internal parameter" do
|
476
|
+
it "should create a public exchange by default" do
|
477
|
+
exchange = @channel.topic("a new public topic exchange")
|
478
|
+
|
479
|
+
exchange.should_not be_internal
|
480
|
+
done
|
481
|
+
end # it
|
482
|
+
|
483
|
+
it "should create a public exchange when :internal is false" do
|
484
|
+
exchange = @channel.topic("a new-public topic exchange", :internal => false)
|
485
|
+
|
486
|
+
exchange.should_not be_internal
|
487
|
+
done
|
488
|
+
end # it
|
489
|
+
|
490
|
+
it "should create an internal exchange when :internal is true" do
|
491
|
+
exchange = @channel.topic("a new internal topic exchange", :internal => true)
|
492
|
+
|
493
|
+
exchange.should be_internal
|
494
|
+
done
|
495
|
+
end # it
|
496
|
+
end # context
|
475
497
|
|
476
498
|
context "when exchange is re-declared with parameters different from the original declaration" do
|
477
499
|
amqp_after do
|
@@ -0,0 +1,124 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe AMQP::Channel do
|
6
|
+
|
7
|
+
#
|
8
|
+
# Environment
|
9
|
+
#
|
10
|
+
|
11
|
+
include EventedSpec::AMQPSpec
|
12
|
+
|
13
|
+
default_options AMQP_OPTS
|
14
|
+
default_timeout 2
|
15
|
+
|
16
|
+
|
17
|
+
amqp_before do
|
18
|
+
@channel = AMQP::Channel.new
|
19
|
+
end
|
20
|
+
|
21
|
+
#
|
22
|
+
# Examples
|
23
|
+
#
|
24
|
+
|
25
|
+
describe "exchange to exchange bindings" do
|
26
|
+
context "basic properties" do
|
27
|
+
it "bind returns self" do
|
28
|
+
source1 = @channel.fanout("fanout-exchange-source-1")
|
29
|
+
source2 = @channel.fanout("fanout-exchange-source-2")
|
30
|
+
destination = @channel.fanout("fanout-exchange-destination-multi")
|
31
|
+
destination.bind(source1).bind(source2).should == destination
|
32
|
+
done
|
33
|
+
end
|
34
|
+
|
35
|
+
it "bind can work with strings for source exchange parameter" do
|
36
|
+
@channel.fanout("fanout-exchange-source-3")
|
37
|
+
destination = @channel.fanout("fanout-exchange-destination-multi-2")
|
38
|
+
destination.bind('fanout-exchange-source-3').should == destination
|
39
|
+
done
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "fanout exchanges" do
|
44
|
+
it "are bindable and forward messages" do
|
45
|
+
source = @channel.fanout("fanout-exchange-source")
|
46
|
+
destination = @channel.fanout("fanout-exchange-destination")
|
47
|
+
messages = []
|
48
|
+
destination.bind(source) do
|
49
|
+
queue = @channel.queue("fanout-forwarding", :auto_delete => true)
|
50
|
+
queue.subscribe do |metadata, payload|
|
51
|
+
messages << payload
|
52
|
+
end
|
53
|
+
queue.bind(destination) do
|
54
|
+
source.publish("x")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
done(0.1) { messages.should == ["x"] }
|
58
|
+
end
|
59
|
+
|
60
|
+
it "can be unbound" do
|
61
|
+
source = @channel.fanout("fanout-exchange-source-2")
|
62
|
+
destination = @channel.fanout("fanout-exchange-destination-2")
|
63
|
+
destination.bind(source) do
|
64
|
+
destination.unbind(source) do
|
65
|
+
done
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
it "can be unbound without callbacks" do
|
71
|
+
source = @channel.fanout("fanout-exchange-source-2")
|
72
|
+
destination = @channel.fanout("fanout-exchange-destination-2")
|
73
|
+
destination.bind(source)
|
74
|
+
destination.unbind(source)
|
75
|
+
done
|
76
|
+
end
|
77
|
+
|
78
|
+
it "using :nowait => true should not call a passed in block" do
|
79
|
+
source = @channel.fanout("fanout-exchange-source-no-wait")
|
80
|
+
destination = @channel.fanout("fanout-exchange-destination-no-wait")
|
81
|
+
callback_called = false
|
82
|
+
destination.bind(source, :nowait => true) do
|
83
|
+
callback_called = true
|
84
|
+
end
|
85
|
+
done(0.1) { callback_called.should be_false}
|
86
|
+
end
|
87
|
+
|
88
|
+
end #context
|
89
|
+
|
90
|
+
context "topic exchanges" do
|
91
|
+
it "using routing key '#'" do
|
92
|
+
source = @channel.topic("topic-exchange-source")
|
93
|
+
destination = @channel.topic("topic-exchange-destination")
|
94
|
+
messages = []
|
95
|
+
destination.bind(source) do
|
96
|
+
queue = @channel.queue("ex-to-ex-default-key", :auto_delete => true)
|
97
|
+
queue.subscribe do |metadata, payload|
|
98
|
+
messages << payload
|
99
|
+
end
|
100
|
+
queue.bind(destination, :routing_key => "#") do
|
101
|
+
source.publish("a", :routing_key => "lalalala")
|
102
|
+
end
|
103
|
+
end
|
104
|
+
done(0.1) { messages.should == ["a"] }
|
105
|
+
end
|
106
|
+
|
107
|
+
it "using routing key 'foo'" do
|
108
|
+
source = @channel.topic("topic-exchange-source-foo")
|
109
|
+
destination = @channel.topic("topic-exchange-destination-foo")
|
110
|
+
messages = []
|
111
|
+
destination.bind(source, :routing_key => 'foo') do
|
112
|
+
queue = @channel.queue("foo-foo", :auto_delete => true)
|
113
|
+
queue.subscribe do |metadata, payload|
|
114
|
+
messages << payload
|
115
|
+
end
|
116
|
+
queue.bind(destination, :routing_key => "foo") do
|
117
|
+
source.publish("b", :routing_key => "foo")
|
118
|
+
end
|
119
|
+
end
|
120
|
+
done(0.1) { messages.should == ["b"]}
|
121
|
+
end
|
122
|
+
end #context
|
123
|
+
end # describe
|
124
|
+
end # describe AMQP
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: amqp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aman Gupta
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2014-
|
13
|
+
date: 2014-02-03 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: eventmachine
|
@@ -272,6 +272,7 @@ files:
|
|
272
272
|
- spec/integration/declare_one_hundred_server_named_queues_spec.rb
|
273
273
|
- spec/integration/direct_exchange_routing_spec.rb
|
274
274
|
- spec/integration/exchange_declaration_spec.rb
|
275
|
+
- spec/integration/exchange_to_exchange_binding_spec.rb
|
275
276
|
- spec/integration/extensions/rabbitmq/publisher_confirmations_spec.rb
|
276
277
|
- spec/integration/fanout_exchange_routing_spec.rb
|
277
278
|
- spec/integration/headers_exchange_routing_spec.rb
|