Search in sources :

Example 1 with DataPersistenceProvider

use of org.opendaylight.controller.cluster.DataPersistenceProvider in project controller by opendaylight.

the class RaftActorTest method testApplyJournalEntriesCallsDataPersistence.

@SuppressWarnings("unchecked")
@Test
public void testApplyJournalEntriesCallsDataPersistence() throws Exception {
    String persistenceId = factory.generateActorId("leader-");
    DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
    config.setHeartBeatInterval(new FiniteDuration(1, TimeUnit.DAYS));
    DataPersistenceProvider dataPersistenceProvider = mock(DataPersistenceProvider.class);
    TestActorRef<MockRaftActor> mockActorRef = factory.createTestActor(MockRaftActor.props(persistenceId, Collections.<String, String>emptyMap(), config, dataPersistenceProvider), persistenceId);
    MockRaftActor mockRaftActor = mockActorRef.underlyingActor();
    mockRaftActor.waitForInitializeBehaviorComplete();
    mockRaftActor.waitUntilLeader();
    mockRaftActor.onReceiveCommand(new ApplyJournalEntries(10));
    verify(dataPersistenceProvider).persistAsync(any(ApplyJournalEntries.class), any(Procedure.class));
}
Also used : DataPersistenceProvider(org.opendaylight.controller.cluster.DataPersistenceProvider) ApplyJournalEntries(org.opendaylight.controller.cluster.raft.persisted.ApplyJournalEntries) FiniteDuration(scala.concurrent.duration.FiniteDuration) Procedure(akka.japi.Procedure) ByteString(com.google.protobuf.ByteString) Test(org.junit.Test)

Example 2 with DataPersistenceProvider

use of org.opendaylight.controller.cluster.DataPersistenceProvider in project controller by opendaylight.

the class RaftActorTest method testApplyState.

@Test
public void testApplyState() throws Exception {
    String persistenceId = factory.generateActorId("leader-");
    DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
    config.setHeartBeatInterval(new FiniteDuration(1, TimeUnit.DAYS));
    DataPersistenceProvider dataPersistenceProvider = mock(DataPersistenceProvider.class);
    TestActorRef<MockRaftActor> mockActorRef = factory.createTestActor(MockRaftActor.props(persistenceId, Collections.<String, String>emptyMap(), config, dataPersistenceProvider), persistenceId);
    MockRaftActor mockRaftActor = mockActorRef.underlyingActor();
    mockRaftActor.waitForInitializeBehaviorComplete();
    ReplicatedLogEntry entry = new SimpleReplicatedLogEntry(5, 1, new MockRaftActorContext.MockPayload("F"));
    final Identifier id = new MockIdentifier("apply-state");
    mockRaftActor.getRaftActorContext().getApplyStateConsumer().accept(new ApplyState(mockActorRef, id, entry));
    verify(mockRaftActor.actorDelegate).applyState(eq(mockActorRef), eq(id), anyObject());
}
Also used : FiniteDuration(scala.concurrent.duration.FiniteDuration) MockPayload(org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload) ByteString(com.google.protobuf.ByteString) SimpleReplicatedLogEntry(org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry) Identifier(org.opendaylight.yangtools.concepts.Identifier) SimpleReplicatedLogEntry(org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry) DataPersistenceProvider(org.opendaylight.controller.cluster.DataPersistenceProvider) ApplyState(org.opendaylight.controller.cluster.raft.base.messages.ApplyState) Test(org.junit.Test)

Example 3 with DataPersistenceProvider

use of org.opendaylight.controller.cluster.DataPersistenceProvider in project controller by opendaylight.

the class RaftActorTest method testFakeSnapshotsForLeaderWithInRealSnapshots.

@Test
public void testFakeSnapshotsForLeaderWithInRealSnapshots() throws Exception {
    final String persistenceId = factory.generateActorId("leader-");
    final String follower1Id = factory.generateActorId("follower-");
    ActorRef followerActor1 = factory.createActor(MessageCollectorActor.props());
    DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
    config.setHeartBeatInterval(new FiniteDuration(1, TimeUnit.DAYS));
    config.setIsolatedLeaderCheckInterval(new FiniteDuration(1, TimeUnit.DAYS));
    DataPersistenceProvider dataPersistenceProvider = mock(DataPersistenceProvider.class);
    Map<String, String> peerAddresses = new HashMap<>();
    peerAddresses.put(follower1Id, followerActor1.path().toString());
    TestActorRef<MockRaftActor> mockActorRef = factory.createTestActor(MockRaftActor.props(persistenceId, peerAddresses, config, dataPersistenceProvider), persistenceId);
    MockRaftActor leaderActor = mockActorRef.underlyingActor();
    leaderActor.getRaftActorContext().setCommitIndex(4);
    leaderActor.getRaftActorContext().setLastApplied(4);
    leaderActor.getRaftActorContext().getTermInformation().update(1, persistenceId);
    leaderActor.waitForInitializeBehaviorComplete();
    // create 8 entries in the log - 0 to 4 are applied and will get picked up as part of the capture snapshot
    Leader leader = new Leader(leaderActor.getRaftActorContext());
    leaderActor.setCurrentBehavior(leader);
    assertEquals(RaftState.Leader, leaderActor.getCurrentBehavior().state());
    MockRaftActorContext.MockReplicatedLogBuilder logBuilder = new MockRaftActorContext.MockReplicatedLogBuilder();
    leaderActor.getRaftActorContext().setReplicatedLog(logBuilder.createEntries(0, 8, 1).build());
    assertEquals(8, leaderActor.getReplicatedLog().size());
    leaderActor.getRaftActorContext().getSnapshotManager().capture(new SimpleReplicatedLogEntry(6, 1, new MockRaftActorContext.MockPayload("x")), 4);
    verify(leaderActor.snapshotCohortDelegate).createSnapshot(anyObject(), anyObject());
    assertEquals(8, leaderActor.getReplicatedLog().size());
    assertEquals(RaftState.Leader, leaderActor.getCurrentBehavior().state());
    // fake snapshot on index 5
    leaderActor.onReceiveCommand(new AppendEntriesReply(follower1Id, 1, true, 5, 1, (short) 0));
    assertEquals(8, leaderActor.getReplicatedLog().size());
    // fake snapshot on index 6
    assertEquals(RaftState.Leader, leaderActor.getCurrentBehavior().state());
    leaderActor.onReceiveCommand(new AppendEntriesReply(follower1Id, 1, true, 6, 1, (short) 0));
    assertEquals(8, leaderActor.getReplicatedLog().size());
    assertEquals(RaftState.Leader, leaderActor.getCurrentBehavior().state());
    assertEquals(8, leaderActor.getReplicatedLog().size());
    MockSnapshotState snapshotState = new MockSnapshotState(Arrays.asList(new MockRaftActorContext.MockPayload("foo-0"), new MockRaftActorContext.MockPayload("foo-1"), new MockRaftActorContext.MockPayload("foo-2"), new MockRaftActorContext.MockPayload("foo-3"), new MockRaftActorContext.MockPayload("foo-4")));
    leaderActor.getRaftActorContext().getSnapshotManager().persist(snapshotState, java.util.Optional.empty(), Runtime.getRuntime().totalMemory());
    assertTrue(leaderActor.getRaftActorContext().getSnapshotManager().isCapturing());
    // The commit is needed to complete the snapshot creation process
    leaderActor.getRaftActorContext().getSnapshotManager().commit(-1, -1);
    // capture snapshot reply should remove the snapshotted entries only
    assertEquals(3, leaderActor.getReplicatedLog().size());
    assertEquals(7, leaderActor.getReplicatedLog().lastIndex());
    // add another non-replicated entry
    leaderActor.getReplicatedLog().append(new SimpleReplicatedLogEntry(8, 1, new MockRaftActorContext.MockPayload("foo-8")));
    // fake snapshot on index 7, since lastApplied = 7 , we would keep the last applied
    leaderActor.onReceiveCommand(new AppendEntriesReply(follower1Id, 1, true, 7, 1, (short) 0));
    assertEquals(2, leaderActor.getReplicatedLog().size());
    assertEquals(8, leaderActor.getReplicatedLog().lastIndex());
}
Also used : MockSnapshotState(org.opendaylight.controller.cluster.raft.MockRaftActor.MockSnapshotState) Leader(org.opendaylight.controller.cluster.raft.behaviors.Leader) HashMap(java.util.HashMap) ActorRef(akka.actor.ActorRef) TestActorRef(akka.testkit.TestActorRef) FiniteDuration(scala.concurrent.duration.FiniteDuration) ByteString(com.google.protobuf.ByteString) MockPayload(org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload) SimpleReplicatedLogEntry(org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry) AppendEntriesReply(org.opendaylight.controller.cluster.raft.messages.AppendEntriesReply) DataPersistenceProvider(org.opendaylight.controller.cluster.DataPersistenceProvider) Test(org.junit.Test)

Example 4 with DataPersistenceProvider

use of org.opendaylight.controller.cluster.DataPersistenceProvider in project controller by opendaylight.

the class RaftActorTest method testRealSnapshotWhenReplicatedToAllIndexMinusOne.

@Test
public void testRealSnapshotWhenReplicatedToAllIndexMinusOne() throws Exception {
    String persistenceId = factory.generateActorId("leader-");
    DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
    config.setHeartBeatInterval(new FiniteDuration(1, TimeUnit.DAYS));
    config.setIsolatedLeaderCheckInterval(new FiniteDuration(1, TimeUnit.DAYS));
    config.setSnapshotBatchCount(5);
    DataPersistenceProvider dataPersistenceProvider = createProvider();
    Map<String, String> peerAddresses = ImmutableMap.<String, String>builder().put("member1", "address").build();
    TestActorRef<MockRaftActor> mockActorRef = factory.createTestActor(MockRaftActor.props(persistenceId, peerAddresses, config, dataPersistenceProvider), persistenceId);
    MockRaftActor leaderActor = mockActorRef.underlyingActor();
    leaderActor.getRaftActorContext().setCommitIndex(3);
    leaderActor.getRaftActorContext().setLastApplied(3);
    leaderActor.getRaftActorContext().getTermInformation().update(1, persistenceId);
    leaderActor.waitForInitializeBehaviorComplete();
    for (int i = 0; i < 4; i++) {
        leaderActor.getReplicatedLog().append(new SimpleReplicatedLogEntry(i, 1, new MockRaftActorContext.MockPayload("A")));
    }
    Leader leader = new Leader(leaderActor.getRaftActorContext());
    leaderActor.setCurrentBehavior(leader);
    assertEquals(RaftState.Leader, leaderActor.getCurrentBehavior().state());
    // Simulate an install snaphost to a follower.
    leaderActor.getRaftActorContext().getSnapshotManager().captureToInstall(leaderActor.getReplicatedLog().last(), -1, "member1");
    // Now send a CaptureSnapshotReply
    mockActorRef.tell(new CaptureSnapshotReply(ByteState.of(fromObject("foo").toByteArray()), java.util.Optional.empty()), mockActorRef);
    // Trimming log in this scenario is a no-op
    assertEquals(-1, leaderActor.getReplicatedLog().getSnapshotIndex());
    assertTrue(leaderActor.getRaftActorContext().getSnapshotManager().isCapturing());
    assertEquals(-1, leader.getReplicatedToAllIndex());
}
Also used : CaptureSnapshotReply(org.opendaylight.controller.cluster.raft.base.messages.CaptureSnapshotReply) Leader(org.opendaylight.controller.cluster.raft.behaviors.Leader) SimpleReplicatedLogEntry(org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry) DataPersistenceProvider(org.opendaylight.controller.cluster.DataPersistenceProvider) FiniteDuration(scala.concurrent.duration.FiniteDuration) ByteString(com.google.protobuf.ByteString) MockPayload(org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload) Test(org.junit.Test)

Example 5 with DataPersistenceProvider

use of org.opendaylight.controller.cluster.DataPersistenceProvider in project controller by opendaylight.

the class RaftActorTest method testFakeSnapshotsForLeaderWithInInitiateSnapshots.

@Test
public void testFakeSnapshotsForLeaderWithInInitiateSnapshots() throws Exception {
    final String persistenceId = factory.generateActorId("leader-");
    final String follower1Id = factory.generateActorId("follower-");
    final String follower2Id = factory.generateActorId("follower-");
    final ActorRef followerActor1 = factory.createActor(MessageCollectorActor.props(), follower1Id);
    final ActorRef followerActor2 = factory.createActor(MessageCollectorActor.props(), follower2Id);
    DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
    config.setHeartBeatInterval(new FiniteDuration(1, TimeUnit.DAYS));
    config.setIsolatedLeaderCheckInterval(new FiniteDuration(1, TimeUnit.DAYS));
    DataPersistenceProvider dataPersistenceProvider = mock(DataPersistenceProvider.class);
    Map<String, String> peerAddresses = new HashMap<>();
    peerAddresses.put(follower1Id, followerActor1.path().toString());
    peerAddresses.put(follower2Id, followerActor2.path().toString());
    TestActorRef<MockRaftActor> mockActorRef = factory.createTestActor(MockRaftActor.props(persistenceId, peerAddresses, config, dataPersistenceProvider), persistenceId);
    MockRaftActor leaderActor = mockActorRef.underlyingActor();
    leaderActor.getRaftActorContext().setCommitIndex(9);
    leaderActor.getRaftActorContext().setLastApplied(9);
    leaderActor.getRaftActorContext().getTermInformation().update(1, persistenceId);
    leaderActor.waitForInitializeBehaviorComplete();
    Leader leader = new Leader(leaderActor.getRaftActorContext());
    leaderActor.setCurrentBehavior(leader);
    assertEquals(RaftState.Leader, leaderActor.getCurrentBehavior().state());
    // create 5 entries in the log
    MockRaftActorContext.MockReplicatedLogBuilder logBuilder = new MockRaftActorContext.MockReplicatedLogBuilder();
    leaderActor.getRaftActorContext().setReplicatedLog(logBuilder.createEntries(5, 10, 1).build());
    // set the snapshot index to 4 , 0 to 4 are snapshotted
    leaderActor.getRaftActorContext().getReplicatedLog().setSnapshotIndex(4);
    // setting replicatedToAllIndex = 9, for the log to clear
    leader.setReplicatedToAllIndex(9);
    assertEquals(5, leaderActor.getReplicatedLog().size());
    assertEquals(RaftState.Leader, leaderActor.getCurrentBehavior().state());
    leaderActor.onReceiveCommand(new AppendEntriesReply(follower1Id, 1, true, 9, 1, (short) 0));
    assertEquals(5, leaderActor.getReplicatedLog().size());
    assertEquals(RaftState.Leader, leaderActor.getCurrentBehavior().state());
    // set the 2nd follower nextIndex to 1 which has been snapshotted
    leaderActor.onReceiveCommand(new AppendEntriesReply(follower2Id, 1, true, 0, 1, (short) 0));
    assertEquals(5, leaderActor.getReplicatedLog().size());
    assertEquals(RaftState.Leader, leaderActor.getCurrentBehavior().state());
    // simulate a real snapshot
    leaderActor.onReceiveCommand(SendHeartBeat.INSTANCE);
    assertEquals(5, leaderActor.getReplicatedLog().size());
    assertEquals(String.format("expected to be Leader but was %s. Current Leader = %s ", leaderActor.getCurrentBehavior().state(), leaderActor.getLeaderId()), RaftState.Leader, leaderActor.getCurrentBehavior().state());
    // reply from a slow follower does not initiate a fake snapshot
    leaderActor.onReceiveCommand(new AppendEntriesReply(follower2Id, 1, true, 9, 1, (short) 0));
    assertEquals("Fake snapshot should not happen when Initiate is in progress", 5, leaderActor.getReplicatedLog().size());
    ByteString snapshotBytes = fromObject(Arrays.asList(new MockRaftActorContext.MockPayload("foo-0"), new MockRaftActorContext.MockPayload("foo-1"), new MockRaftActorContext.MockPayload("foo-2"), new MockRaftActorContext.MockPayload("foo-3"), new MockRaftActorContext.MockPayload("foo-4")));
    leaderActor.onReceiveCommand(new CaptureSnapshotReply(ByteState.of(snapshotBytes.toByteArray()), java.util.Optional.empty()));
    assertTrue(leaderActor.getRaftActorContext().getSnapshotManager().isCapturing());
    assertEquals("Real snapshot didn't clear the log till replicatedToAllIndex", 0, leaderActor.getReplicatedLog().size());
    // reply from a slow follower after should not raise errors
    leaderActor.onReceiveCommand(new AppendEntriesReply(follower2Id, 1, true, 5, 1, (short) 0));
    assertEquals(0, leaderActor.getReplicatedLog().size());
}
Also used : CaptureSnapshotReply(org.opendaylight.controller.cluster.raft.base.messages.CaptureSnapshotReply) Leader(org.opendaylight.controller.cluster.raft.behaviors.Leader) HashMap(java.util.HashMap) ActorRef(akka.actor.ActorRef) TestActorRef(akka.testkit.TestActorRef) ByteString(com.google.protobuf.ByteString) FiniteDuration(scala.concurrent.duration.FiniteDuration) ByteString(com.google.protobuf.ByteString) MockPayload(org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload) AppendEntriesReply(org.opendaylight.controller.cluster.raft.messages.AppendEntriesReply) DataPersistenceProvider(org.opendaylight.controller.cluster.DataPersistenceProvider) Test(org.junit.Test)

Aggregations

DataPersistenceProvider (org.opendaylight.controller.cluster.DataPersistenceProvider)12 ByteString (com.google.protobuf.ByteString)10 Test (org.junit.Test)10 FiniteDuration (scala.concurrent.duration.FiniteDuration)9 MockPayload (org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload)7 SimpleReplicatedLogEntry (org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry)6 Leader (org.opendaylight.controller.cluster.raft.behaviors.Leader)5 ActorRef (akka.actor.ActorRef)4 TestActorRef (akka.testkit.TestActorRef)4 CaptureSnapshotReply (org.opendaylight.controller.cluster.raft.base.messages.CaptureSnapshotReply)4 HashMap (java.util.HashMap)3 AppendEntriesReply (org.opendaylight.controller.cluster.raft.messages.AppendEntriesReply)3 Procedure (akka.japi.Procedure)2 DelegatingPersistentDataProvider (org.opendaylight.controller.cluster.DelegatingPersistentDataProvider)2 SaveSnapshotSuccess (akka.persistence.SaveSnapshotSuccess)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 NonPersistentDataProvider (org.opendaylight.controller.cluster.NonPersistentDataProvider)1 PersistentDataProvider (org.opendaylight.controller.cluster.PersistentDataProvider)1 MetadataShardDataTreeSnapshot (org.opendaylight.controller.cluster.datastore.persisted.MetadataShardDataTreeSnapshot)1