rabbit_vhost:set_tags/2 avoids notifying if tags are unchanged
Additionally, tags are now always sorted when set
This commit is contained in:
		
							parent
							
								
									d07e4790ec
								
							
						
					
					
						commit
						12ec3a55ff
					
				|  | @ -1043,6 +1043,9 @@ rabbitmq_integration_suite( | ||||||
|     name = "vhost_SUITE", |     name = "vhost_SUITE", | ||||||
|     size = "medium", |     size = "medium", | ||||||
|     flaky = True, |     flaky = True, | ||||||
|  |     additional_srcs = [ | ||||||
|  |         "test/test_rabbit_event_handler.erl", | ||||||
|  |     ], | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| rabbitmq_suite( | rabbitmq_suite( | ||||||
|  |  | ||||||
|  | @ -132,7 +132,7 @@ merge_metadata_in_mnesia_tx(VHostName, Metadata) -> | ||||||
| 
 | 
 | ||||||
| set_tags(VHostName, Tags) | set_tags(VHostName, Tags) | ||||||
|   when is_binary(VHostName) andalso is_list(Tags) -> |   when is_binary(VHostName) andalso is_list(Tags) -> | ||||||
|     ConvertedTags = [rabbit_data_coercion:to_atom(Tag) || Tag <- Tags], |     ConvertedTags = lists:usort([rabbit_data_coercion:to_atom(Tag) || Tag <- Tags]), | ||||||
|     rabbit_db:run( |     rabbit_db:run( | ||||||
|       #{mnesia => fun() -> set_tags_in_mnesia(VHostName, ConvertedTags) end}). |       #{mnesia => fun() -> set_tags_in_mnesia(VHostName, ConvertedTags) end}). | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -518,15 +518,36 @@ assert(VHostName) -> | ||||||
|         false -> throw({error, {no_such_vhost, VHostName}}) |         false -> throw({error, {no_such_vhost, VHostName}}) | ||||||
|     end. |     end. | ||||||
| 
 | 
 | ||||||
|  | are_different0([], []) -> | ||||||
|  |     false; | ||||||
|  | are_different0([], [_ | _]) -> | ||||||
|  |     true; | ||||||
|  | are_different0([_ | _], []) -> | ||||||
|  |     true; | ||||||
|  | are_different0([E], [E]) -> | ||||||
|  |     false; | ||||||
|  | are_different0([E | R1], [E | R2]) -> | ||||||
|  |     are_different0(R1, R2); | ||||||
|  | are_different0(_, _) -> | ||||||
|  |     true. | ||||||
|  | 
 | ||||||
|  | are_different(L1, L2) -> | ||||||
|  |     are_different0(lists:usort(L1), lists:usort(L2)). | ||||||
|  | 
 | ||||||
| -spec update_tags(vhost:name(), [vhost_tag()], rabbit_types:username()) -> vhost:vhost(). | -spec update_tags(vhost:name(), [vhost_tag()], rabbit_types:username()) -> vhost:vhost(). | ||||||
| update_tags(VHostName, Tags, ActingUser) -> | update_tags(VHostName, Tags, ActingUser) -> | ||||||
|     try |     try | ||||||
|  |         CurrentTags = case rabbit_db_vhost:get(VHostName) of | ||||||
|  |                           undefined -> []; | ||||||
|  |                           V -> vhost:get_tags(V) | ||||||
|  |                       end, | ||||||
|         VHost = rabbit_db_vhost:set_tags(VHostName, Tags), |         VHost = rabbit_db_vhost:set_tags(VHostName, Tags), | ||||||
|         ConvertedTags = vhost:get_tags(VHost), |         ConvertedTags = vhost:get_tags(VHost), | ||||||
|         rabbit_log:info("Successfully set tags for virtual host '~ts' to ~tp", [VHostName, ConvertedTags]), |         rabbit_log:info("Successfully set tags for virtual host '~ts' to ~tp", [VHostName, ConvertedTags]), | ||||||
|         rabbit_event:notify(vhost_tags_set, [{name, VHostName}, |         rabbit_event:notify_if(are_different(CurrentTags, ConvertedTags), | ||||||
|                                              {tags, ConvertedTags}, |                                vhost_tags_set, [{name, VHostName}, | ||||||
|                                              {user_who_performed_action, ActingUser}]), |                                                 {tags, ConvertedTags}, | ||||||
|  |                                                 {user_who_performed_action, ActingUser}]), | ||||||
|         VHost |         VHost | ||||||
|     catch |     catch | ||||||
|         throw:{error, {no_such_vhost, _}} = Error -> |         throw:{error, {no_such_vhost, _}} = Error -> | ||||||
|  |  | ||||||
|  | @ -0,0 +1,33 @@ | ||||||
|  | -module(test_rabbit_event_handler). | ||||||
|  | 
 | ||||||
|  | -behaviour(gen_event). | ||||||
|  | 
 | ||||||
|  | -export([okay/0]). | ||||||
|  | -export([init/1, handle_call/2, handle_event/2, handle_info/2, | ||||||
|  |     terminate/2, code_change/3]). | ||||||
|  | 
 | ||||||
|  | -include_lib("rabbit_common/include/rabbit.hrl"). | ||||||
|  | 
 | ||||||
|  | % an exported callable func, used to allow rabbit_ct_broker_helpers | ||||||
|  | % to load this code when rpc'd | ||||||
|  | okay() -> ok. | ||||||
|  | 
 | ||||||
|  | init([]) -> | ||||||
|  |     {ok, #{events => []}}. | ||||||
|  | 
 | ||||||
|  | handle_event(#event{} = Event, #{events := Events} = State) -> | ||||||
|  |     {ok, State#{events => [Event | Events]}}; | ||||||
|  | handle_event(_, State) -> | ||||||
|  |     {ok, State}. | ||||||
|  | 
 | ||||||
|  | handle_call(events,  #{events := Events} = State) -> | ||||||
|  |     {ok, Events, State}. | ||||||
|  | 
 | ||||||
|  | handle_info(_Info, State) -> | ||||||
|  |     {ok, State}. | ||||||
|  | 
 | ||||||
|  | terminate(_Arg, _State) -> | ||||||
|  |     ok. | ||||||
|  | 
 | ||||||
|  | code_change(_OldVsn, State, _Extra) -> | ||||||
|  |     {ok, State}. | ||||||
|  | @ -28,6 +28,7 @@ groups() -> | ||||||
|         single_node_vhost_deletion_forces_connection_closure, |         single_node_vhost_deletion_forces_connection_closure, | ||||||
|         vhost_failure_forces_connection_closure, |         vhost_failure_forces_connection_closure, | ||||||
|         vhost_creation_idempotency, |         vhost_creation_idempotency, | ||||||
|  |         vhost_update_idempotency, | ||||||
|         parse_tags |         parse_tags | ||||||
|     ], |     ], | ||||||
|     ClusterSize2Tests = [ |     ClusterSize2Tests = [ | ||||||
|  | @ -321,6 +322,42 @@ vhost_creation_idempotency(Config) -> | ||||||
|         rabbit_ct_broker_helpers:delete_vhost(Config, VHost) |         rabbit_ct_broker_helpers:delete_vhost(Config, VHost) | ||||||
|     end. |     end. | ||||||
| 
 | 
 | ||||||
|  | vhost_update_idempotency(Config) -> | ||||||
|  |     VHost = <<"update-idempotency-test">>, | ||||||
|  |     ActingUser = <<"acting-user">>, | ||||||
|  |     try | ||||||
|  |         % load the dummy event handler on the node | ||||||
|  |         ok = rabbit_ct_broker_helpers:rpc(Config, 0, test_rabbit_event_handler, okay, []), | ||||||
|  | 
 | ||||||
|  |         ok = rabbit_ct_broker_helpers:rpc(Config, 0, gen_event, add_handler, | ||||||
|  |                                           [rabbit_event, test_rabbit_event_handler, []]), | ||||||
|  | 
 | ||||||
|  |         ?assertEqual(ok, rabbit_ct_broker_helpers:add_vhost(Config, VHost)), | ||||||
|  | 
 | ||||||
|  |         ?assertMatch({vhost,VHost, [], #{tags := [private,replicate]}}, | ||||||
|  |                      rabbit_ct_broker_helpers:rpc(Config, 0, | ||||||
|  |                                                   rabbit_vhost, update_tags, | ||||||
|  |                                                   [VHost, [private, replicate], ActingUser])), | ||||||
|  |         ?assertMatch({vhost,VHost, [], #{tags := [private,replicate]}}, | ||||||
|  |                      rabbit_ct_broker_helpers:rpc(Config, 0, | ||||||
|  |                                                   rabbit_vhost, update_tags, | ||||||
|  |                                                   [VHost, [replicate, private], ActingUser])), | ||||||
|  | 
 | ||||||
|  |         Events = rabbit_ct_broker_helpers:rpc(Config, 0, | ||||||
|  |                                               gen_event, call, | ||||||
|  |                                               [rabbit_event, test_rabbit_event_handler, events, 100]), | ||||||
|  |         ct:pal(?LOW_IMPORTANCE, "Events: ~p", [lists:reverse(Events)]), | ||||||
|  |         TagsSetEvents = lists:filter(fun | ||||||
|  |                                          (#event{type = vhost_tags_set}) -> true; | ||||||
|  |                                          (_) -> false | ||||||
|  |                                      end, Events), | ||||||
|  |         ?assertMatch([#event{}], TagsSetEvents) | ||||||
|  |     after | ||||||
|  |         rabbit_ct_broker_helpers:rpc(Config, 0, | ||||||
|  |                                      gen_event, delete_handler, [rabbit_event, test_rabbit_event_handler, []]), | ||||||
|  |         rabbit_ct_broker_helpers:delete_vhost(Config, VHost) | ||||||
|  |     end. | ||||||
|  | 
 | ||||||
| vhost_is_created_with_default_limits(Config) -> | vhost_is_created_with_default_limits(Config) -> | ||||||
|     VHost = <<"vhost1">>, |     VHost = <<"vhost1">>, | ||||||
|     Limits = [{<<"max-connections">>, 10}, {<<"max-queues">>, 1}], |     Limits = [{<<"max-connections">>, 10}, {<<"max-queues">>, 1}], | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue