Search in sources :

Example 11 with ServerInfo

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

the class NonVotingFollowerIntegrationTest method setupLeaderAndNonVotingFollower.

private void setupLeaderAndNonVotingFollower() {
    snapshotBatchCount = 100;
    int persistedTerm = 1;
    // Set up a persisted ServerConfigurationPayload with the leader voting and the follower non-voting.
    ServerConfigurationPayload persistedServerConfig = new ServerConfigurationPayload(Arrays.asList(new ServerInfo(leaderId, true), new ServerInfo(follower1Id, false)));
    SimpleReplicatedLogEntry persistedServerConfigEntry = new SimpleReplicatedLogEntry(0, persistedTerm, persistedServerConfig);
    InMemoryJournal.addEntry(leaderId, 1, new UpdateElectionTerm(persistedTerm, leaderId));
    InMemoryJournal.addEntry(leaderId, 2, persistedServerConfigEntry);
    InMemoryJournal.addEntry(follower1Id, 1, new UpdateElectionTerm(persistedTerm, leaderId));
    InMemoryJournal.addEntry(follower1Id, 2, persistedServerConfigEntry);
    DefaultConfigParamsImpl followerConfigParams = newFollowerConfigParams();
    follower1Actor = newTestRaftActor(follower1Id, follower1Builder.peerAddresses(ImmutableMap.of(leaderId, testActorPath(leaderId))).config(followerConfigParams).persistent(Optional.of(false)));
    peerAddresses = ImmutableMap.<String, String>builder().put(follower1Id, follower1Actor.path().toString()).build();
    leaderConfigParams = newLeaderConfigParams();
    leaderActor = newTestRaftActor(leaderId, TestRaftActor.newBuilder().peerAddresses(peerAddresses).config(leaderConfigParams).persistent(Optional.of(false)));
    followerInstance = follower1Actor.underlyingActor();
    follower1CollectorActor = followerInstance.collectorActor();
    leaderInstance = leaderActor.underlyingActor();
    leaderCollectorActor = leaderInstance.collectorActor();
    leaderContext = leaderInstance.getRaftActorContext();
    follower1Context = followerInstance.getRaftActorContext();
    waitUntilLeader(leaderActor);
    // Verify leader's context after startup
    currentTerm = persistedTerm + 1;
    assertEquals("Leader term", currentTerm, leaderContext.getTermInformation().getCurrentTerm());
    assertEquals("Leader server config", Sets.newHashSet(persistedServerConfig.getServerConfig()), Sets.newHashSet(leaderContext.getPeerServerInfo(true).getServerConfig()));
    assertEquals("Leader isVotingMember", true, leaderContext.isVotingMember());
    // Verify follower's context after startup
    MessageCollectorActor.expectFirstMatching(follower1CollectorActor, AppendEntries.class);
    assertEquals("Follower term", currentTerm, follower1Context.getTermInformation().getCurrentTerm());
    assertEquals("Follower server config", Sets.newHashSet(persistedServerConfig.getServerConfig()), Sets.newHashSet(follower1Context.getPeerServerInfo(true).getServerConfig()));
    assertEquals("FollowerisVotingMember", false, follower1Context.isVotingMember());
}
Also used : ServerConfigurationPayload(org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload) SimpleReplicatedLogEntry(org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry) ServerInfo(org.opendaylight.controller.cluster.raft.persisted.ServerInfo) UpdateElectionTerm(org.opendaylight.controller.cluster.raft.persisted.UpdateElectionTerm)

Example 12 with ServerInfo

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

the class RaftActorContextImplTest method testUpdatePeerIds.

@Test
public void testUpdatePeerIds() {
    RaftActorContextImpl context = new RaftActorContextImpl(actor, actor.underlyingActor().getContext(), "self", new ElectionTermImpl(createProvider(), "test", LOG), -1, -1, Maps.newHashMap(ImmutableMap.<String, String>of("peer1", "peerAddress1")), new DefaultConfigParamsImpl(), createProvider(), applyState -> {
    }, LOG);
    context.updatePeerIds(new ServerConfigurationPayload(Arrays.asList(new ServerInfo("self", false), new ServerInfo("peer2", true), new ServerInfo("peer3", false))));
    verifyPeerInfo(context, "peer1", null);
    verifyPeerInfo(context, "peer2", true);
    verifyPeerInfo(context, "peer3", false);
    assertEquals("isVotingMember", false, context.isVotingMember());
    context.updatePeerIds(new ServerConfigurationPayload(Arrays.asList(new ServerInfo("self", true), new ServerInfo("peer2", true), new ServerInfo("peer3", true))));
    verifyPeerInfo(context, "peer2", true);
    verifyPeerInfo(context, "peer3", true);
    assertEquals("isVotingMember", true, context.isVotingMember());
    context.updatePeerIds(new ServerConfigurationPayload(Arrays.asList(new ServerInfo("peer2", true), new ServerInfo("peer3", true))));
    verifyPeerInfo(context, "peer2", true);
    verifyPeerInfo(context, "peer3", true);
    assertEquals("isVotingMember", false, context.isVotingMember());
}
Also used : ServerConfigurationPayload(org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload) ServerInfo(org.opendaylight.controller.cluster.raft.persisted.ServerInfo) Matchers.anyString(org.mockito.Matchers.anyString) Test(org.junit.Test)

Example 13 with ServerInfo

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

the class RaftActorRecoverySupportTest method testServerConfigurationPayloadApplied.

@Test
public void testServerConfigurationPayloadApplied() {
    String follower1 = "follower1";
    String follower2 = "follower2";
    String follower3 = "follower3";
    context.addToPeers(follower1, null, VotingState.VOTING);
    context.addToPeers(follower2, null, VotingState.VOTING);
    // add new Server
    ServerConfigurationPayload obj = new ServerConfigurationPayload(Arrays.asList(new ServerInfo(localId, true), new ServerInfo(follower1, true), new ServerInfo(follower2, false), new ServerInfo(follower3, true)));
    sendMessageToSupport(new SimpleReplicatedLogEntry(0, 1, obj));
    // verify new peers
    assertTrue("Dynamic server configuration", context.isDynamicServerConfigurationInUse());
    assertEquals("New peer Ids", Sets.newHashSet(follower1, follower2, follower3), Sets.newHashSet(context.getPeerIds()));
    assertEquals("follower1 isVoting", true, context.getPeerInfo(follower1).isVoting());
    assertEquals("follower2 isVoting", false, context.getPeerInfo(follower2).isVoting());
    assertEquals("follower3 isVoting", true, context.getPeerInfo(follower3).isVoting());
    sendMessageToSupport(new ApplyJournalEntries(0));
    verify(mockCohort, never()).startLogRecoveryBatch(anyInt());
    verify(mockCohort, never()).appendRecoveredLogEntry(any(Payload.class));
    // remove existing follower1
    obj = new ServerConfigurationPayload(Arrays.asList(new ServerInfo(localId, true), new ServerInfo("follower2", true), new ServerInfo("follower3", true)));
    sendMessageToSupport(new SimpleReplicatedLogEntry(1, 1, obj));
    // verify new peers
    assertTrue("Dynamic server configuration", context.isDynamicServerConfigurationInUse());
    assertEquals("New peer Ids", Sets.newHashSet(follower2, follower3), Sets.newHashSet(context.getPeerIds()));
}
Also used : ServerConfigurationPayload(org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload) SimpleReplicatedLogEntry(org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry) ServerInfo(org.opendaylight.controller.cluster.raft.persisted.ServerInfo) ApplyJournalEntries(org.opendaylight.controller.cluster.raft.persisted.ApplyJournalEntries) MockPayload(org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload) ServerConfigurationPayload(org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload) Payload(org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payload) Test(org.junit.Test)

Example 14 with ServerInfo

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

the class RaftActorRecoverySupportTest method testServerConfigurationPayloadAppliedWithPersistenceDisabled.

@Test
public void testServerConfigurationPayloadAppliedWithPersistenceDisabled() {
    doReturn(false).when(mockPersistence).isRecoveryApplicable();
    String follower = "follower";
    ServerConfigurationPayload obj = new ServerConfigurationPayload(Arrays.asList(new ServerInfo(localId, true), new ServerInfo(follower, true)));
    sendMessageToSupport(new SimpleReplicatedLogEntry(0, 1, obj));
    // verify new peers
    assertEquals("New peer Ids", Sets.newHashSet(follower), Sets.newHashSet(context.getPeerIds()));
}
Also used : ServerConfigurationPayload(org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload) SimpleReplicatedLogEntry(org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry) ServerInfo(org.opendaylight.controller.cluster.raft.persisted.ServerInfo) Test(org.junit.Test)

Example 15 with ServerInfo

use of org.opendaylight.controller.cluster.raft.persisted.ServerInfo 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)

Aggregations

ServerInfo (org.opendaylight.controller.cluster.raft.persisted.ServerInfo)23 ServerConfigurationPayload (org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload)21 Test (org.junit.Test)17 SimpleReplicatedLogEntry (org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry)13 UpdateElectionTerm (org.opendaylight.controller.cluster.raft.persisted.UpdateElectionTerm)7 FiniteDuration (scala.concurrent.duration.FiniteDuration)5 ActorRef (akka.actor.ActorRef)4 TestActorRef (akka.testkit.TestActorRef)4 ArrayList (java.util.ArrayList)4 CoreMatchers.containsString (org.hamcrest.CoreMatchers.containsString)4 ApplySnapshot (org.opendaylight.controller.cluster.raft.base.messages.ApplySnapshot)4 ApplyState (org.opendaylight.controller.cluster.raft.base.messages.ApplyState)4 ChangeServersVotingStatus (org.opendaylight.controller.cluster.raft.messages.ChangeServersVotingStatus)4 InstallSnapshot (org.opendaylight.controller.cluster.raft.messages.InstallSnapshot)4 ServerChangeReply (org.opendaylight.controller.cluster.raft.messages.ServerChangeReply)4 ApplyJournalEntries (org.opendaylight.controller.cluster.raft.persisted.ApplyJournalEntries)3 Snapshot (org.opendaylight.controller.cluster.raft.persisted.Snapshot)3 Props (akka.actor.Props)2 UntypedActor (akka.actor.UntypedActor)2 Dispatchers (akka.dispatch.Dispatchers)2