diff options
| -rw-r--r-- | src/rabbit_amqqueue.erl | 29 | ||||
| -rw-r--r-- | src/rabbit_amqqueue_process.erl | 2 | ||||
| -rw-r--r-- | src/rabbit_exchange.erl | 22 | ||||
| -rw-r--r-- | src/rabbit_misc.erl | 20 |
4 files changed, 37 insertions, 36 deletions
diff --git a/src/rabbit_amqqueue.erl b/src/rabbit_amqqueue.erl index 89a8002519..9a05406c80 100644 --- a/src/rabbit_amqqueue.erl +++ b/src/rabbit_amqqueue.erl @@ -83,8 +83,8 @@ -spec(with_or_die/2 :: (name(), qfun(A)) -> A). -spec(assert_equivalence/5 :: (rabbit_types:amqqueue(), boolean(), boolean(), - rabbit_framing:amqp_table(), rabbit_types:maybe(pid)) - -> ok). + rabbit_framing:amqp_table(), rabbit_types:maybe(pid())) + -> 'ok' | no_return()). -spec(check_exclusive_access/2 :: (rabbit_types:amqqueue(), pid()) -> 'ok'). -spec(with_exclusive_access_or_die/3 :: (name(), pid(), qfun(A)) -> A). -spec(list/1 :: (rabbit_types:vhost()) -> [rabbit_types:amqqueue()]). @@ -256,15 +256,13 @@ with(Name, F) -> with_or_die(Name, F) -> with(Name, F, fun () -> rabbit_misc:not_found(Name) end). -assert_equivalence(#amqqueue{name = Name, - durable = Durable, - auto_delete = AutoDelete, - arguments = Args1} = Q, - Durable, AutoDelete, Args, Owner) -> - check_argument_equivalent(Args1, Args, <<"x-expires">>, Name), +assert_equivalence(#amqqueue{durable = Durable, + auto_delete = AutoDelete} = Q, + Durable, AutoDelete, RequiredArgs, Owner) -> + assert_args_equivalence(Q, RequiredArgs), check_exclusive_access(Q, Owner, strict); assert_equivalence(#amqqueue{name = QueueName}, - _Durable, _AutoDelete, _Args, _Owner) -> + _Durable, _AutoDelete, _RequiredArgs, _Owner) -> rabbit_misc:protocol_error( not_allowed, "parameters for ~s not equivalent", [rabbit_misc:rs(QueueName)]). @@ -285,15 +283,10 @@ with_exclusive_access_or_die(Name, ReaderPid, F) -> with_or_die(Name, fun (Q) -> check_exclusive_access(Q, ReaderPid), F(Q) end). -check_argument_equivalent(Prev, Now, Key, QueueName) -> - case {rabbit_misc:table_lookup(Now, Key), - rabbit_misc:table_lookup(Prev, Key)} of - {Same, Same} -> ok; - {New, Old} -> rabbit_misc:protocol_error( - precondition_failed, - "arguments for ~s not equivalent: ~s=~w (was ~w)", - [rabbit_misc:rs(QueueName), Key, New, Old]) - end. +assert_args_equivalence(#amqqueue{name = QueueName, arguments = Args}, + RequiredArgs) -> + rabbit_misc:assert_args_equivalence(Args, RequiredArgs, QueueName, + [<<"x-expires">>]). list(VHostPath) -> mnesia:dirty_match_object( diff --git a/src/rabbit_amqqueue_process.erl b/src/rabbit_amqqueue_process.erl index de83ed7d7c..a9c827413f 100644 --- a/src/rabbit_amqqueue_process.erl +++ b/src/rabbit_amqqueue_process.erl @@ -135,7 +135,7 @@ init(Q) -> rate_timer_ref = undefined, expiry_timer_ref = undefined}, - case init_expires(State) of + case init_expires(State) of {error, Error} -> {stop, Error}; NewState -> {ok, NewState, hibernate, {backoff, ?HIBERNATE_AFTER_MIN, diff --git a/src/rabbit_exchange.erl b/src/rabbit_exchange.erl index d91ebe9ba9..9316934782 100644 --- a/src/rabbit_exchange.erl +++ b/src/rabbit_exchange.erl @@ -76,9 +76,9 @@ -spec(assert_equivalence/5 :: (rabbit_types:exchange(), atom(), boolean(), boolean(), rabbit_framing:amqp_table()) - -> 'ok'). + -> 'ok' | no_return()). -spec(assert_args_equivalence/2 :: - (rabbit_types:exchange(), rabbit_framing:amqp_table()) -> 'ok'). + (rabbit_types:exchange(), rabbit_framing:amqp_table()) -> 'ok' | no_return()). -spec(lookup/1 :: (name()) -> rabbit_types:ok(rabbit_types:exchange()) | rabbit_types:error('not_found')). @@ -218,9 +218,8 @@ check_type(TypeBin) -> assert_equivalence(X = #exchange{ durable = Durable, auto_delete = AutoDelete, type = Type}, - Type, Durable, AutoDelete, - RequiredArgs) -> - ok = (type_to_module(Type)):assert_args_equivalence(X, RequiredArgs); + Type, Durable, AutoDelete, RequiredArgs) -> + (type_to_module(Type)):assert_args_equivalence(X, RequiredArgs); assert_equivalence(#exchange{ name = Name }, _Type, _Durable, _AutoDelete, _Args) -> rabbit_misc:protocol_error( @@ -228,23 +227,14 @@ assert_equivalence(#exchange{ name = Name }, _Type, _Durable, _AutoDelete, "cannot redeclare ~s with different type, durable or autodelete value", [rabbit_misc:rs(Name)]). -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. + rabbit_misc:assert_args_equivalence(Args, RequiredArgs, Name, + [<<"alternate-exchange">>]). lookup(Name) -> rabbit_misc:dirty_read({rabbit_exchange, Name}). diff --git a/src/rabbit_misc.erl b/src/rabbit_misc.erl index 5d33c124e2..a211df378d 100644 --- a/src/rabbit_misc.erl +++ b/src/rabbit_misc.erl @@ -38,7 +38,7 @@ -export([method_record_type/1, polite_pause/0, polite_pause/1]). -export([die/1, frame_error/2, amqp_error/4, protocol_error/3, protocol_error/4, protocol_error/1]). --export([not_found/1]). +-export([not_found/1, assert_args_equivalence/4]). -export([get_config/1, get_config/2, set_config/2]). -export([dirty_read/1]). -export([table_lookup/2]). @@ -98,6 +98,10 @@ -> no_return()). -spec(protocol_error/1 :: (rabbit_types:amqp_error()) -> no_return()). -spec(not_found/1 :: (rabbit_types:r(atom())) -> no_return()). +-spec(assert_args_equivalence/4 :: (rabbit_framing:amqp_table(), + rabbit_framing:amqp_table(), + rabbit_types:r(any()), [binary()]) -> + 'ok' | no_return()). -spec(get_config/1 :: (atom()) -> rabbit_types:ok_or_error2(any(), 'not_found')). -spec(get_config/2 :: (atom(), A) -> A). @@ -211,6 +215,20 @@ protocol_error(#amqp_error{} = Error) -> not_found(R) -> protocol_error(not_found, "no ~s", [rs(R)]). +assert_args_equivalence(Orig, New, Name, Keys) -> + [assert_args_equivalence1(Orig, New, Name, Key) || Key <- Keys], + ok. + +assert_args_equivalence1(Orig, New, Name, Key) -> + case {table_lookup(Orig, Key), table_lookup(New, Key)} of + {Same, Same} -> ok; + {Orig1, New1} -> protocol_error( + not_allowed, + "cannot redeclare ~s with inequivalent args for ~s: " + "required ~w, received ~w", + [rabbit_misc:rs(Name), Key, New1, Orig1]) + end. + get_config(Key) -> case dirty_read({rabbit_config, Key}) of {ok, {rabbit_config, Key, V}} -> {ok, V}; |
