summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/rabbit_channel.erl2
-rw-r--r--src/rabbit_exchange.erl32
2 files changed, 31 insertions, 3 deletions
diff --git a/src/rabbit_channel.erl b/src/rabbit_channel.erl
index 71a6b117a2..84c34b0464 100644
--- a/src/rabbit_channel.erl
+++ b/src/rabbit_channel.erl
@@ -592,7 +592,7 @@ handle_method(#'exchange.declare'{exchange = ExchangeNameBin,
Durable,
Args)
end,
- ok = rabbit_exchange:assert_type(X, CheckedType),
+ ok = rabbit_exchange:assert_equivalence(X, CheckedType, Durable, Args),
return_ok(State, NoWait, #'exchange.declare_ok'{});
handle_method(#'exchange.declare'{exchange = ExchangeNameBin,
diff --git a/src/rabbit_exchange.erl b/src/rabbit_exchange.erl
index 899756e17a..68a0481142 100644
--- a/src/rabbit_exchange.erl
+++ b/src/rabbit_exchange.erl
@@ -39,7 +39,7 @@
-export([add_binding/5, delete_binding/5, list_bindings/1]).
-export([delete/2]).
-export([delete_queue_bindings/1, delete_transient_queue_bindings/1]).
--export([check_type/1, assert_type/2]).
+-export([check_type/1, assert_equivalence/4]).
%% EXTENDED API
-export([list_exchange_bindings/1]).
@@ -63,7 +63,7 @@
-spec(recover/0 :: () -> 'ok').
-spec(declare/4 :: (exchange_name(), exchange_type(), boolean(), amqp_table()) -> exchange()).
-spec(check_type/1 :: (binary()) -> atom()).
--spec(assert_type/2 :: (exchange(), atom()) -> 'ok').
+-spec(assert_equivalence/4 :: (exchange(), atom(), boolean(), amqp_table()) -> 'ok').
-spec(lookup/1 :: (exchange_name()) -> {'ok', exchange()} | not_found()).
-spec(lookup_or_die/1 :: (exchange_name()) -> exchange()).
-spec(list/1 :: (vhost()) -> [exchange()]).
@@ -160,6 +160,16 @@ check_type(T) ->
Module
end.
+assert_equivalence(X = #exchange{ durable = ActualDurable },
+ RequiredType, RequiredDurable, RequiredArgs)
+ when ActualDurable==RequiredDurable ->
+ ok = assert_type(X, RequiredType),
+ ok = assert_args_equivalence(X, RequiredArgs);
+assert_equivalence(#exchange{ name = Name }, _Type, _Durable, _Args) ->
+ rabbit_misc:protocol_error(
+ not_allowed, "cannot redeclare ~s with different durable value",
+ [rabbit_misc:rs(Name)]).
+
assert_type(#exchange{ type = ActualType }, RequiredType)
when ActualType == RequiredType ->
ok;
@@ -170,6 +180,24 @@ assert_type(#exchange{ name = Name, type = ActualType }, RequiredType) ->
plugin_module_to_typename(ActualType),
plugin_module_to_typename(RequiredType)]).
+alternate_exchange_value(Args) ->
+ lists:keysearch(<<"alternate-exchange">>, 1, Args).
+
+assert_args_equivalence(#exchange{ name = Name,
+ arguments = Args },
+ RequiredArgs) ->
+ %% The spec says "Arguments are compared for semantic
+ %% equivalence". The only arg we care about is
+ %% "alternate-exchange".
+ Ae1 = alternate_exchange_value(RequiredArgs),
+ Ae2 = alternate_exchange_value(Args),
+ if Ae1==Ae2 -> ok;
+ true -> rabbit_misc:protocol_error(
+ not_allowed,
+ "cannot redeclare ~s with inequivalent args",
+ [rabbit_misc:rs(Name)])
+ end.
+
lookup(Name) ->
rabbit_misc:dirty_read({rabbit_exchange, Name}).