Fix default queue type handling for single vhost imports
Default queue type logic didn't apply when import was done for a single vhost. Exported definitions for a single vhost don't contain `vhost` key, and anyway it's better to use the actual vhost name that will be used for queue declaration. And just in case, `vhost` is now stripped from all exported items for a single vhost (it was still present in `parameters` and `policies`) - on import it was ignored, but it could have been a source of the bug similar to the one with the default queue type.
This commit is contained in:
		
							parent
							
								
									31dffe78a7
								
							
						
					
					
						commit
						4bfe352168
					
				|  | @ -729,12 +729,11 @@ add_queue_int(_Queue, R = #resource{kind = queue, | |||
|     Name = R#resource.name, | ||||
|     rabbit_log:warning("Skipping import of a queue whose name begins with 'amq.', " | ||||
|                        "name: ~ts, acting user: ~ts", [Name, ActingUser]); | ||||
| add_queue_int(Queue, Name, ActingUser) -> | ||||
| add_queue_int(Queue, Name = #resource{virtual_host = VHostName}, ActingUser) -> | ||||
|     case rabbit_amqqueue:exists(Name) of | ||||
|         true -> | ||||
|             ok; | ||||
|         false -> | ||||
|             VHostName = maps:get(vhost, Queue, rabbit_vhost:default_name()), | ||||
|             AutoDelete = maps:get(auto_delete, Queue, false), | ||||
|             DurableDeclare = maps:get(durable, Queue, true), | ||||
|             ExclusiveDeclare = maps:get(exclusive, Queue, false), | ||||
|  |  | |||
|  | @ -99,14 +99,15 @@ vhost_definitions(ReqData, VHost, Context) -> | |||
|     Bs = [strip_vhost(B) || B <- rabbit_mgmt_wm_bindings:basic(ReqData), | ||||
|                             export_binding(B, QNames)], | ||||
|     {ok, Vsn} = application:get_key(rabbit, vsn), | ||||
|     Parameters = [rabbit_mgmt_format:parameter( | ||||
|                     rabbit_mgmt_wm_parameters:fix_shovel_publish_properties(P)) | ||||
|     Parameters = [strip_vhost( | ||||
|                     rabbit_mgmt_format:parameter( | ||||
|                       rabbit_mgmt_wm_parameters:fix_shovel_publish_properties(P))) | ||||
|                   || P <- rabbit_runtime_parameters:list(VHost)], | ||||
|     rabbit_mgmt_util:reply( | ||||
|       [{rabbit_version, rabbit_data_coercion:to_binary(Vsn)}] ++ | ||||
|           filter( | ||||
|             [{parameters,  Parameters}, | ||||
|              {policies,    rabbit_mgmt_wm_policies:basic(ReqData)}, | ||||
|              {policies,    [strip_vhost(P) || P <- rabbit_mgmt_wm_policies:basic(ReqData)]}, | ||||
|              {queues,      Qs}, | ||||
|              {exchanges,   Xs}, | ||||
|              {bindings,    Bs}]), | ||||
|  |  | |||
|  | @ -98,6 +98,7 @@ all_tests() -> [ | |||
|     definitions_remove_things_test, | ||||
|     definitions_server_named_queue_test, | ||||
|     definitions_with_charset_test, | ||||
|     definitions_default_queue_type_test, | ||||
|     long_definitions_test, | ||||
|     long_definitions_multipart_test, | ||||
|     aliveness_test, | ||||
|  | @ -1667,10 +1668,33 @@ long_definitions_vhosts(long_definitions_multipart_test) -> | |||
|     [#{name => <<"long_definitions_test-", Bin/binary, (integer_to_binary(N))/binary>>} || | ||||
|      N <- lists:seq(1, 16)]. | ||||
| 
 | ||||
| defs_default_queue_type_vhost(Config, QueueType) -> | ||||
|     register_parameters_and_policy_validator(Config), | ||||
| 
 | ||||
|     %% Create test vhost | ||||
|     http_put(Config, "/vhosts/test-vhost", #{defaultqueuetype => QueueType}, {group, '2xx'}), | ||||
|     PermArgs = [{configure, <<".*">>}, {write, <<".*">>}, {read, <<".*">>}], | ||||
|     http_put(Config, "/permissions/test-vhost/guest", PermArgs, {group, '2xx'}), | ||||
| 
 | ||||
|     %% Import queue definition without an explicit queue type | ||||
|     http_post(Config, "/definitions/test-vhost", | ||||
|               #{queues => [#{name => <<"test-queue">>, durable => true}]}, | ||||
|               {group, '2xx'}), | ||||
| 
 | ||||
|     %% And check whether it was indeed created with the default type | ||||
|     Q = http_get(Config, "/queues/test-vhost/test-queue", ?OK), | ||||
|     QueueType = maps:get(type, Q), | ||||
| 
 | ||||
|     %% Remove test vhost | ||||
|     http_delete(Config, "/vhosts/test-vhost", {group, '2xx'}), | ||||
|     ok. | ||||
| 
 | ||||
| definitions_default_queue_type_test(Config) -> | ||||
|     defs_default_queue_type_vhost(Config, <<"classic">>), | ||||
|     defs_default_queue_type_vhost(Config, <<"quorum">>). | ||||
| 
 | ||||
| defs_vhost(Config, Key, URI, CreateMethod, Args) -> | ||||
|     Rep1 = fun (S, S2) -> re:replace(S, "<vhost>", S2, [{return, list}]) end, | ||||
|     ReplaceVHostInArgs = fun(M, V2) -> maps:map(fun(vhost, _) -> V2; | ||||
|         (_, V1)    -> V1 end, M) end, | ||||
| 
 | ||||
|     %% Create test vhost | ||||
|     http_put(Config, "/vhosts/test", none, {group, '2xx'}), | ||||
|  | @ -1678,41 +1702,49 @@ defs_vhost(Config, Key, URI, CreateMethod, Args) -> | |||
|     http_put(Config, "/permissions/test/guest", PermArgs, {group, '2xx'}), | ||||
| 
 | ||||
|     %% Test against default vhost | ||||
|     defs_vhost(Config, Key, URI, Rep1, "%2F", "test", CreateMethod, | ||||
|                ReplaceVHostInArgs(Args, <<"/">>), ReplaceVHostInArgs(Args, <<"test">>), | ||||
|     defs_vhost(Config, Key, URI, Rep1, "%2F", "test", CreateMethod, Args, | ||||
|                fun(URI2) -> http_delete(Config, URI2, {group, '2xx'}) end), | ||||
| 
 | ||||
|     %% Test against test vhost | ||||
|     defs_vhost(Config, Key, URI, Rep1, "test", "%2F", CreateMethod, | ||||
|                ReplaceVHostInArgs(Args, <<"test">>), ReplaceVHostInArgs(Args, <<"/">>), | ||||
|     defs_vhost(Config, Key, URI, Rep1, "test", "%2F", CreateMethod, Args, | ||||
|                fun(URI2) -> http_delete(Config, URI2, {group, '2xx'}) end), | ||||
| 
 | ||||
|     %% Remove test vhost | ||||
|     http_delete(Config, "/vhosts/test", {group, '2xx'}). | ||||
| 
 | ||||
| 
 | ||||
| defs_vhost(Config, Key, URI0, Rep1, VHost1, VHost2, CreateMethod, Args1, Args2, | ||||
| defs_vhost(Config, Key, URI0, Rep1, VHost1, VHost2, CreateMethod, Args, | ||||
|            DeleteFun) -> | ||||
|     %% Create the item | ||||
|     URI2 = create(Config, CreateMethod, Rep1(URI0, VHost1), Args1), | ||||
|     URI2 = create(Config, CreateMethod, Rep1(URI0, VHost1), Args), | ||||
| 
 | ||||
|     %% Make sure it ends up in definitions | ||||
|     Definitions = http_get(Config, "/definitions/" ++ VHost1, ?OK), | ||||
|     true = lists:any(fun(I) -> test_item(Args1, I) end, maps:get(Key, Definitions)), | ||||
|     true = lists:any(fun(I) -> test_item(Args, I) end, maps:get(Key, Definitions)), | ||||
| 
 | ||||
|     %% `vhost` is implied when importing/exporting for a single | ||||
|     %% virtual host, let's make sure that it doesn't accidentally | ||||
|     %% appear in the exported definitions. This can (and did) cause a | ||||
|     %% confusion about which part of the request to use as the source | ||||
|     %% for the vhost name. | ||||
|     case [ I || #{vhost := _} = I <- maps:get(Key, Definitions)] of | ||||
|         [] -> ok; | ||||
|         WithVHost -> error({vhost_included_in, Key, WithVHost}) | ||||
|     end, | ||||
| 
 | ||||
|     %% Make sure it is not in the other vhost | ||||
|     Definitions0 = http_get(Config, "/definitions/" ++ VHost2, ?OK), | ||||
|     false = lists:any(fun(I) -> test_item(Args2, I) end, maps:get(Key, Definitions0)), | ||||
|     false = lists:any(fun(I) -> test_item(Args, I) end, maps:get(Key, Definitions0)), | ||||
| 
 | ||||
|     %% Post the definitions back | ||||
|     http_post(Config, "/definitions/" ++ VHost2, Definitions, {group, '2xx'}), | ||||
| 
 | ||||
|     %% Make sure it is now in the other vhost | ||||
|     Definitions1 = http_get(Config, "/definitions/" ++ VHost2, ?OK), | ||||
|     true = lists:any(fun(I) -> test_item(Args2, I) end, maps:get(Key, Definitions1)), | ||||
|     true = lists:any(fun(I) -> test_item(Args, I) end, maps:get(Key, Definitions1)), | ||||
| 
 | ||||
|     %% Delete it | ||||
|     DeleteFun(URI2), | ||||
|     URI3 = create(Config, CreateMethod, Rep1(URI0, VHost2), Args2), | ||||
|     URI3 = create(Config, CreateMethod, Rep1(URI0, VHost2), Args), | ||||
|     DeleteFun(URI3), | ||||
|     passed. | ||||
| 
 | ||||
|  | @ -1731,15 +1763,13 @@ definitions_vhost_test(Config) -> | |||
|     defs_vhost(Config, bindings, "/bindings/<vhost>/e/amq.direct/e/amq.fanout", post, | ||||
|                #{routing_key => <<"routing">>, arguments => #{}}), | ||||
|     defs_vhost(Config, policies, "/policies/<vhost>/my-policy", put, | ||||
|                #{vhost      => vhost, | ||||
|                  name       => <<"my-policy">>, | ||||
|                #{name       => <<"my-policy">>, | ||||
|                  pattern    => <<".*">>, | ||||
|                  definition => #{testpos => [1, 2, 3]}, | ||||
|                  priority   => 1}), | ||||
| 
 | ||||
|     defs_vhost(Config, parameters, "/parameters/vhost-limits/<vhost>/limits", put, | ||||
|                #{vhost      => vhost, | ||||
|                  name       => <<"limits">>, | ||||
|                #{name       => <<"limits">>, | ||||
|                  component  => <<"vhost-limits">>, | ||||
|                  value      => #{ 'max-connections' => 100 }}), | ||||
|     Upload = | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue