diff options
| -rw-r--r-- | src/rabbit_channel.erl | 2 | ||||
| -rw-r--r-- | src/rabbit_exchange.erl | 32 |
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}). |
