From df745e2544824b882d174b99d1d4470d05ac78c8 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Wed, 20 Jul 2016 18:04:59 +0300 Subject: [PATCH] Force close connections when vhost is deleted Fixes #627, related to #500. --- src/rabbit_connection_tracking_handler.erl | 12 ++++--- test/per_vhost_connection_limit_SUITE.erl | 37 ++++++++++++++++++++-- 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/src/rabbit_connection_tracking_handler.erl b/src/rabbit_connection_tracking_handler.erl index 70195d5fb8b2..deaf9bc7f666 100644 --- a/src/rabbit_connection_tracking_handler.erl +++ b/src/rabbit_connection_tracking_handler.erl @@ -72,10 +72,14 @@ handle_event(#event{type = connection_closed, props = Details}, State) -> proplists:get_value(name, Details)}), {ok, State}; handle_event(#event{type = vhost_deleted, props = Details}, State) -> - _VHost = proplists:get_value(name, Details), - %% TODO: force close and unregister connections in - %% this vhost. Moved to rabbitmq/rabbitmq-server#627. - {ok, State}; + VHost = proplists:get_value(name, Details), + rabbit_log_connection:info("Closing all connections in vhost '~s' because it's being deleted", [VHost]), + case rabbit_connection_tracking:list(VHost) of + [] -> {ok, State}; + Cs -> + [rabbit_networking:close_connection(Pid, rabbit_misc:format("vhost '~s' is deleted", [VHost])) || #tracked_connection{pid = Pid} <- Cs], + {ok, State} + end; handle_event(#event{type = user_deleted, props = Details}, State) -> _Username = proplists:get_value(name, Details), %% TODO: force close and unregister connections from diff --git a/test/per_vhost_connection_limit_SUITE.erl b/test/per_vhost_connection_limit_SUITE.erl index 32b3be3a1622..c29acfea92f8 100644 --- a/test/per_vhost_connection_limit_SUITE.erl +++ b/test/per_vhost_connection_limit_SUITE.erl @@ -41,7 +41,8 @@ groups() -> single_node_list_in_vhost_test, single_node_connection_reregistration_idempotency_test, single_node_single_vhost_limit_test, - single_node_multiple_vhost_limit_test + single_node_multiple_vhost_limit_test, + single_node_vhost_deletion_forces_connection_closure_test ]}, {cluster_size_2, [], [ most_basic_cluster_connection_count_test, @@ -498,7 +499,7 @@ single_node_single_vhost_limit_test(Config) -> end, [Conn1, Conn2, Conn3, Conn4, Conn5]), ?assertEqual(0, count_connections_in(Config, VHost)), - set_vhost_connection_limit(Config, VHost, 100000000), + set_vhost_connection_limit(Config, VHost, 0), passed. @@ -577,7 +578,37 @@ cluster_single_vhost_limit_test(Config) -> ?assertEqual(0, count_connections_in(Config, VHost)), - set_vhost_connection_limit(Config, VHost, 100000000), + set_vhost_connection_limit(Config, VHost, 0), + + passed. + +single_node_vhost_deletion_forces_connection_closure_test(Config) -> + VHost1 = <<"vhost1">>, + VHost2 = <<"vhost2">>, + + rabbit_ct_broker_helpers:add_vhost(Config, VHost1), + rabbit_ct_broker_helpers:set_full_permissions(Config, <<"guest">>, VHost1), + + rabbit_ct_broker_helpers:add_vhost(Config, VHost2), + rabbit_ct_broker_helpers:set_full_permissions(Config, <<"guest">>, VHost2), + + ?assertEqual(0, count_connections_in(Config, VHost1)), + ?assertEqual(0, count_connections_in(Config, VHost2)), + + Conn1 = open_unmanaged_connection(Config, 0, VHost1), + ?assertEqual(1, count_connections_in(Config, VHost1)), + + _Conn2 = open_unmanaged_connection(Config, 0, VHost2), + ?assertEqual(1, count_connections_in(Config, VHost2)), + + rabbit_ct_broker_helpers:delete_vhost(Config, VHost2), + timer:sleep(200), + ?assertEqual(0, count_connections_in(Config, VHost2)), + + rabbit_ct_client_helpers:close_connection(Conn1), + ?assertEqual(0, count_connections_in(Config, VHost1)), + + rabbit_ct_broker_helpers:delete_vhost(Config, VHost1), passed.