From 421b5a27bd36cdaa04159d5f7ceb9f8e3affb2fa Mon Sep 17 00:00:00 2001 From: Tom Pantelis Date: Tue, 12 Jan 2016 01:30:29 -0500 Subject: [PATCH] Disallow remove leader in single node We don't want to allow removal of the leader in a single node cluster, ie when there's no followers. Change-Id: I3bedd1727736c7dfec55ba696f5ef1197a68c89d Signed-off-by: Tom Pantelis --- .../raft/RaftActorServerConfigurationSupport.java | 5 ++++- .../cluster/raft/messages/ServerChangeStatus.java | 2 +- .../RaftActorServerConfigurationSupportTest.java | 12 ++++++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActorServerConfigurationSupport.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActorServerConfigurationSupport.java index 3db0316dd1..95269f6b32 100644 --- a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActorServerConfigurationSupport.java +++ b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActorServerConfigurationSupport.java @@ -78,7 +78,10 @@ class RaftActorServerConfigurationSupport { private void onRemoveServer(RemoveServer removeServer, ActorRef sender) { LOG.debug("{}: onRemoveServer: {}, state: {}", raftContext.getId(), removeServer, currentOperationState); boolean isSelf = removeServer.getServerId().equals(raftActor.getId()); - if(!isSelf && !raftContext.getPeerIds().contains(removeServer.getServerId())) { + if(isSelf && !raftContext.hasFollowers()) { + sender.tell(new RemoveServerReply(ServerChangeStatus.NOT_SUPPORTED, raftActor.getLeaderId()), + raftActor.getSelf()); + } else if(!isSelf && !raftContext.getPeerIds().contains(removeServer.getServerId())) { sender.tell(new RemoveServerReply(ServerChangeStatus.DOES_NOT_EXIST, raftActor.getLeaderId()), raftActor.getSelf()); } else { diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/ServerChangeStatus.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/ServerChangeStatus.java index 7616fe6743..8f6a370a92 100644 --- a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/ServerChangeStatus.java +++ b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/ServerChangeStatus.java @@ -45,7 +45,7 @@ public enum ServerChangeStatus { PRIOR_REQUEST_CONSENSUS_TIMEOUT, /** - * An unsupported request, for example removing the current leader may not be supported (at least initially) + * An unsupported request, for example removing the leader in a single node cluster. */ NOT_SUPPORTED, } diff --git a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/RaftActorServerConfigurationSupportTest.java b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/RaftActorServerConfigurationSupportTest.java index 3420c4f083..0025a6d1cc 100644 --- a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/RaftActorServerConfigurationSupportTest.java +++ b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/RaftActorServerConfigurationSupportTest.java @@ -821,6 +821,18 @@ public class RaftActorServerConfigurationSupportTest extends AbstractActorTest { MessageCollectorActor.expectFirstMatching(leaderCollector, ServerRemoved.class); } + @Test + public void testRemoveServerLeaderWithNoFollowers() { + TestActorRef leaderActor = actorFactory.createTestActor( + MockLeaderRaftActor.props(Collections.emptyMap(), + new MockRaftActorContext()).withDispatcher(Dispatchers.DefaultDispatcherId()), + actorFactory.generateActorId(LEADER_ID)); + + leaderActor.tell(new RemoveServer(LEADER_ID), testKit.getRef()); + RemoveServerReply removeServerReply = testKit.expectMsgClass(JavaTestKit.duration("5 seconds"), RemoveServerReply.class); + assertEquals("getStatus", ServerChangeStatus.NOT_SUPPORTED, removeServerReply.getStatus()); + } + private ServerInfo votingServer(String id) { return new ServerInfo(id, true); } -- 2.36.6