use of org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload 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()));
}
use of org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload 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()));
}
use of org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload in project controller by opendaylight.
the class RaftActorServerConfigurationSupportTest method verifyServerConfigurationPayloadEntry.
private static void verifyServerConfigurationPayloadEntry(ReplicatedLog log, ServerInfo... expected) {
ReplicatedLogEntry logEntry = log.get(log.lastIndex());
assertEquals("Last log entry payload class", ServerConfigurationPayload.class, logEntry.getData().getClass());
ServerConfigurationPayload payload = (ServerConfigurationPayload) logEntry.getData();
assertEquals("Server config", Sets.newHashSet(expected), Sets.newHashSet(payload.getServerConfig()));
}
use of org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload 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");
}
use of org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload in project controller by opendaylight.
the class RaftActorServerConfigurationSupportTest method testOnApplyState.
@Test
public void testOnApplyState() {
LOG.info("testOnApplyState starting");
DefaultConfigParamsImpl configParams = new DefaultConfigParamsImpl();
configParams.setHeartBeatInterval(new FiniteDuration(1, TimeUnit.DAYS));
TestActorRef<MockRaftActor> noLeaderActor = actorFactory.createTestActor(MockRaftActor.builder().id(LEADER_ID).peerAddresses(ImmutableMap.of(FOLLOWER_ID, followerActor.path().toString())).config(configParams).persistent(Optional.of(false)).props().withDispatcher(Dispatchers.DefaultDispatcherId()), actorFactory.generateActorId(LEADER_ID));
RaftActorServerConfigurationSupport support = new RaftActorServerConfigurationSupport(noLeaderActor.underlyingActor());
ReplicatedLogEntry serverConfigEntry = new SimpleReplicatedLogEntry(1, 1, new ServerConfigurationPayload(Collections.<ServerInfo>emptyList()));
boolean handled = support.handleMessage(new ApplyState(null, null, serverConfigEntry), ActorRef.noSender());
assertEquals("Message handled", true, handled);
ReplicatedLogEntry nonServerConfigEntry = new SimpleReplicatedLogEntry(1, 1, new MockRaftActorContext.MockPayload("1"));
handled = support.handleMessage(new ApplyState(null, null, nonServerConfigEntry), ActorRef.noSender());
assertEquals("Message handled", false, handled);
LOG.info("testOnApplyState ending");
}
Aggregations