use of org.opendaylight.controller.cluster.raft.base.messages.LeaderTransitioning in project controller by opendaylight.
the class LeadershipTransferIntegrationTest method sendShutDownToLeaderAndVerifyLeadershipTransferToFollower1.
private void sendShutDownToLeaderAndVerifyLeadershipTransferToFollower1() throws Exception {
testLog.info("sendShutDownToLeaderAndVerifyLeadershipTransferToFollower1 starting");
clearMessages(leaderNotifierActor);
clearMessages(follower1NotifierActor);
clearMessages(follower2NotifierActor);
clearMessages(follower3NotifierActor);
// Simulate a delay for follower2 in receiving the LeaderTransitioning message with null leader id.
final TestRaftActor follower2Instance = follower2Actor.underlyingActor();
follower2Instance.startDropMessages(LeaderTransitioning.class);
FiniteDuration duration = FiniteDuration.create(5, TimeUnit.SECONDS);
final Future<Boolean> stopFuture = Patterns.gracefulStop(leaderActor, duration, Shutdown.INSTANCE);
verifyRaftState(follower1Actor, RaftState.Leader);
Boolean stopped = Await.result(stopFuture, duration);
assertEquals("Stopped", Boolean.TRUE, stopped);
// Re-enable LeaderTransitioning messages to follower2.
final LeaderTransitioning leaderTransitioning = expectFirstMatching(follower2CollectorActor, LeaderTransitioning.class);
follower2Instance.stopDropMessages(LeaderTransitioning.class);
follower2Instance.stopDropMessages(AppendEntries.class);
ApplyState applyState = expectFirstMatching(follower2CollectorActor, ApplyState.class);
assertEquals("Apply sate index", 0, applyState.getReplicatedLogEntry().getIndex());
// Now send the LeaderTransitioning to follower2 after it has received AppendEntries from the new leader.
follower2Actor.tell(leaderTransitioning, ActorRef.noSender());
verifyLeaderStateChangedMessages(leaderNotifierActor, null, follower1Id);
verifyLeaderStateChangedMessages(follower1NotifierActor, null, follower1Id);
// follower2 should only get 1 LeaderStateChanged with the new leaderId - the LeaderTransitioning message
// should not generate a LeaderStateChanged with null leaderId since it arrived after the new leaderId was set.
verifyLeaderStateChangedMessages(follower2NotifierActor, follower1Id);
verifyLeaderStateChangedMessages(follower3NotifierActor, null, follower1Id);
testLog.info("sendShutDownToLeaderAndVerifyLeadershipTransferToFollower1 ending");
}
use of org.opendaylight.controller.cluster.raft.base.messages.LeaderTransitioning in project controller by opendaylight.
the class RaftActorTest method testLeaderTransitioning.
@Test
public void testLeaderTransitioning() throws Exception {
TEST_LOG.info("testLeaderTransitioning starting");
ActorRef notifierActor = factory.createActor(MessageCollectorActor.props());
DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
config.setCustomRaftPolicyImplementationClass(DisableElectionsRaftPolicy.class.getName());
String persistenceId = factory.generateActorId("test-actor-");
TestActorRef<MockRaftActor> raftActorRef = factory.createTestActor(MockRaftActor.builder().id(persistenceId).config(config).roleChangeNotifier(notifierActor).props().withDispatcher(Dispatchers.DefaultDispatcherId()), persistenceId);
MockRaftActor mockRaftActor = raftActorRef.underlyingActor();
mockRaftActor.waitForInitializeBehaviorComplete();
raftActorRef.tell(new AppendEntries(1L, "leader", 0L, 1L, Collections.<ReplicatedLogEntry>emptyList(), 0L, -1L, (short) 1), ActorRef.noSender());
LeaderStateChanged leaderStateChange = MessageCollectorActor.expectFirstMatching(notifierActor, LeaderStateChanged.class);
assertEquals("getLeaderId", "leader", leaderStateChange.getLeaderId());
MessageCollectorActor.clearMessages(notifierActor);
raftActorRef.tell(new LeaderTransitioning("leader"), ActorRef.noSender());
leaderStateChange = MessageCollectorActor.expectFirstMatching(notifierActor, LeaderStateChanged.class);
assertEquals("getMemberId", persistenceId, leaderStateChange.getMemberId());
assertEquals("getLeaderId", null, leaderStateChange.getLeaderId());
TEST_LOG.info("testLeaderTransitioning ending");
}
use of org.opendaylight.controller.cluster.raft.base.messages.LeaderTransitioning in project controller by opendaylight.
the class RaftActor method handleCommand.
/**
* Handles a message.
*
* @deprecated This method is not final for testing purposes. DO NOT OVERRIDE IT, override
* {@link #handleNonRaftCommand(Object)} instead.
*/
@Deprecated
@Override
protected // FIXME: make this method final once our unit tests do not need to override it
void handleCommand(final Object message) {
if (serverConfigurationSupport.handleMessage(message, getSender())) {
return;
}
if (snapshotSupport.handleSnapshotMessage(message, getSender())) {
return;
}
if (message instanceof ApplyState) {
ApplyState applyState = (ApplyState) message;
if (!hasFollowers()) {
// for single node, the capture should happen after the apply state
// as we delete messages from the persistent journal which have made it to the snapshot
// capturing the snapshot before applying makes the persistent journal and snapshot out of sync
// and recovery shows data missing
context.getReplicatedLog().captureSnapshotIfReady(applyState.getReplicatedLogEntry());
context.getSnapshotManager().trimLog(context.getLastApplied());
}
possiblyHandleBehaviorMessage(message);
} else if (message instanceof ApplyJournalEntries) {
ApplyJournalEntries applyEntries = (ApplyJournalEntries) message;
LOG.debug("{}: Persisting ApplyJournalEntries with index={}", persistenceId(), applyEntries.getToIndex());
persistence().persistAsync(applyEntries, NoopProcedure.instance());
} else if (message instanceof FindLeader) {
getSender().tell(new FindLeaderReply(getLeaderAddress()), getSelf());
} else if (message instanceof GetOnDemandRaftState) {
onGetOnDemandRaftStats();
} else if (message instanceof InitiateCaptureSnapshot) {
captureSnapshot();
} else if (message instanceof SwitchBehavior) {
switchBehavior((SwitchBehavior) message);
} else if (message instanceof LeaderTransitioning) {
onLeaderTransitioning((LeaderTransitioning) message);
} else if (message instanceof Shutdown) {
onShutDown();
} else if (message instanceof Runnable) {
((Runnable) message).run();
} else if (message instanceof NoopPayload) {
persistData(null, null, (NoopPayload) message, false);
} else if (message instanceof RequestLeadership) {
onRequestLeadership((RequestLeadership) message);
} else if (!possiblyHandleBehaviorMessage(message)) {
handleNonRaftCommand(message);
}
}
use of org.opendaylight.controller.cluster.raft.base.messages.LeaderTransitioning in project controller by opendaylight.
the class RaftActorLeadershipTransferCohort method init.
void init() {
RaftActorContext context = raftActor.getRaftActorContext();
RaftActorBehavior currentBehavior = raftActor.getCurrentBehavior();
transferTimer.start();
Optional<ActorRef> roleChangeNotifier = raftActor.getRoleChangeNotifier();
if (roleChangeNotifier.isPresent()) {
roleChangeNotifier.get().tell(raftActor.newLeaderStateChanged(context.getId(), null, currentBehavior.getLeaderPayloadVersion()), raftActor.self());
}
for (String peerId : context.getPeerIds()) {
ActorSelection followerActor = context.getPeerActorSelection(peerId);
if (followerActor != null) {
followerActor.tell(new LeaderTransitioning(context.getId()), context.getActor());
}
}
raftActor.pauseLeader(new TimedRunnable(context.getConfigParams().getElectionTimeOutInterval(), raftActor) {
@Override
protected void doRun() {
LOG.debug("{}: pauseLeader successfully completed - doing transfer", raftActor.persistenceId());
doTransfer();
}
@Override
protected void doCancel() {
LOG.debug("{}: pauseLeader timed out - continuing with transfer", raftActor.persistenceId());
doTransfer();
}
});
}
Aggregations