diff options
| author | kjnilsson <knilsson@pivotal.io> | 2019-02-14 16:53:43 +0000 |
|---|---|---|
| committer | kjnilsson <knilsson@pivotal.io> | 2019-02-14 16:53:43 +0000 |
| commit | 8e6701b310679eb1b05e4a80ab42e6e1b1af0768 (patch) | |
| tree | 0688db95032d419827f62997242276e28d03762b | |
| parent | b062641019a849f2c80118bf33c0882335cda431 (diff) | |
| download | rabbitmq-server-git-8e6701b310679eb1b05e4a80ab42e6e1b1af0768.tar.gz | |
Disallow removal of the last quorum member
Also change formatting.
[#162782789]
| -rw-r--r-- | src/rabbit_quorum_queue.erl | 43 | ||||
| -rw-r--r-- | test/quorum_queue_SUITE.erl | 11 |
2 files changed, 35 insertions, 19 deletions
diff --git a/src/rabbit_quorum_queue.erl b/src/rabbit_quorum_queue.erl index b9ca15467c..fd57608515 100644 --- a/src/rabbit_quorum_queue.erl +++ b/src/rabbit_quorum_queue.erl @@ -712,18 +712,27 @@ delete_member(Q, Node) when ?amqqueue_is_quorum(Q) -> QName = amqqueue:get_name(Q), {RaName, _} = amqqueue:get_pid(Q), ServerId = {RaName, Node}, - case ra:leave_and_delete_server(ServerId) of - ok -> - Fun = fun(Q1) -> - amqqueue:set_quorum_nodes( - Q1, - lists:delete(Node, amqqueue:get_quorum_nodes(Q1))) - end, - rabbit_misc:execute_mnesia_transaction( - fun() -> rabbit_amqqueue:update(QName, Fun) end), - ok; - E -> - E + case amqqueue:get_quorum_nodes(Q) of + [Node] -> + %% deleting the last member is not allowed + {error, last_node}; + _ -> + case ra:leave_and_delete_server(ServerId) of + ok -> + Fun = fun(Q1) -> + amqqueue:set_quorum_nodes( + Q1, + lists:delete(Node, + amqqueue:get_quorum_nodes(Q1))) + end, + rabbit_misc:execute_mnesia_transaction( + fun() -> rabbit_amqqueue:update(QName, Fun) end), + ok; + timeout -> + {error, timeout}; + E -> + E + end end. shrink_all(Node) -> @@ -733,11 +742,11 @@ shrink_all(Node) -> [rabbit_misc:rs(QName), Node]), case delete_member(Q, Node) of ok -> - {ok, QName}; - Err -> - rabbit_log:warning("~s: Failed to remove member ~w", - [rabbit_misc:rs(QName), Node]), - {error, QName, Err} + {QName, ok}; + {error, Err} -> + rabbit_log:warning("~s: Failed to remove member ~w, Error ~w", + [rabbit_misc:rs(QName), Node, Err]), + {QName, {error, Err}} end end || Q <- rabbit_amqqueue:list(), amqqueue:get_type(Q) == quorum, diff --git a/test/quorum_queue_SUITE.erl b/test/quorum_queue_SUITE.erl index 509d56ece4..430dfb229b 100644 --- a/test/quorum_queue_SUITE.erl +++ b/test/quorum_queue_SUITE.erl @@ -630,7 +630,7 @@ consume_in_minority(Config) -> ok. shrink_all(Config) -> - [Server0, _Server1, Server2] = + [Server0, Server1, Server2] = rabbit_ct_broker_helpers:get_node_configs(Config, nodename), Ch = rabbit_ct_client_helpers:open_channel(Config, Server0), @@ -643,7 +643,14 @@ shrink_all(Config) -> timer:sleep(500), Result = rpc:call(Server0, rabbit_quorum_queue, shrink_all, [Server2]), ct:pal("shring all result ~p", [Result]), - ?assertMatch([{ok, _}, {ok, _}], Result), + ?assertMatch([{_, ok}, {_, ok}], Result), + Result1 = rpc:call(Server0, rabbit_quorum_queue, shrink_all, [Server1]), + ct:pal("shring all result ~p", [Result1]), + ?assertMatch([{_, ok}, {_, ok}], Result1), + Result2 = rpc:call(Server0, rabbit_quorum_queue, shrink_all, [Server0]), + ct:pal("shring all result ~p", [Result2]), + ?assertMatch([{_, {error, last_node}}, + {_, {error, last_node}}], Result2), ok. |
