Search in sources :

Example 1 with RequestVoteReply

use of org.opendaylight.controller.cluster.raft.messages.RequestVoteReply in project controller by opendaylight.

the class DummyShard method onReceive.

@Override
public void onReceive(Object message) throws Exception {
    if (message instanceof RequestVote) {
        RequestVote req = (RequestVote) message;
        sender().tell(new RequestVoteReply(req.getTerm(), true), self());
    } else if (message instanceof AppendEntries) {
        handleAppendEntries((AppendEntries) message);
    } else if (message instanceof InstallSnapshot) {
        handleInstallSnapshot((InstallSnapshot) message);
    } else {
        LOG.error("Unknown message : {}", message.getClass());
    }
}
Also used : RequestVoteReply(org.opendaylight.controller.cluster.raft.messages.RequestVoteReply) AppendEntries(org.opendaylight.controller.cluster.raft.messages.AppendEntries) RequestVote(org.opendaylight.controller.cluster.raft.messages.RequestVote) InstallSnapshot(org.opendaylight.controller.cluster.raft.messages.InstallSnapshot)

Example 2 with RequestVoteReply

use of org.opendaylight.controller.cluster.raft.messages.RequestVoteReply in project controller by opendaylight.

the class PartitionedCandidateOnStartupElectionScenarioTest method sendElectionTimeoutToFollowerMember1.

private void sendElectionTimeoutToFollowerMember1() {
    testLog.info("sendElectionTimeoutToFollowerMember1 starting");
    // At this point we have no leader. Candidate member 3 would continue to start new elections
    // but wouldn't be granted a vote. One of the 2 followers would eventually time out from
    // not having received a heartbeat from a leader and switch to candidate and start a new
    // election. We'll simulate that here by sending an ElectionTimeout to member 1.
    member1Actor.clear();
    member1Actor.expectMessageClass(RequestVoteReply.class, 1);
    member2Actor.clear();
    member2Actor.expectMessageClass(RequestVote.class, 1);
    member3Actor.clear();
    member3Actor.expectMessageClass(RequestVote.class, 1);
    member3Actor.expectBehaviorStateChange();
    member1ActorRef.tell(TimeoutNow.INSTANCE, ActorRef.noSender());
    member2Actor.waitForExpectedMessages(RequestVote.class);
    member3Actor.waitForExpectedMessages(RequestVote.class);
    // The RequestVoteReply should come from Follower member 2 and the vote should be granted
    // since member 2's last term and index matches member 1's.
    member1Actor.waitForExpectedMessages(RequestVoteReply.class);
    RequestVoteReply requestVoteReply = member1Actor.getCapturedMessage(RequestVoteReply.class);
    assertEquals("getTerm", member1Context.getTermInformation().getCurrentTerm(), requestVoteReply.getTerm());
    assertEquals("isVoteGranted", true, requestVoteReply.isVoteGranted());
    // Candidate member 3 should change to follower as its term should be less than the
    // RequestVote term (member 1 started a new term higher than the other member's terms).
    member3Actor.waitForBehaviorStateChange();
    verifyBehaviorState("member 1", member1Actor, RaftState.Leader);
    verifyBehaviorState("member 2", member2Actor, RaftState.Follower);
    verifyBehaviorState("member 3", member3Actor, RaftState.Follower);
    // newTerm should be 10.
    long newTerm = candidateElectionTerm + 1;
    assertEquals("member 1 election term", newTerm, member1Context.getTermInformation().getCurrentTerm());
    assertEquals("member 2 election term", newTerm, member2Context.getTermInformation().getCurrentTerm());
    assertEquals("member 3 election term", newTerm, member3Context.getTermInformation().getCurrentTerm());
    testLog.info("sendElectionTimeoutToFollowerMember1 ending");
}
Also used : RequestVoteReply(org.opendaylight.controller.cluster.raft.messages.RequestVoteReply)

Example 3 with RequestVoteReply

use of org.opendaylight.controller.cluster.raft.messages.RequestVoteReply in project controller by opendaylight.

the class PartitionedLeadersElectionScenarioTest method sendInitialElectionTimeoutToFollowerMember3.

private void sendInitialElectionTimeoutToFollowerMember3() {
    testLog.info("sendInitialElectionTimeoutToFollowerMember3 starting");
    // Send ElectionTimeout to member 3 to simulate no heartbeat from a Leader (originally member 1).
    // member 3 should switch to Candidate and send out RequestVote messages. member 1, now a follower,
    // should reply and grant the vote but member 2 will drop the message to simulate loss of network
    // connectivity between members 2 and 3. member 3 should switch to leader.
    member1Actor.clear();
    member1Actor.expectMessageClass(RequestVote.class, 1);
    member1Actor.expectMessageClass(AppendEntries.class, 1);
    member2Actor.clear();
    member2Actor.dropMessagesToBehavior(RequestVote.class);
    member2Actor.dropMessagesToBehavior(AppendEntries.class);
    member3Actor.clear();
    member3Actor.expectMessageClass(RequestVoteReply.class, 1);
    member3Actor.expectMessageClass(AppendEntriesReply.class, 1);
    member3ActorRef.tell(TimeoutNow.INSTANCE, ActorRef.noSender());
    member1Actor.waitForExpectedMessages(RequestVote.class);
    member2Actor.waitForExpectedMessages(RequestVote.class);
    member3Actor.waitForExpectedMessages(RequestVoteReply.class);
    RequestVoteReply requestVoteReply = member3Actor.getCapturedMessage(RequestVoteReply.class);
    assertEquals("getTerm", member3Context.getTermInformation().getCurrentTerm(), requestVoteReply.getTerm());
    assertEquals("isVoteGranted", true, requestVoteReply.isVoteGranted());
    // when member 3 switches to Leader it will immediately send out heartbeat AppendEntries to
    // the followers. Wait for AppendEntries to member 1 and its AppendEntriesReply. The
    // AppendEntries message to member 2 is dropped.
    member1Actor.waitForExpectedMessages(AppendEntries.class);
    member2Actor.waitForExpectedMessages(AppendEntries.class);
    member3Actor.waitForExpectedMessages(AppendEntriesReply.class);
    verifyBehaviorState("member 1", member1Actor, RaftState.Follower);
    verifyBehaviorState("member 2", member2Actor, RaftState.Candidate);
    verifyBehaviorState("member 3", member3Actor, RaftState.Leader);
    assertEquals("member 1 election term", 2, member1Context.getTermInformation().getCurrentTerm());
    assertEquals("member 2 election term", 2, member2Context.getTermInformation().getCurrentTerm());
    assertEquals("member 3 election term", 2, member3Context.getTermInformation().getCurrentTerm());
    testLog.info("sendInitialElectionTimeoutToFollowerMember3 ending");
}
Also used : RequestVoteReply(org.opendaylight.controller.cluster.raft.messages.RequestVoteReply)

Example 4 with RequestVoteReply

use of org.opendaylight.controller.cluster.raft.messages.RequestVoteReply in project controller by opendaylight.

the class PartitionedLeadersElectionScenarioTest method sendElectionTimeoutToNowCandidateMember2.

private void sendElectionTimeoutToNowCandidateMember2() {
    testLog.info("sendElectionTimeoutToNowCandidateMember2 starting");
    // member 2, now a candidate, is partitioned from the Leader (now member 3) and hasn't received any
    // messages. It would get another ElectionTimeout so simulate that. member 1 should send back a reply
    // granting the vote. Messages (RequestVote and AppendEntries) from member 2 to member 3
    // are dropped to simulate loss of network connectivity. Note member 2 will increment its
    // election term to 3.
    member1Actor.clear();
    member1Actor.expectMessageClass(AppendEntries.class, 1);
    member2Actor.clear();
    member2Actor.expectMessageClass(RequestVoteReply.class, 1);
    member2Actor.expectMessageClass(AppendEntriesReply.class, 1);
    member3Actor.clear();
    member3Actor.dropMessagesToBehavior(AppendEntries.class);
    member3Actor.dropMessagesToBehavior(RequestVote.class);
    member2ActorRef.tell(ElectionTimeout.INSTANCE, ActorRef.noSender());
    member2Actor.waitForExpectedMessages(RequestVoteReply.class);
    RequestVoteReply requestVoteReply = member2Actor.getCapturedMessage(RequestVoteReply.class);
    assertEquals("getTerm", member2Context.getTermInformation().getCurrentTerm(), requestVoteReply.getTerm());
    assertEquals("isVoteGranted", true, requestVoteReply.isVoteGranted());
    member3Actor.waitForExpectedMessages(RequestVote.class);
    member1Actor.waitForExpectedMessages(AppendEntries.class);
    member3Actor.waitForExpectedMessages(AppendEntries.class);
    member2Actor.waitForExpectedMessages(AppendEntriesReply.class);
    // We end up with 2 partitioned leaders both leading member 1. The term for member 1 and 3
    // is 3 and member 3's term is 2.
    verifyBehaviorState("member 1", member1Actor, RaftState.Follower);
    verifyBehaviorState("member 2", member2Actor, RaftState.Leader);
    verifyBehaviorState("member 3", member3Actor, RaftState.Leader);
    assertEquals("member 1 election term", 3, member1Context.getTermInformation().getCurrentTerm());
    assertEquals("member 2 election term", 3, member2Context.getTermInformation().getCurrentTerm());
    assertEquals("member 3 election term", 2, member3Context.getTermInformation().getCurrentTerm());
    testLog.info("sendElectionTimeoutToNowCandidateMember2 ending");
}
Also used : RequestVoteReply(org.opendaylight.controller.cluster.raft.messages.RequestVoteReply)

Example 5 with RequestVoteReply

use of org.opendaylight.controller.cluster.raft.messages.RequestVoteReply in project controller by opendaylight.

the class AbstractRaftActorBehaviorTest method testHandleRequestVoteWhenSenderTermLessThanCurrentTerm.

/**
 * This test verifies that the receiving RaftActor will not grant a vote
 * to a sender if the sender's term is lesser than the currentTerm of the
 * recipient RaftActor.
 */
@Test
public void testHandleRequestVoteWhenSenderTermLessThanCurrentTerm() {
    MockRaftActorContext context = createActorContext();
    context.getTermInformation().update(1000, null);
    behavior = createBehavior(context);
    behavior.handleMessage(behaviorActor, new RequestVote(999, "test", 10000, 999));
    RequestVoteReply reply = MessageCollectorActor.expectFirstMatching(behaviorActor, RequestVoteReply.class);
    assertEquals("isVoteGranted", false, reply.isVoteGranted());
}
Also used : MockRaftActorContext(org.opendaylight.controller.cluster.raft.MockRaftActorContext) RequestVoteReply(org.opendaylight.controller.cluster.raft.messages.RequestVoteReply) RequestVote(org.opendaylight.controller.cluster.raft.messages.RequestVote) AbstractActorTest(org.opendaylight.controller.cluster.raft.AbstractActorTest) Test(org.junit.Test)

Aggregations

RequestVoteReply (org.opendaylight.controller.cluster.raft.messages.RequestVoteReply)20 Test (org.junit.Test)13 MockRaftActorContext (org.opendaylight.controller.cluster.raft.MockRaftActorContext)12 RequestVote (org.opendaylight.controller.cluster.raft.messages.RequestVote)10 AbstractActorTest (org.opendaylight.controller.cluster.raft.AbstractActorTest)3 FiniteDuration (scala.concurrent.duration.FiniteDuration)2 NonPersistentDataProvider (org.opendaylight.controller.cluster.NonPersistentDataProvider)1 DefaultConfigParamsImpl (org.opendaylight.controller.cluster.raft.DefaultConfigParamsImpl)1 ElectionTerm (org.opendaylight.controller.cluster.raft.ElectionTerm)1 RaftActorContext (org.opendaylight.controller.cluster.raft.RaftActorContext)1 RaftActorContextImpl (org.opendaylight.controller.cluster.raft.RaftActorContextImpl)1 AppendEntries (org.opendaylight.controller.cluster.raft.messages.AppendEntries)1 InstallSnapshot (org.opendaylight.controller.cluster.raft.messages.InstallSnapshot)1