Search in sources :

Example 11 with ApplyJournalEntries

use of org.opendaylight.controller.cluster.raft.persisted.ApplyJournalEntries in project controller by opendaylight.

the class RaftActorRecoverySupportTest method testOnRecoveryCompletedWithRemainingBatch.

@Test
public void testOnRecoveryCompletedWithRemainingBatch() {
    ReplicatedLog replicatedLog = context.getReplicatedLog();
    replicatedLog.append(new SimpleReplicatedLogEntry(0, 1, new MockRaftActorContext.MockPayload("0")));
    replicatedLog.append(new SimpleReplicatedLogEntry(1, 1, new MockRaftActorContext.MockPayload("1")));
    sendMessageToSupport(new ApplyJournalEntries(1));
    sendMessageToSupport(RecoveryCompleted.getInstance(), true);
    assertEquals("Last applied", 1, context.getLastApplied());
    assertEquals("Commit index", 1, context.getCommitIndex());
    InOrder inOrder = Mockito.inOrder(mockCohort);
    inOrder.verify(mockCohort).startLogRecoveryBatch(anyInt());
    for (int i = 0; i < replicatedLog.size(); i++) {
        inOrder.verify(mockCohort).appendRecoveredLogEntry(replicatedLog.get(i).getData());
    }
    inOrder.verify(mockCohort).applyCurrentLogRecoveryBatch();
    inOrder.verify(mockCohort).getRestoreFromSnapshot();
    inOrder.verifyNoMoreInteractions();
}
Also used : InOrder(org.mockito.InOrder) SimpleReplicatedLogEntry(org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry) ApplyJournalEntries(org.opendaylight.controller.cluster.raft.persisted.ApplyJournalEntries) MockPayload(org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload) Test(org.junit.Test)

Example 12 with ApplyJournalEntries

use of org.opendaylight.controller.cluster.raft.persisted.ApplyJournalEntries in project controller by opendaylight.

the class RaftActorServerConfigurationSupportTest method testChangeToVotingWithNoLeaderAndForwardedToOtherNodeAfterElectionTimeout.

@Test
public void testChangeToVotingWithNoLeaderAndForwardedToOtherNodeAfterElectionTimeout() {
    LOG.info("testChangeToVotingWithNoLeaderAndForwardedToOtherNodeAfterElectionTimeout starting");
    final String node1ID = "node1";
    final String node2ID = "node2";
    final PeerAddressResolver peerAddressResolver = peerId -> peerId.equals(node1ID) ? actorFactory.createTestActorPath(node1ID) : peerId.equals(node2ID) ? actorFactory.createTestActorPath(node2ID) : null;
    DefaultConfigParamsImpl configParams = new DefaultConfigParamsImpl();
    configParams.setHeartBeatInterval(new FiniteDuration(100, TimeUnit.MILLISECONDS));
    configParams.setElectionTimeoutFactor(3);
    configParams.setPeerAddressResolver(peerAddressResolver);
    ServerConfigurationPayload persistedServerConfig = new ServerConfigurationPayload(Arrays.asList(new ServerInfo(node1ID, false), new ServerInfo(node2ID, false)));
    SimpleReplicatedLogEntry persistedServerConfigEntry = new SimpleReplicatedLogEntry(0, 1, persistedServerConfig);
    InMemoryJournal.addEntry(node1ID, 1, new UpdateElectionTerm(1, "node1"));
    InMemoryJournal.addEntry(node1ID, 2, persistedServerConfigEntry);
    InMemoryJournal.addEntry(node2ID, 1, new UpdateElectionTerm(1, "node1"));
    InMemoryJournal.addEntry(node2ID, 2, persistedServerConfigEntry);
    InMemoryJournal.addEntry(node2ID, 3, new SimpleReplicatedLogEntry(1, 1, new MockRaftActorContext.MockPayload("2")));
    InMemoryJournal.addEntry(node2ID, 4, new ApplyJournalEntries(1));
    ActorRef node1Collector = actorFactory.createActor(MessageCollectorActor.props(), actorFactory.generateActorId("collector"));
    TestActorRef<CollectingMockRaftActor> node1RaftActorRef = actorFactory.createTestActor(CollectingMockRaftActor.props(node1ID, ImmutableMap.<String, String>of(), configParams, PERSISTENT, node1Collector).withDispatcher(Dispatchers.DefaultDispatcherId()), node1ID);
    final CollectingMockRaftActor node1RaftActor = node1RaftActorRef.underlyingActor();
    ActorRef node2Collector = actorFactory.createActor(MessageCollectorActor.props(), actorFactory.generateActorId("collector"));
    TestActorRef<CollectingMockRaftActor> node2RaftActorRef = actorFactory.createTestActor(CollectingMockRaftActor.props(node2ID, ImmutableMap.<String, String>of(), configParams, PERSISTENT, node2Collector).withDispatcher(Dispatchers.DefaultDispatcherId()), node2ID);
    final CollectingMockRaftActor node2RaftActor = node2RaftActorRef.underlyingActor();
    // Send a ChangeServersVotingStatus message to node1 to change mode1 to voting. This should cause
    // node1 to try to elect itself as leader in order to apply the new server config. However node1's log
    // is behind node2's so node2 should not grant node1's vote. This should cause node1 to time out and
    // forward the request to node2.
    ChangeServersVotingStatus changeServers = new ChangeServersVotingStatus(ImmutableMap.of(node1ID, true, node2ID, true));
    node1RaftActorRef.tell(changeServers, testKit.getRef());
    ServerChangeReply reply = testKit.expectMsgClass(testKit.duration("5 seconds"), ServerChangeReply.class);
    assertEquals("getStatus", ServerChangeStatus.OK, reply.getStatus());
    MessageCollectorActor.expectFirstMatching(node2Collector, ApplyJournalEntries.class);
    verifyServerConfigurationPayloadEntry(node2RaftActor.getRaftActorContext().getReplicatedLog(), votingServer(node1ID), votingServer(node2ID));
    assertEquals("getRaftState", RaftState.Leader, node2RaftActor.getRaftState());
    MessageCollectorActor.expectFirstMatching(node1Collector, ApplyJournalEntries.class);
    verifyServerConfigurationPayloadEntry(node1RaftActor.getRaftActorContext().getReplicatedLog(), votingServer(node1ID), votingServer(node2ID));
    assertEquals("isVotingMember", true, node1RaftActor.getRaftActorContext().isVotingMember());
    assertEquals("getRaftState", RaftState.Follower, node1RaftActor.getRaftState());
    LOG.info("testChangeToVotingWithNoLeaderAndForwardedToOtherNodeAfterElectionTimeout ending");
}
Also used : UnInitializedFollowerSnapshotReply(org.opendaylight.controller.cluster.raft.messages.UnInitializedFollowerSnapshotReply) SimpleReplicatedLogEntry(org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry) Arrays(java.util.Arrays) AddServerReply(org.opendaylight.controller.cluster.raft.messages.AddServerReply) ForwardMessageToBehaviorActor(org.opendaylight.controller.cluster.raft.utils.ForwardMessageToBehaviorActor) LoggerFactory(org.slf4j.LoggerFactory) ServerInfo(org.opendaylight.controller.cluster.raft.persisted.ServerInfo) ApplySnapshot(org.opendaylight.controller.cluster.raft.base.messages.ApplySnapshot) ActorRef(akka.actor.ActorRef) Optional(com.google.common.base.Optional) RemoveServer(org.opendaylight.controller.cluster.raft.messages.RemoveServer) RemoveServerReply(org.opendaylight.controller.cluster.raft.messages.RemoveServerReply) Map(java.util.Map) After(org.junit.After) Assert.fail(org.junit.Assert.fail) UntypedActor(akka.actor.UntypedActor) ApplyJournalEntries(org.opendaylight.controller.cluster.raft.persisted.ApplyJournalEntries) RaftActorBehavior(org.opendaylight.controller.cluster.raft.behaviors.RaftActorBehavior) Dispatchers(akka.dispatch.Dispatchers) AppendEntries(org.opendaylight.controller.cluster.raft.messages.AppendEntries) ServerConfigurationPayload(org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload) ImmutableMap(com.google.common.collect.ImmutableMap) AddServer(org.opendaylight.controller.cluster.raft.messages.AddServer) FiniteDuration(scala.concurrent.duration.FiniteDuration) RequestVote(org.opendaylight.controller.cluster.raft.messages.RequestVote) MessageCollectorActor.clearMessages(org.opendaylight.controller.cluster.raft.utils.MessageCollectorActor.clearMessages) Sets(com.google.common.collect.Sets) List(java.util.List) AbstractLeader(org.opendaylight.controller.cluster.raft.behaviors.AbstractLeader) MessageCollectorActor(org.opendaylight.controller.cluster.raft.utils.MessageCollectorActor) MessageCollectorActor.expectMatching(org.opendaylight.controller.cluster.raft.utils.MessageCollectorActor.expectMatching) Props(akka.actor.Props) CaptureSnapshotReply(org.opendaylight.controller.cluster.raft.base.messages.CaptureSnapshotReply) InstallSnapshot(org.opendaylight.controller.cluster.raft.messages.InstallSnapshot) Follower(org.opendaylight.controller.cluster.raft.behaviors.Follower) Stopwatch(com.google.common.base.Stopwatch) ApplyState(org.opendaylight.controller.cluster.raft.base.messages.ApplyState) ServerChangeStatus(org.opendaylight.controller.cluster.raft.messages.ServerChangeStatus) InMemoryJournal(org.opendaylight.controller.cluster.raft.utils.InMemoryJournal) SerializationUtils(org.apache.commons.lang3.SerializationUtils) InMemorySnapshotStore(org.opendaylight.controller.cluster.raft.utils.InMemorySnapshotStore) TimeoutNow(org.opendaylight.controller.cluster.raft.base.messages.TimeoutNow) ArrayList(java.util.ArrayList) InitiateCaptureSnapshot(org.opendaylight.controller.cluster.raft.base.messages.InitiateCaptureSnapshot) MessageCollectorActor.assertNoneMatching(org.opendaylight.controller.cluster.raft.utils.MessageCollectorActor.assertNoneMatching) ChangeServersVotingStatus(org.opendaylight.controller.cluster.raft.messages.ChangeServersVotingStatus) ByteSource(com.google.common.io.ByteSource) Before(org.junit.Before) DisableElectionsRaftPolicy(org.opendaylight.controller.cluster.raft.policy.DisableElectionsRaftPolicy) OutputStream(java.io.OutputStream) MessageCollectorActor.expectFirstMatching(org.opendaylight.controller.cluster.raft.utils.MessageCollectorActor.expectFirstMatching) Logger(org.slf4j.Logger) Assert.assertTrue(org.junit.Assert.assertTrue) ServerChangeReply(org.opendaylight.controller.cluster.raft.messages.ServerChangeReply) Test(org.junit.Test) TestKit(akka.testkit.javadsl.TestKit) TestActorRef(akka.testkit.TestActorRef) Maps(com.google.common.collect.Maps) TimeUnit(java.util.concurrent.TimeUnit) NonPersistentDataProvider(org.opendaylight.controller.cluster.NonPersistentDataProvider) ServerRemoved(org.opendaylight.controller.cluster.raft.messages.ServerRemoved) ByteState(org.opendaylight.controller.cluster.raft.persisted.ByteState) Leader(org.opendaylight.controller.cluster.raft.behaviors.Leader) UpdateElectionTerm(org.opendaylight.controller.cluster.raft.persisted.UpdateElectionTerm) Collections(java.util.Collections) Assert.assertEquals(org.junit.Assert.assertEquals) ServerInfo(org.opendaylight.controller.cluster.raft.persisted.ServerInfo) ActorRef(akka.actor.ActorRef) TestActorRef(akka.testkit.TestActorRef) FiniteDuration(scala.concurrent.duration.FiniteDuration) ServerConfigurationPayload(org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload) SimpleReplicatedLogEntry(org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry) ChangeServersVotingStatus(org.opendaylight.controller.cluster.raft.messages.ChangeServersVotingStatus) ApplyJournalEntries(org.opendaylight.controller.cluster.raft.persisted.ApplyJournalEntries) ServerChangeReply(org.opendaylight.controller.cluster.raft.messages.ServerChangeReply) UpdateElectionTerm(org.opendaylight.controller.cluster.raft.persisted.UpdateElectionTerm) Test(org.junit.Test)

Example 13 with ApplyJournalEntries

use of org.opendaylight.controller.cluster.raft.persisted.ApplyJournalEntries in project controller by opendaylight.

the class RaftActorServerConfigurationSupportTest method testChangeToVotingWithNoLeader.

@Test
public void testChangeToVotingWithNoLeader() {
    LOG.info("testChangeToVotingWithNoLeader starting");
    DefaultConfigParamsImpl configParams = new DefaultConfigParamsImpl();
    configParams.setHeartBeatInterval(new FiniteDuration(100, TimeUnit.MILLISECONDS));
    configParams.setElectionTimeoutFactor(5);
    final String node1ID = "node1";
    final String node2ID = "node2";
    // Set up a persisted ServerConfigurationPayload. Initially node1 and node2 will come up as non-voting.
    // via the server config. The server config will also contain 2 voting peers that are down (ie no
    // actors created).
    ServerConfigurationPayload persistedServerConfig = new ServerConfigurationPayload(Arrays.asList(new ServerInfo(node1ID, false), new ServerInfo(node2ID, false), new ServerInfo("downNode1", true), new ServerInfo("downNode2", true)));
    SimpleReplicatedLogEntry persistedServerConfigEntry = new SimpleReplicatedLogEntry(0, 1, persistedServerConfig);
    InMemoryJournal.addEntry(node1ID, 1, new UpdateElectionTerm(1, "downNode1"));
    InMemoryJournal.addEntry(node1ID, 2, persistedServerConfigEntry);
    InMemoryJournal.addEntry(node1ID, 3, new ApplyJournalEntries(0));
    InMemoryJournal.addEntry(node2ID, 1, new UpdateElectionTerm(1, "downNode2"));
    InMemoryJournal.addEntry(node2ID, 2, persistedServerConfigEntry);
    InMemoryJournal.addEntry(node2ID, 3, new ApplyJournalEntries(0));
    ActorRef node1Collector = actorFactory.createActor(MessageCollectorActor.props(), actorFactory.generateActorId("collector"));
    TestActorRef<CollectingMockRaftActor> node1RaftActorRef = actorFactory.createTestActor(CollectingMockRaftActor.props(node1ID, ImmutableMap.<String, String>of(), configParams, PERSISTENT, node1Collector).withDispatcher(Dispatchers.DefaultDispatcherId()), node1ID);
    CollectingMockRaftActor node1RaftActor = node1RaftActorRef.underlyingActor();
    ActorRef node2Collector = actorFactory.createActor(MessageCollectorActor.props(), actorFactory.generateActorId("collector"));
    TestActorRef<CollectingMockRaftActor> node2RaftActorRef = actorFactory.createTestActor(CollectingMockRaftActor.props(node2ID, ImmutableMap.<String, String>of(), configParams, PERSISTENT, node2Collector).withDispatcher(Dispatchers.DefaultDispatcherId()), node2ID);
    CollectingMockRaftActor node2RaftActor = node2RaftActorRef.underlyingActor();
    node1RaftActor.waitForInitializeBehaviorComplete();
    node2RaftActor.waitForInitializeBehaviorComplete();
    // Verify the intended server config was loaded and applied.
    verifyServerConfigurationPayloadEntry(node1RaftActor.getRaftActorContext().getReplicatedLog(), nonVotingServer(node1ID), nonVotingServer(node2ID), votingServer("downNode1"), votingServer("downNode2"));
    assertEquals("isVotingMember", false, node1RaftActor.getRaftActorContext().isVotingMember());
    assertEquals("getRaftState", RaftState.Follower, node1RaftActor.getRaftState());
    assertEquals("getLeaderId", null, node1RaftActor.getLeaderId());
    verifyServerConfigurationPayloadEntry(node2RaftActor.getRaftActorContext().getReplicatedLog(), nonVotingServer(node1ID), nonVotingServer(node2ID), votingServer("downNode1"), votingServer("downNode2"));
    assertEquals("isVotingMember", false, node2RaftActor.getRaftActorContext().isVotingMember());
    // For the test, we send a ChangeServersVotingStatus message to node1 to flip the voting states for
    // each server, ie node1 and node2 to voting and the 2 down nodes to non-voting. This should cause
    // node1 to try to elect itself as leader in order to apply the new server config. Since the 2
    // down nodes are switched to non-voting, node1 should only need a vote from node2.
    // First send the message such that node1 has no peer address for node2 - should fail.
    ChangeServersVotingStatus changeServers = new ChangeServersVotingStatus(ImmutableMap.of(node1ID, true, node2ID, true, "downNode1", false, "downNode2", false));
    node1RaftActorRef.tell(changeServers, testKit.getRef());
    ServerChangeReply reply = testKit.expectMsgClass(testKit.duration("5 seconds"), ServerChangeReply.class);
    assertEquals("getStatus", ServerChangeStatus.NO_LEADER, reply.getStatus());
    assertEquals("getRaftState", RaftState.Follower, node1RaftActor.getRaftState());
    // Send an AppendEntries so node1 has a leaderId
    long term = node1RaftActor.getRaftActorContext().getTermInformation().getCurrentTerm();
    node1RaftActorRef.tell(new AppendEntries(term, "downNode1", -1L, -1L, Collections.<ReplicatedLogEntry>emptyList(), 0, -1, (short) 1), ActorRef.noSender());
    // Wait for the ElectionTimeout to clear the leaderId. The leaderId must be null so on the next
    // ChangeServersVotingStatus message, it will try to elect a leader.
    AbstractRaftActorIntegrationTest.verifyRaftState(node1RaftActorRef, rs -> assertEquals("getLeader", null, rs.getLeader()));
    // Update node2's peer address and send the message again
    node1RaftActor.setPeerAddress(node2ID, node2RaftActorRef.path().toString());
    node1RaftActorRef.tell(changeServers, testKit.getRef());
    reply = testKit.expectMsgClass(testKit.duration("5 seconds"), ServerChangeReply.class);
    assertEquals("getStatus", ServerChangeStatus.OK, reply.getStatus());
    ApplyJournalEntries apply = MessageCollectorActor.expectFirstMatching(node1Collector, ApplyJournalEntries.class);
    assertEquals("getToIndex", 1, apply.getToIndex());
    verifyServerConfigurationPayloadEntry(node1RaftActor.getRaftActorContext().getReplicatedLog(), votingServer(node1ID), votingServer(node2ID), nonVotingServer("downNode1"), nonVotingServer("downNode2"));
    assertEquals("isVotingMember", true, node1RaftActor.getRaftActorContext().isVotingMember());
    assertEquals("getRaftState", RaftState.Leader, node1RaftActor.getRaftState());
    apply = MessageCollectorActor.expectFirstMatching(node2Collector, ApplyJournalEntries.class);
    assertEquals("getToIndex", 1, apply.getToIndex());
    verifyServerConfigurationPayloadEntry(node2RaftActor.getRaftActorContext().getReplicatedLog(), votingServer(node1ID), votingServer(node2ID), nonVotingServer("downNode1"), nonVotingServer("downNode2"));
    assertEquals("isVotingMember", true, node2RaftActor.getRaftActorContext().isVotingMember());
    assertEquals("getRaftState", RaftState.Follower, node2RaftActor.getRaftState());
    LOG.info("testChangeToVotingWithNoLeader ending");
}
Also used : ServerInfo(org.opendaylight.controller.cluster.raft.persisted.ServerInfo) ActorRef(akka.actor.ActorRef) TestActorRef(akka.testkit.TestActorRef) FiniteDuration(scala.concurrent.duration.FiniteDuration) AppendEntries(org.opendaylight.controller.cluster.raft.messages.AppendEntries) SimpleReplicatedLogEntry(org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry) ServerConfigurationPayload(org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload) SimpleReplicatedLogEntry(org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry) ChangeServersVotingStatus(org.opendaylight.controller.cluster.raft.messages.ChangeServersVotingStatus) ApplyJournalEntries(org.opendaylight.controller.cluster.raft.persisted.ApplyJournalEntries) ServerChangeReply(org.opendaylight.controller.cluster.raft.messages.ServerChangeReply) UpdateElectionTerm(org.opendaylight.controller.cluster.raft.persisted.UpdateElectionTerm) Test(org.junit.Test)

Example 14 with ApplyJournalEntries

use of org.opendaylight.controller.cluster.raft.persisted.ApplyJournalEntries in project controller by opendaylight.

the class RaftActorTest method testRaftActorRecoveryWithPersistenceEnabled.

@Test
public void testRaftActorRecoveryWithPersistenceEnabled() throws Exception {
    TEST_LOG.info("testRaftActorRecoveryWithPersistenceEnabled starting");
    TestKit kit = new TestKit(getSystem());
    String persistenceId = factory.generateActorId("follower-");
    DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
    // Set the heartbeat interval high to essentially disable election otherwise the test
    // may fail if the actor is switched to Leader and the commitIndex is set to the last
    // log entry.
    config.setHeartBeatInterval(new FiniteDuration(1, TimeUnit.DAYS));
    ImmutableMap<String, String> peerAddresses = ImmutableMap.<String, String>builder().put("member1", "address").build();
    ActorRef followerActor = factory.createActor(MockRaftActor.props(persistenceId, peerAddresses, config), persistenceId);
    kit.watch(followerActor);
    List<ReplicatedLogEntry> snapshotUnappliedEntries = new ArrayList<>();
    ReplicatedLogEntry entry1 = new SimpleReplicatedLogEntry(4, 1, new MockRaftActorContext.MockPayload("E"));
    snapshotUnappliedEntries.add(entry1);
    int lastAppliedDuringSnapshotCapture = 3;
    int lastIndexDuringSnapshotCapture = 4;
    // 4 messages as part of snapshot, which are applied to state
    MockSnapshotState snapshotState = new MockSnapshotState(Arrays.asList(new MockRaftActorContext.MockPayload("A"), new MockRaftActorContext.MockPayload("B"), new MockRaftActorContext.MockPayload("C"), new MockRaftActorContext.MockPayload("D")));
    Snapshot snapshot = Snapshot.create(snapshotState, snapshotUnappliedEntries, lastIndexDuringSnapshotCapture, 1, lastAppliedDuringSnapshotCapture, 1, -1, null, null);
    InMemorySnapshotStore.addSnapshot(persistenceId, snapshot);
    // add more entries after snapshot is taken
    List<ReplicatedLogEntry> entries = new ArrayList<>();
    ReplicatedLogEntry entry2 = new SimpleReplicatedLogEntry(5, 1, new MockRaftActorContext.MockPayload("F", 2));
    ReplicatedLogEntry entry3 = new SimpleReplicatedLogEntry(6, 1, new MockRaftActorContext.MockPayload("G", 3));
    ReplicatedLogEntry entry4 = new SimpleReplicatedLogEntry(7, 1, new MockRaftActorContext.MockPayload("H", 4));
    entries.add(entry2);
    entries.add(entry3);
    entries.add(entry4);
    final int lastAppliedToState = 5;
    final int lastIndex = 7;
    InMemoryJournal.addEntry(persistenceId, 5, entry2);
    // 2 entries are applied to state besides the 4 entries in snapshot
    InMemoryJournal.addEntry(persistenceId, 6, new ApplyJournalEntries(lastAppliedToState));
    InMemoryJournal.addEntry(persistenceId, 7, entry3);
    InMemoryJournal.addEntry(persistenceId, 8, entry4);
    // kill the actor
    followerActor.tell(PoisonPill.getInstance(), null);
    kit.expectMsgClass(kit.duration("5 seconds"), Terminated.class);
    kit.unwatch(followerActor);
    // reinstate the actor
    TestActorRef<MockRaftActor> ref = factory.createTestActor(MockRaftActor.props(persistenceId, peerAddresses, config));
    MockRaftActor mockRaftActor = ref.underlyingActor();
    mockRaftActor.waitForRecoveryComplete();
    RaftActorContext context = mockRaftActor.getRaftActorContext();
    assertEquals("Journal log size", snapshotUnappliedEntries.size() + entries.size(), context.getReplicatedLog().size());
    assertEquals("Journal data size", 10, context.getReplicatedLog().dataSize());
    assertEquals("Last index", lastIndex, context.getReplicatedLog().lastIndex());
    assertEquals("Last applied", lastAppliedToState, context.getLastApplied());
    assertEquals("Commit index", lastAppliedToState, context.getCommitIndex());
    assertEquals("Recovered state size", 6, mockRaftActor.getState().size());
    mockRaftActor.waitForInitializeBehaviorComplete();
    assertEquals("getRaftState", RaftState.Follower, mockRaftActor.getRaftState());
    TEST_LOG.info("testRaftActorRecoveryWithPersistenceEnabled ending");
}
Also used : MockSnapshotState(org.opendaylight.controller.cluster.raft.MockRaftActor.MockSnapshotState) ActorRef(akka.actor.ActorRef) TestActorRef(akka.testkit.TestActorRef) ArrayList(java.util.ArrayList) FiniteDuration(scala.concurrent.duration.FiniteDuration) MockPayload(org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload) TestKit(akka.testkit.javadsl.TestKit) ByteString(com.google.protobuf.ByteString) MockPayload(org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload) ApplySnapshot(org.opendaylight.controller.cluster.raft.base.messages.ApplySnapshot) Snapshot(org.opendaylight.controller.cluster.raft.persisted.Snapshot) GetSnapshot(org.opendaylight.controller.cluster.raft.client.messages.GetSnapshot) SimpleReplicatedLogEntry(org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry) SimpleReplicatedLogEntry(org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry) ApplyJournalEntries(org.opendaylight.controller.cluster.raft.persisted.ApplyJournalEntries) Test(org.junit.Test)

Example 15 with ApplyJournalEntries

use of org.opendaylight.controller.cluster.raft.persisted.ApplyJournalEntries in project controller by opendaylight.

the class ReplicationAndSnapshotsIntegrationTest method runTest.

@Test
public void runTest() throws Exception {
    testLog.info("testReplicationAndSnapshots starting");
    // Setup the persistent journal for the leader. We'll start up with 3 journal log entries (one less
    // than the snapshotBatchCount).
    long seqId = 1;
    InMemoryJournal.addEntry(leaderId, seqId++, new UpdateElectionTerm(initialTerm, leaderId));
    recoveredPayload0 = new MockPayload("zero");
    InMemoryJournal.addEntry(leaderId, seqId++, new SimpleReplicatedLogEntry(0, initialTerm, recoveredPayload0));
    recoveredPayload1 = new MockPayload("one");
    InMemoryJournal.addEntry(leaderId, seqId++, new SimpleReplicatedLogEntry(1, initialTerm, recoveredPayload1));
    recoveredPayload2 = new MockPayload("two");
    InMemoryJournal.addEntry(leaderId, seqId++, new SimpleReplicatedLogEntry(2, initialTerm, recoveredPayload2));
    InMemoryJournal.addEntry(leaderId, seqId++, new ApplyJournalEntries(2));
    origLeaderJournal = InMemoryJournal.get(leaderId, SimpleReplicatedLogEntry.class);
    // Create the leader and 2 follower actors and verify initial syncing of the followers after leader
    // persistence recovery.
    DefaultConfigParamsImpl followerConfigParams = newFollowerConfigParams();
    followerConfigParams.setSnapshotBatchCount(snapshotBatchCount);
    follower1Actor = newTestRaftActor(follower1Id, ImmutableMap.of(leaderId, testActorPath(leaderId), follower2Id, testActorPath(follower2Id)), followerConfigParams);
    follower2Actor = newTestRaftActor(follower2Id, ImmutableMap.of(leaderId, testActorPath(leaderId), follower1Id, testActorPath(follower1Id)), followerConfigParams);
    peerAddresses = ImmutableMap.<String, String>builder().put(follower1Id, follower1Actor.path().toString()).put(follower2Id, follower2Actor.path().toString()).build();
    leaderConfigParams = newLeaderConfigParams();
    leaderActor = newTestRaftActor(leaderId, peerAddresses, leaderConfigParams);
    follower1CollectorActor = follower1Actor.underlyingActor().collectorActor();
    follower2CollectorActor = follower2Actor.underlyingActor().collectorActor();
    leaderCollectorActor = leaderActor.underlyingActor().collectorActor();
    leaderContext = leaderActor.underlyingActor().getRaftActorContext();
    verifyLeaderRecoveryAndInitialization();
    testFirstSnapshot();
    testSubsequentReplications();
    testSecondSnapshot();
    testLeaderReinstatement();
    testLog.info("testReplicationAndSnapshots ending");
}
Also used : SimpleReplicatedLogEntry(org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry) ApplyJournalEntries(org.opendaylight.controller.cluster.raft.persisted.ApplyJournalEntries) UpdateElectionTerm(org.opendaylight.controller.cluster.raft.persisted.UpdateElectionTerm) MockPayload(org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload) Test(org.junit.Test)

Aggregations

ApplyJournalEntries (org.opendaylight.controller.cluster.raft.persisted.ApplyJournalEntries)19 Test (org.junit.Test)15 SimpleReplicatedLogEntry (org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry)14 MockPayload (org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload)9 UpdateElectionTerm (org.opendaylight.controller.cluster.raft.persisted.UpdateElectionTerm)7 ApplyState (org.opendaylight.controller.cluster.raft.base.messages.ApplyState)6 Snapshot (org.opendaylight.controller.cluster.raft.persisted.Snapshot)6 ActorRef (akka.actor.ActorRef)5 TestActorRef (akka.testkit.TestActorRef)5 ApplySnapshot (org.opendaylight.controller.cluster.raft.base.messages.ApplySnapshot)5 FiniteDuration (scala.concurrent.duration.FiniteDuration)5 ByteString (com.google.protobuf.ByteString)4 TestKit (akka.testkit.javadsl.TestKit)3 ServerConfigurationPayload (org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload)3 ServerInfo (org.opendaylight.controller.cluster.raft.persisted.ServerInfo)3 SnapshotMetadata (akka.persistence.SnapshotMetadata)2 SnapshotOffer (akka.persistence.SnapshotOffer)2 Optional (com.google.common.base.Optional)2 Stopwatch (com.google.common.base.Stopwatch)2 ByteSource (com.google.common.io.ByteSource)2