Search in sources :

Example 1 with SendInstallSnapshot

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

the class AbstractLeader method handleMessage.

@Override
public RaftActorBehavior handleMessage(final ActorRef sender, final Object message) {
    Preconditions.checkNotNull(sender, "sender should not be null");
    if (appendEntriesMessageSlicer.handleMessage(message)) {
        return this;
    }
    if (message instanceof RaftRPC) {
        RaftRPC rpc = (RaftRPC) message;
        // This applies to all RPC messages and responses
        if (rpc.getTerm() > context.getTermInformation().getCurrentTerm()) {
            log.info("{}: Term {} in \"{}\" message is greater than leader's term {} - switching to Follower", logName(), rpc.getTerm(), rpc, context.getTermInformation().getCurrentTerm());
            context.getTermInformation().updateAndPersist(rpc.getTerm(), null);
            // leadership, we should make every effort to get the requesting node elected.
            if (message instanceof RequestVote && context.getRaftActorLeadershipTransferCohort() != null) {
                log.debug("{}: Leadership transfer in progress - processing RequestVote", logName());
                super.handleMessage(sender, message);
            }
            return internalSwitchBehavior(RaftState.Follower);
        }
    }
    if (message instanceof SendHeartBeat) {
        beforeSendHeartbeat();
        sendHeartBeat();
        scheduleHeartBeat(context.getConfigParams().getHeartBeatInterval());
    } else if (message instanceof SendInstallSnapshot) {
        SendInstallSnapshot sendInstallSnapshot = (SendInstallSnapshot) message;
        setSnapshotHolder(new SnapshotHolder(sendInstallSnapshot.getSnapshot(), sendInstallSnapshot.getSnapshotBytes()));
        sendInstallSnapshot();
    } else if (message instanceof Replicate) {
        replicate((Replicate) message);
    } else if (message instanceof InstallSnapshotReply) {
        handleInstallSnapshotReply((InstallSnapshotReply) message);
    } else if (message instanceof CheckConsensusReached) {
        possiblyUpdateCommitIndex();
    } else {
        return super.handleMessage(sender, message);
    }
    return this;
}
Also used : RaftRPC(org.opendaylight.controller.cluster.raft.messages.RaftRPC) SendInstallSnapshot(org.opendaylight.controller.cluster.raft.base.messages.SendInstallSnapshot) Replicate(org.opendaylight.controller.cluster.raft.base.messages.Replicate) CheckConsensusReached(org.opendaylight.controller.cluster.raft.base.messages.CheckConsensusReached) InstallSnapshotReply(org.opendaylight.controller.cluster.raft.messages.InstallSnapshotReply) SendHeartBeat(org.opendaylight.controller.cluster.raft.base.messages.SendHeartBeat) RequestVote(org.opendaylight.controller.cluster.raft.messages.RequestVote)

Example 2 with SendInstallSnapshot

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

the class LeaderTest method testHandleInstallSnapshotReplyWithInvalidChunkIndex.

@Test
public void testHandleInstallSnapshotReplyWithInvalidChunkIndex() throws Exception {
    logStart("testHandleInstallSnapshotReplyWithInvalidChunkIndex");
    MockRaftActorContext actorContext = createActorContextWithFollower();
    final int commitIndex = 3;
    final int snapshotIndex = 2;
    final int snapshotTerm = 1;
    final int currentTerm = 2;
    actorContext.setConfigParams(new DefaultConfigParamsImpl() {

        @Override
        public int getSnapshotChunkSize() {
            return 50;
        }
    });
    actorContext.setCommitIndex(commitIndex);
    leader = new Leader(actorContext);
    leader.getFollower(FOLLOWER_ID).setMatchIndex(-1);
    leader.getFollower(FOLLOWER_ID).setNextIndex(0);
    Map<String, String> leadersSnapshot = new HashMap<>();
    leadersSnapshot.put("1", "A");
    leadersSnapshot.put("2", "B");
    leadersSnapshot.put("3", "C");
    // set the snapshot variables in replicatedlog
    actorContext.getReplicatedLog().setSnapshotIndex(snapshotIndex);
    actorContext.getReplicatedLog().setSnapshotTerm(snapshotTerm);
    actorContext.getTermInformation().update(currentTerm, leaderActor.path().toString());
    ByteString bs = toByteString(leadersSnapshot);
    Snapshot snapshot = Snapshot.create(ByteState.of(bs.toByteArray()), Collections.<ReplicatedLogEntry>emptyList(), commitIndex, snapshotTerm, commitIndex, snapshotTerm, -1, null, null);
    Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS);
    leader.handleMessage(leaderActor, new SendInstallSnapshot(snapshot, ByteSource.wrap(bs.toByteArray())));
    InstallSnapshot installSnapshot = MessageCollectorActor.expectFirstMatching(followerActor, InstallSnapshot.class);
    assertEquals(1, installSnapshot.getChunkIndex());
    assertEquals(3, installSnapshot.getTotalChunks());
    followerActor.underlyingActor().clear();
    leader.handleMessage(followerActor, new InstallSnapshotReply(actorContext.getTermInformation().getCurrentTerm(), FOLLOWER_ID, -1, false));
    Uninterruptibles.sleepUninterruptibly(actorContext.getConfigParams().getHeartBeatInterval().toMillis(), TimeUnit.MILLISECONDS);
    leader.handleMessage(leaderActor, SendHeartBeat.INSTANCE);
    installSnapshot = MessageCollectorActor.expectFirstMatching(followerActor, InstallSnapshot.class);
    assertEquals(1, installSnapshot.getChunkIndex());
    assertEquals(3, installSnapshot.getTotalChunks());
}
Also used : SendInstallSnapshot(org.opendaylight.controller.cluster.raft.base.messages.SendInstallSnapshot) HashMap(java.util.HashMap) InstallSnapshotReply(org.opendaylight.controller.cluster.raft.messages.InstallSnapshotReply) ByteString(com.google.protobuf.ByteString) MockRaftActorContext(org.opendaylight.controller.cluster.raft.MockRaftActorContext) DefaultConfigParamsImpl(org.opendaylight.controller.cluster.raft.DefaultConfigParamsImpl) ByteString(com.google.protobuf.ByteString) InstallSnapshot(org.opendaylight.controller.cluster.raft.messages.InstallSnapshot) SendInstallSnapshot(org.opendaylight.controller.cluster.raft.base.messages.SendInstallSnapshot) Snapshot(org.opendaylight.controller.cluster.raft.persisted.Snapshot) InstallSnapshot(org.opendaylight.controller.cluster.raft.messages.InstallSnapshot) CaptureSnapshot(org.opendaylight.controller.cluster.raft.base.messages.CaptureSnapshot) SendInstallSnapshot(org.opendaylight.controller.cluster.raft.base.messages.SendInstallSnapshot) Test(org.junit.Test)

Example 3 with SendInstallSnapshot

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

the class LeaderTest method testSendSnapshotfromInstallSnapshotReply.

@Test
public void testSendSnapshotfromInstallSnapshotReply() throws Exception {
    logStart("testSendSnapshotfromInstallSnapshotReply");
    MockRaftActorContext actorContext = createActorContextWithFollower();
    final int commitIndex = 3;
    final int snapshotIndex = 2;
    final int snapshotTerm = 1;
    final int currentTerm = 2;
    DefaultConfigParamsImpl configParams = new DefaultConfigParamsImpl() {

        @Override
        public int getSnapshotChunkSize() {
            return 50;
        }
    };
    configParams.setHeartBeatInterval(new FiniteDuration(9, TimeUnit.SECONDS));
    configParams.setIsolatedLeaderCheckInterval(new FiniteDuration(10, TimeUnit.SECONDS));
    actorContext.setConfigParams(configParams);
    actorContext.setCommitIndex(commitIndex);
    leader = new Leader(actorContext);
    actorContext.setCurrentBehavior(leader);
    leader.getFollower(FOLLOWER_ID).setMatchIndex(-1);
    leader.getFollower(FOLLOWER_ID).setNextIndex(0);
    Map<String, String> leadersSnapshot = new HashMap<>();
    leadersSnapshot.put("1", "A");
    leadersSnapshot.put("2", "B");
    leadersSnapshot.put("3", "C");
    // set the snapshot variables in replicatedlog
    actorContext.getReplicatedLog().setSnapshotIndex(snapshotIndex);
    actorContext.getReplicatedLog().setSnapshotTerm(snapshotTerm);
    actorContext.getTermInformation().update(currentTerm, leaderActor.path().toString());
    ByteString bs = toByteString(leadersSnapshot);
    Snapshot snapshot = Snapshot.create(ByteState.of(bs.toByteArray()), Collections.<ReplicatedLogEntry>emptyList(), commitIndex, snapshotTerm, commitIndex, snapshotTerm, -1, null, null);
    leader.handleMessage(leaderActor, new SendInstallSnapshot(snapshot, ByteSource.wrap(bs.toByteArray())));
    InstallSnapshot installSnapshot = MessageCollectorActor.expectFirstMatching(followerActor, InstallSnapshot.class);
    assertEquals(1, installSnapshot.getChunkIndex());
    assertEquals(3, installSnapshot.getTotalChunks());
    followerActor.underlyingActor().clear();
    leader.handleMessage(followerActor, new InstallSnapshotReply(actorContext.getTermInformation().getCurrentTerm(), FOLLOWER_ID, installSnapshot.getChunkIndex(), true));
    installSnapshot = MessageCollectorActor.expectFirstMatching(followerActor, InstallSnapshot.class);
    assertEquals(2, installSnapshot.getChunkIndex());
    assertEquals(3, installSnapshot.getTotalChunks());
    followerActor.underlyingActor().clear();
    leader.handleMessage(followerActor, new InstallSnapshotReply(actorContext.getTermInformation().getCurrentTerm(), FOLLOWER_ID, installSnapshot.getChunkIndex(), true));
    installSnapshot = MessageCollectorActor.expectFirstMatching(followerActor, InstallSnapshot.class);
    // Send snapshot reply one more time and make sure that a new snapshot message should not be sent to follower
    followerActor.underlyingActor().clear();
    leader.handleMessage(followerActor, new InstallSnapshotReply(actorContext.getTermInformation().getCurrentTerm(), FOLLOWER_ID, installSnapshot.getChunkIndex(), true));
    installSnapshot = MessageCollectorActor.getFirstMatching(followerActor, InstallSnapshot.class);
    assertNull(installSnapshot);
}
Also used : SendInstallSnapshot(org.opendaylight.controller.cluster.raft.base.messages.SendInstallSnapshot) HashMap(java.util.HashMap) InstallSnapshotReply(org.opendaylight.controller.cluster.raft.messages.InstallSnapshotReply) ByteString(com.google.protobuf.ByteString) MockRaftActorContext(org.opendaylight.controller.cluster.raft.MockRaftActorContext) FiniteDuration(scala.concurrent.duration.FiniteDuration) DefaultConfigParamsImpl(org.opendaylight.controller.cluster.raft.DefaultConfigParamsImpl) ByteString(com.google.protobuf.ByteString) InstallSnapshot(org.opendaylight.controller.cluster.raft.messages.InstallSnapshot) SendInstallSnapshot(org.opendaylight.controller.cluster.raft.base.messages.SendInstallSnapshot) Snapshot(org.opendaylight.controller.cluster.raft.persisted.Snapshot) InstallSnapshot(org.opendaylight.controller.cluster.raft.messages.InstallSnapshot) CaptureSnapshot(org.opendaylight.controller.cluster.raft.base.messages.CaptureSnapshot) SendInstallSnapshot(org.opendaylight.controller.cluster.raft.base.messages.SendInstallSnapshot) Test(org.junit.Test)

Example 4 with SendInstallSnapshot

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

the class LeaderTest method testInstallSnapshot.

@Test
public void testInstallSnapshot() throws Exception {
    logStart("testInstallSnapshot");
    final MockRaftActorContext actorContext = createActorContextWithFollower();
    Map<String, String> leadersSnapshot = new HashMap<>();
    leadersSnapshot.put("1", "A");
    leadersSnapshot.put("2", "B");
    leadersSnapshot.put("3", "C");
    // clears leaders log
    actorContext.getReplicatedLog().removeFrom(0);
    final int lastAppliedIndex = 3;
    final int snapshotIndex = 2;
    final int snapshotTerm = 1;
    final int currentTerm = 2;
    // set the snapshot variables in replicatedlog
    actorContext.getReplicatedLog().setSnapshotIndex(snapshotIndex);
    actorContext.getReplicatedLog().setSnapshotTerm(snapshotTerm);
    actorContext.getTermInformation().update(currentTerm, leaderActor.path().toString());
    actorContext.setCommitIndex(lastAppliedIndex);
    actorContext.setLastApplied(lastAppliedIndex);
    leader = new Leader(actorContext);
    // Initial heartbeat.
    MessageCollectorActor.expectFirstMatching(followerActor, AppendEntries.class);
    leader.getFollower(FOLLOWER_ID).setMatchIndex(-1);
    leader.getFollower(FOLLOWER_ID).setNextIndex(0);
    byte[] bytes = toByteString(leadersSnapshot).toByteArray();
    Snapshot snapshot = Snapshot.create(ByteState.of(bytes), Collections.<ReplicatedLogEntry>emptyList(), lastAppliedIndex, snapshotTerm, lastAppliedIndex, snapshotTerm, -1, null, null);
    RaftActorBehavior raftBehavior = leader.handleMessage(leaderActor, new SendInstallSnapshot(snapshot, ByteSource.wrap(bytes)));
    assertTrue(raftBehavior instanceof Leader);
    // check if installsnapshot gets called with the correct values.
    InstallSnapshot installSnapshot = MessageCollectorActor.expectFirstMatching(followerActor, InstallSnapshot.class);
    assertNotNull(installSnapshot.getData());
    assertEquals(lastAppliedIndex, installSnapshot.getLastIncludedIndex());
    assertEquals(snapshotTerm, installSnapshot.getLastIncludedTerm());
    assertEquals(currentTerm, installSnapshot.getTerm());
}
Also used : Snapshot(org.opendaylight.controller.cluster.raft.persisted.Snapshot) InstallSnapshot(org.opendaylight.controller.cluster.raft.messages.InstallSnapshot) CaptureSnapshot(org.opendaylight.controller.cluster.raft.base.messages.CaptureSnapshot) SendInstallSnapshot(org.opendaylight.controller.cluster.raft.base.messages.SendInstallSnapshot) SendInstallSnapshot(org.opendaylight.controller.cluster.raft.base.messages.SendInstallSnapshot) HashMap(java.util.HashMap) MockRaftActorContext(org.opendaylight.controller.cluster.raft.MockRaftActorContext) ByteString(com.google.protobuf.ByteString) InstallSnapshot(org.opendaylight.controller.cluster.raft.messages.InstallSnapshot) SendInstallSnapshot(org.opendaylight.controller.cluster.raft.base.messages.SendInstallSnapshot) Test(org.junit.Test)

Example 5 with SendInstallSnapshot

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

the class LeaderTest method testForceInstallSnapshot.

@Test
public void testForceInstallSnapshot() throws Exception {
    logStart("testForceInstallSnapshot");
    final MockRaftActorContext actorContext = createActorContextWithFollower();
    Map<String, String> leadersSnapshot = new HashMap<>();
    leadersSnapshot.put("1", "A");
    leadersSnapshot.put("2", "B");
    leadersSnapshot.put("3", "C");
    final int lastAppliedIndex = 3;
    final int snapshotIndex = -1;
    final int snapshotTerm = -1;
    final int currentTerm = 2;
    // set the snapshot variables in replicatedlog
    actorContext.getReplicatedLog().setSnapshotIndex(snapshotIndex);
    actorContext.getReplicatedLog().setSnapshotTerm(snapshotTerm);
    actorContext.getTermInformation().update(currentTerm, leaderActor.path().toString());
    actorContext.setCommitIndex(lastAppliedIndex);
    actorContext.setLastApplied(lastAppliedIndex);
    leader = new Leader(actorContext);
    // Initial heartbeat.
    MessageCollectorActor.expectFirstMatching(followerActor, AppendEntries.class);
    leader.getFollower(FOLLOWER_ID).setMatchIndex(-1);
    leader.getFollower(FOLLOWER_ID).setNextIndex(-1);
    byte[] bytes = toByteString(leadersSnapshot).toByteArray();
    Snapshot snapshot = Snapshot.create(ByteState.of(bytes), Collections.<ReplicatedLogEntry>emptyList(), lastAppliedIndex, snapshotTerm, lastAppliedIndex, snapshotTerm, -1, null, null);
    RaftActorBehavior raftBehavior = leader.handleMessage(leaderActor, new SendInstallSnapshot(snapshot, ByteSource.wrap(bytes)));
    assertTrue(raftBehavior instanceof Leader);
    // check if installsnapshot gets called with the correct values.
    InstallSnapshot installSnapshot = MessageCollectorActor.expectFirstMatching(followerActor, InstallSnapshot.class);
    assertNotNull(installSnapshot.getData());
    assertEquals(lastAppliedIndex, installSnapshot.getLastIncludedIndex());
    assertEquals(snapshotTerm, installSnapshot.getLastIncludedTerm());
    assertEquals(currentTerm, installSnapshot.getTerm());
}
Also used : Snapshot(org.opendaylight.controller.cluster.raft.persisted.Snapshot) InstallSnapshot(org.opendaylight.controller.cluster.raft.messages.InstallSnapshot) CaptureSnapshot(org.opendaylight.controller.cluster.raft.base.messages.CaptureSnapshot) SendInstallSnapshot(org.opendaylight.controller.cluster.raft.base.messages.SendInstallSnapshot) SendInstallSnapshot(org.opendaylight.controller.cluster.raft.base.messages.SendInstallSnapshot) HashMap(java.util.HashMap) MockRaftActorContext(org.opendaylight.controller.cluster.raft.MockRaftActorContext) ByteString(com.google.protobuf.ByteString) InstallSnapshot(org.opendaylight.controller.cluster.raft.messages.InstallSnapshot) SendInstallSnapshot(org.opendaylight.controller.cluster.raft.base.messages.SendInstallSnapshot) Test(org.junit.Test)

Aggregations

SendInstallSnapshot (org.opendaylight.controller.cluster.raft.base.messages.SendInstallSnapshot)7 Test (org.junit.Test)6 CaptureSnapshot (org.opendaylight.controller.cluster.raft.base.messages.CaptureSnapshot)6 Snapshot (org.opendaylight.controller.cluster.raft.persisted.Snapshot)6 ByteString (com.google.protobuf.ByteString)5 HashMap (java.util.HashMap)5 MockRaftActorContext (org.opendaylight.controller.cluster.raft.MockRaftActorContext)5 InstallSnapshot (org.opendaylight.controller.cluster.raft.messages.InstallSnapshot)5 InstallSnapshotReply (org.opendaylight.controller.cluster.raft.messages.InstallSnapshotReply)4 DefaultConfigParamsImpl (org.opendaylight.controller.cluster.raft.DefaultConfigParamsImpl)3 ActorRef (akka.actor.ActorRef)1 OutputStream (java.io.OutputStream)1 Optional (java.util.Optional)1 CheckConsensusReached (org.opendaylight.controller.cluster.raft.base.messages.CheckConsensusReached)1 Replicate (org.opendaylight.controller.cluster.raft.base.messages.Replicate)1 SendHeartBeat (org.opendaylight.controller.cluster.raft.base.messages.SendHeartBeat)1 RaftRPC (org.opendaylight.controller.cluster.raft.messages.RaftRPC)1 RequestVote (org.opendaylight.controller.cluster.raft.messages.RequestVote)1 ByteState (org.opendaylight.controller.cluster.raft.persisted.ByteState)1 SimpleReplicatedLogEntry (org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry)1