use of org.opendaylight.controller.cluster.raft.behaviors.RaftActorBehavior in project controller by opendaylight.
the class RaftActor method updateConfigParams.
protected void updateConfigParams(final ConfigParams configParams) {
// obtain the RaftPolicy for oldConfigParams and the updated one.
String oldRaftPolicy = context.getConfigParams().getCustomRaftPolicyImplementationClass();
String newRaftPolicy = configParams.getCustomRaftPolicyImplementationClass();
LOG.debug("{}: RaftPolicy used with prev.config {}, RaftPolicy used with newConfig {}", persistenceId(), oldRaftPolicy, newRaftPolicy);
context.setConfigParams(configParams);
if (!Objects.equals(oldRaftPolicy, newRaftPolicy)) {
// The RaftPolicy was modified. If the current behavior is Follower then re-initialize to Follower
// but transfer the previous leaderId so it doesn't immediately try to schedule an election. This
// avoids potential disruption. Otherwise, switch to Follower normally.
RaftActorBehavior behavior = getCurrentBehavior();
if (behavior != null && behavior.state() == RaftState.Follower) {
String previousLeaderId = behavior.getLeaderId();
short previousLeaderPayloadVersion = behavior.getLeaderPayloadVersion();
LOG.debug("{}: Re-initializing to Follower with previous leaderId {}", persistenceId(), previousLeaderId);
changeCurrentBehavior(new Follower(context, previousLeaderId, previousLeaderPayloadVersion));
} else {
initializeBehavior();
}
}
}
use of org.opendaylight.controller.cluster.raft.behaviors.RaftActorBehavior in project controller by opendaylight.
the class RaftActor method onShutDown.
private void onShutDown() {
LOG.debug("{}: onShutDown", persistenceId());
if (shuttingDown) {
return;
}
shuttingDown = true;
final RaftActorBehavior currentBehavior = context.getCurrentBehavior();
switch(currentBehavior.state()) {
case Leader:
case PreLeader:
// Fall-through to more work
break;
default:
// For non-leaders shutdown is a no-op
self().tell(PoisonPill.getInstance(), self());
return;
}
if (context.hasFollowers()) {
initiateLeadershipTransfer(new RaftActorLeadershipTransferCohort.OnComplete() {
@Override
public void onSuccess(final ActorRef raftActorRef) {
LOG.debug("{}: leader transfer succeeded - sending PoisonPill", persistenceId());
raftActorRef.tell(PoisonPill.getInstance(), raftActorRef);
}
@Override
public void onFailure(final ActorRef raftActorRef) {
LOG.debug("{}: leader transfer failed - sending PoisonPill", persistenceId());
raftActorRef.tell(PoisonPill.getInstance(), raftActorRef);
}
}, null, TimeUnit.MILLISECONDS.convert(2, TimeUnit.SECONDS));
} else {
pauseLeader(new TimedRunnable(context.getConfigParams().getElectionTimeOutInterval(), this) {
@Override
protected void doRun() {
self().tell(PoisonPill.getInstance(), self());
}
@Override
protected void doCancel() {
self().tell(PoisonPill.getInstance(), self());
}
});
}
}
use of org.opendaylight.controller.cluster.raft.behaviors.RaftActorBehavior in project controller by opendaylight.
the class RaftActorServerConfigurationSupportTest method testRemoveServer.
@Test
public void testRemoveServer() throws Exception {
LOG.info("testRemoveServer starting");
DefaultConfigParamsImpl configParams = new DefaultConfigParamsImpl();
configParams.setHeartBeatInterval(new FiniteDuration(1, TimeUnit.DAYS));
configParams.setCustomRaftPolicyImplementationClass(DisableElectionsRaftPolicy.class.getName());
final String follower1ActorId = actorFactory.generateActorId(FOLLOWER_ID);
final String follower1ActorPath = actorFactory.createTestActorPath(follower1ActorId);
final String follower2ActorId = actorFactory.generateActorId(FOLLOWER_ID2);
final String follower2ActorPath = actorFactory.createTestActorPath(follower2ActorId);
RaftActorContext initialActorContext = new MockRaftActorContext();
final String downNodeId = "downNode";
TestActorRef<MockLeaderRaftActor> leaderActor = actorFactory.createTestActor(MockLeaderRaftActor.props(ImmutableMap.of(FOLLOWER_ID, follower1ActorPath, FOLLOWER_ID2, follower2ActorPath, downNodeId, ""), initialActorContext).withDispatcher(Dispatchers.DefaultDispatcherId()), actorFactory.generateActorId(LEADER_ID));
final ActorRef leaderCollector = newLeaderCollectorActor(leaderActor.underlyingActor());
ActorRef follower1Collector = actorFactory.createActor(MessageCollectorActor.props(), actorFactory.generateActorId("collector"));
final TestActorRef<CollectingMockRaftActor> follower1Actor = actorFactory.createTestActor(CollectingMockRaftActor.props(FOLLOWER_ID, ImmutableMap.of(LEADER_ID, leaderActor.path().toString(), FOLLOWER_ID2, follower2ActorPath, downNodeId, ""), configParams, NO_PERSISTENCE, follower1Collector).withDispatcher(Dispatchers.DefaultDispatcherId()), follower1ActorId);
ActorRef follower2Collector = actorFactory.createActor(MessageCollectorActor.props(), actorFactory.generateActorId("collector"));
final TestActorRef<CollectingMockRaftActor> follower2Actor = actorFactory.createTestActor(CollectingMockRaftActor.props(FOLLOWER_ID2, ImmutableMap.of(LEADER_ID, leaderActor.path().toString(), FOLLOWER_ID, follower1ActorPath, downNodeId, ""), configParams, NO_PERSISTENCE, follower2Collector).withDispatcher(Dispatchers.DefaultDispatcherId()), follower2ActorId);
leaderActor.underlyingActor().waitForInitializeBehaviorComplete();
follower1Actor.underlyingActor().waitForInitializeBehaviorComplete();
follower2Actor.underlyingActor().waitForInitializeBehaviorComplete();
leaderActor.tell(new RemoveServer(FOLLOWER_ID), testKit.getRef());
RemoveServerReply removeServerReply = testKit.expectMsgClass(testKit.duration("5 seconds"), RemoveServerReply.class);
assertEquals("getStatus", ServerChangeStatus.OK, removeServerReply.getStatus());
ApplyState applyState = MessageCollectorActor.expectFirstMatching(leaderCollector, ApplyState.class);
assertEquals(0L, applyState.getReplicatedLogEntry().getIndex());
verifyServerConfigurationPayloadEntry(leaderActor.underlyingActor().getRaftActorContext().getReplicatedLog(), votingServer(LEADER_ID), votingServer(FOLLOWER_ID2), votingServer(downNodeId));
applyState = MessageCollectorActor.expectFirstMatching(follower2Collector, ApplyState.class);
assertEquals(0L, applyState.getReplicatedLogEntry().getIndex());
verifyServerConfigurationPayloadEntry(leaderActor.underlyingActor().getRaftActorContext().getReplicatedLog(), votingServer(LEADER_ID), votingServer(FOLLOWER_ID2), votingServer(downNodeId));
RaftActorBehavior currentBehavior = leaderActor.underlyingActor().getCurrentBehavior();
assertTrue("Expected Leader", currentBehavior instanceof Leader);
assertEquals("Follower ids size", 2, ((Leader) currentBehavior).getFollowerIds().size());
MessageCollectorActor.expectFirstMatching(follower1Collector, ServerRemoved.class);
LOG.info("testRemoveServer ending");
}
use of org.opendaylight.controller.cluster.raft.behaviors.RaftActorBehavior in project controller by opendaylight.
the class RaftActorTest method testUpdateConfigParam.
@Test
public void testUpdateConfigParam() throws Exception {
DefaultConfigParamsImpl emptyConfig = new DefaultConfigParamsImpl();
String persistenceId = factory.generateActorId("follower-");
ImmutableMap<String, String> peerAddresses = ImmutableMap.<String, String>builder().put("member1", "address").build();
DataPersistenceProvider dataPersistenceProvider = mock(DataPersistenceProvider.class);
TestActorRef<MockRaftActor> actorRef = factory.createTestActor(MockRaftActor.props(persistenceId, peerAddresses, emptyConfig, dataPersistenceProvider), persistenceId);
MockRaftActor mockRaftActor = actorRef.underlyingActor();
mockRaftActor.waitForInitializeBehaviorComplete();
RaftActorBehavior behavior = mockRaftActor.getCurrentBehavior();
mockRaftActor.updateConfigParams(emptyConfig);
assertSame("Same Behavior", behavior, mockRaftActor.getCurrentBehavior());
assertEquals("Behavior State", RaftState.Follower, mockRaftActor.getCurrentBehavior().state());
DefaultConfigParamsImpl disableConfig = new DefaultConfigParamsImpl();
disableConfig.setCustomRaftPolicyImplementationClass("org.opendaylight.controller.cluster.raft.policy.DisableElectionsRaftPolicy");
mockRaftActor.updateConfigParams(disableConfig);
assertNotSame("Different Behavior", behavior, mockRaftActor.getCurrentBehavior());
assertEquals("Behavior State", RaftState.Follower, mockRaftActor.getCurrentBehavior().state());
behavior = mockRaftActor.getCurrentBehavior();
mockRaftActor.updateConfigParams(disableConfig);
assertSame("Same Behavior", behavior, mockRaftActor.getCurrentBehavior());
assertEquals("Behavior State", RaftState.Follower, mockRaftActor.getCurrentBehavior().state());
DefaultConfigParamsImpl defaultConfig = new DefaultConfigParamsImpl();
defaultConfig.setCustomRaftPolicyImplementationClass("org.opendaylight.controller.cluster.raft.policy.DefaultRaftPolicy");
mockRaftActor.updateConfigParams(defaultConfig);
assertNotSame("Different Behavior", behavior, mockRaftActor.getCurrentBehavior());
assertEquals("Behavior State", RaftState.Follower, mockRaftActor.getCurrentBehavior().state());
behavior = mockRaftActor.getCurrentBehavior();
mockRaftActor.updateConfigParams(defaultConfig);
assertSame("Same Behavior", behavior, mockRaftActor.getCurrentBehavior());
assertEquals("Behavior State", RaftState.Follower, mockRaftActor.getCurrentBehavior().state());
}
use of org.opendaylight.controller.cluster.raft.behaviors.RaftActorBehavior in project controller by opendaylight.
the class RaftActor method handleBehaviorChange.
private void handleBehaviorChange(final BehaviorState oldBehaviorState, final RaftActorBehavior currentBehavior) {
RaftActorBehavior oldBehavior = oldBehaviorState.getBehavior();
if (oldBehavior != currentBehavior) {
onStateChanged();
}
String lastLeaderId = oldBehavior == null ? null : oldBehaviorState.getLastLeaderId();
String lastValidLeaderId = oldBehavior == null ? null : oldBehaviorState.getLastValidLeaderId();
String oldBehaviorStateName = oldBehavior == null ? null : oldBehavior.state().name();
// it can happen that the state has not changed but the leader has changed.
Optional<ActorRef> roleChangeNotifier = getRoleChangeNotifier();
if (!Objects.equals(lastLeaderId, currentBehavior.getLeaderId()) || oldBehaviorState.getLeaderPayloadVersion() != currentBehavior.getLeaderPayloadVersion()) {
if (roleChangeNotifier.isPresent()) {
roleChangeNotifier.get().tell(newLeaderStateChanged(getId(), currentBehavior.getLeaderId(), currentBehavior.getLeaderPayloadVersion()), getSelf());
}
onLeaderChanged(lastValidLeaderId, currentBehavior.getLeaderId());
RaftActorLeadershipTransferCohort leadershipTransferInProgress = context.getRaftActorLeadershipTransferCohort();
if (leadershipTransferInProgress != null) {
leadershipTransferInProgress.onNewLeader(currentBehavior.getLeaderId());
}
serverConfigurationSupport.onNewLeader(currentBehavior.getLeaderId());
}
if (roleChangeNotifier.isPresent() && (oldBehavior == null || oldBehavior.state() != currentBehavior.state())) {
roleChangeNotifier.get().tell(new RoleChanged(getId(), oldBehaviorStateName, currentBehavior.state().name()), getSelf());
}
}
Aggregations