See #8076. Skip arg and type check on re-declare of QQ if declare type is classic.

This commit is contained in:
Simon Unge 2023-05-01 13:41:45 -07:00
parent 46eee71110
commit d32c19e86f
3 changed files with 85 additions and 2 deletions

View File

@ -2483,6 +2483,8 @@ end}.
{mapping, "quorum_queue.compute_checksums", "rabbit.quorum_compute_checksums", [
{datatype, {enum, [true, false]}}]}.
{mapping, "quorum_queue.property_equivalence.relaxed_checks_on_redeclaration", "rabbit.quorum_relaxed_checks_on_redeclaration", [
{datatype, {enum, [true, false]}}]}.
%%
%% Runtime parameters

View File

@ -652,13 +652,54 @@ priv_absent(QueueName, QPid, _IsDurable, alive) ->
'ok' | rabbit_types:channel_exit() | rabbit_types:connection_exit().
assert_equivalence(Q, DurableDeclare, AutoDeleteDeclare, Args1, Owner) ->
case equivalence_check_level(Q, Args1) of
full_check ->
perform_full_equivalence_checks(Q, DurableDeclare, AutoDeleteDeclare,
Args1, Owner);
limited_check_on_qq_redeclaration ->
perform_limited_equivalence_checks_on_qq_redeclaration(Q, Args1)
end.
equivalence_check_level(Q, NewArgs) ->
Relaxed = rabbit_misc:get_env(rabbit,
quorum_relaxed_checks_on_redeclaration,
false),
case Relaxed of
true ->
ExistingArgs = amqqueue:get_arguments(Q),
OldType = rabbit_misc:table_lookup(ExistingArgs, <<"x-queue-type">>),
NewType = rabbit_misc:table_lookup(NewArgs, <<"x-queue-type">>),
case {OldType, NewType} of
{{longstr, <<"quorum">>}, {longstr, <<"classic">>}} ->
limited_check_on_qq_redeclaration;
_ ->
full_check
end;
false ->
full_check
end.
perform_full_equivalence_checks(Q, DurableDeclare, AutoDeleteDeclare, NewArgs, Owner) ->
QName = amqqueue:get_name(Q),
DurableQ = amqqueue:is_durable(Q),
AutoDeleteQ = amqqueue:is_auto_delete(Q),
ok = check_exclusive_access(Q, Owner, strict),
ok = rabbit_misc:assert_field_equivalence(DurableQ, DurableDeclare, QName, durable),
ok = rabbit_misc:assert_field_equivalence(AutoDeleteQ, AutoDeleteDeclare, QName, auto_delete),
ok = assert_args_equivalence(Q, Args1).
ok = assert_args_equivalence(Q, NewArgs).
perform_limited_equivalence_checks_on_qq_redeclaration(Q, NewArgs) ->
QName = amqqueue:get_name(Q),
ExistingArgs = amqqueue:get_arguments(Q),
CheckTypeArgs = [<<"x-dead-letter-exchange">>,
<<"x-dead-letter-routing-key">>,
<<"x-expires">>,
<<"x-max-length">>,
<<"x-max-length-bytes">>,
<<"x-single-active-consumer">>,
<<"x-message-ttl">>],
ok = rabbit_misc:assert_args_equivalence(ExistingArgs, NewArgs, QName, CheckTypeArgs).
-spec augment_declare_args(vhost:name(), boolean(),
boolean(), boolean(),

View File

@ -107,6 +107,7 @@ all_tests() ->
declare_invalid_arg_1,
declare_invalid_arg_2,
declare_invalid_arg_3,
redeclare_qq_as_classic,
consume_invalid_arg_1,
consume_invalid_arg_2,
start_queue,
@ -416,6 +417,45 @@ declare_invalid_arg_3(Config) ->
declare(Ch, Q, [{<<"x-queue-type">>, longstr, <<"quorum">>},
{<<"x-max-length">>, long, -5}])).
redeclare_qq_as_classic(Config) ->
ok = rabbit_ct_broker_helpers:rpc(Config, 0, application, set_env,
[rabbit, quorum_relaxed_checks_on_redeclaration, true]),
Node = rabbit_ct_broker_helpers:get_node_config(Config, 0, nodename),
VHost = <<"redeclarevhost">>,
User = ?config(rmq_username, Config),
ok = rabbit_ct_broker_helpers:add_vhost(Config, Node, VHost, User),
ok = rabbit_ct_broker_helpers:set_full_permissions(Config, User, VHost),
Conn = rabbit_ct_client_helpers:open_unmanaged_connection(Config, Node, VHost),
{ok, Ch} = amqp_connection:open_channel(Conn),
Q = atom_to_binary(?FUNCTION_NAME, utf8),
%% Declare a quorum queue
?assertEqual({'queue.declare_ok', Q, 0, 0},
declare(Ch, Q, [{<<"x-queue-type">>, longstr, <<"quorum">>},
{<<"x-expires">>, long, 1000}])),
%% re-declare it as 'classic' queue, which now is OK.
?assertEqual({'queue.declare_ok', Q, 0, 0},
declare(Ch, Q, [{<<"x-queue-type">>, longstr, <<"classic">>},
{<<"x-expires">>, long, 1000}])),
%% re-declare it as 'classic' queue, with classic only arguments ignored, so OK.
?assertEqual({'queue.declare_ok', Q, 0, 0},
declare(Ch, Q, [{<<"x-queue-type">>, longstr, <<"classic">>},
{<<"x-max-priority">>, byte, 5},
{<<"x-expires">>, long, 1000}])),
%% re-declare it as 'classic' queue, with shared arguments not part of original queue not OK,
?assertExit(
{{shutdown, {server_initiated_close, 406, _}}, _},
declare(Ch, Q, [{<<"x-queue-type">>, longstr, <<"classic">>},
{<<"x-message-ttl">>, long, 5},
{<<"x-expires">>, long, 1000}])),
ok = rabbit_ct_broker_helpers:delete_vhost(Config, VHost),
ok = rabbit_ct_broker_helpers:rpc(Config, 0, application, set_env,
[rabbit, quorum_relaxed_checks_on_redeclaration, false]),
ok.
consume_invalid_arg_1(Config) ->
Server = rabbit_ct_broker_helpers:get_node_config(Config, 0, nodename),
Ch = rabbit_ct_client_helpers:open_channel(Config, Server),