Search in sources :

Example 1 with RaftActorBehavior

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();
        }
    }
}
Also used : RaftActorBehavior(org.opendaylight.controller.cluster.raft.behaviors.RaftActorBehavior) AbstractRaftActorBehavior(org.opendaylight.controller.cluster.raft.behaviors.AbstractRaftActorBehavior) Follower(org.opendaylight.controller.cluster.raft.behaviors.Follower)

Example 2 with RaftActorBehavior

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());
            }
        });
    }
}
Also used : ActorRef(akka.actor.ActorRef) RaftActorBehavior(org.opendaylight.controller.cluster.raft.behaviors.RaftActorBehavior) AbstractRaftActorBehavior(org.opendaylight.controller.cluster.raft.behaviors.AbstractRaftActorBehavior)

Example 3 with RaftActorBehavior

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");
}
Also used : AbstractLeader(org.opendaylight.controller.cluster.raft.behaviors.AbstractLeader) Leader(org.opendaylight.controller.cluster.raft.behaviors.Leader) ActorRef(akka.actor.ActorRef) TestActorRef(akka.testkit.TestActorRef) RaftActorBehavior(org.opendaylight.controller.cluster.raft.behaviors.RaftActorBehavior) FiniteDuration(scala.concurrent.duration.FiniteDuration) DisableElectionsRaftPolicy(org.opendaylight.controller.cluster.raft.policy.DisableElectionsRaftPolicy) RemoveServer(org.opendaylight.controller.cluster.raft.messages.RemoveServer) ApplyState(org.opendaylight.controller.cluster.raft.base.messages.ApplyState) RemoveServerReply(org.opendaylight.controller.cluster.raft.messages.RemoveServerReply) Test(org.junit.Test)

Example 4 with RaftActorBehavior

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());
}
Also used : DataPersistenceProvider(org.opendaylight.controller.cluster.DataPersistenceProvider) RaftActorBehavior(org.opendaylight.controller.cluster.raft.behaviors.RaftActorBehavior) ByteString(com.google.protobuf.ByteString) Test(org.junit.Test)

Example 5 with RaftActorBehavior

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());
    }
}
Also used : ActorRef(akka.actor.ActorRef) RaftActorBehavior(org.opendaylight.controller.cluster.raft.behaviors.RaftActorBehavior) AbstractRaftActorBehavior(org.opendaylight.controller.cluster.raft.behaviors.AbstractRaftActorBehavior) RoleChanged(org.opendaylight.controller.cluster.notifications.RoleChanged)

Aggregations

RaftActorBehavior (org.opendaylight.controller.cluster.raft.behaviors.RaftActorBehavior)10 AbstractRaftActorBehavior (org.opendaylight.controller.cluster.raft.behaviors.AbstractRaftActorBehavior)6 ActorRef (akka.actor.ActorRef)4 VisibleForTesting (com.google.common.annotations.VisibleForTesting)2 Test (org.junit.Test)2 AbstractLeader (org.opendaylight.controller.cluster.raft.behaviors.AbstractLeader)2 Leader (org.opendaylight.controller.cluster.raft.behaviors.Leader)2 ActorSelection (akka.actor.ActorSelection)1 TestActorRef (akka.testkit.TestActorRef)1 ByteString (com.google.protobuf.ByteString)1 HashMap (java.util.HashMap)1 DataPersistenceProvider (org.opendaylight.controller.cluster.DataPersistenceProvider)1 RoleChanged (org.opendaylight.controller.cluster.notifications.RoleChanged)1 ApplyState (org.opendaylight.controller.cluster.raft.base.messages.ApplyState)1 LeaderTransitioning (org.opendaylight.controller.cluster.raft.base.messages.LeaderTransitioning)1 Follower (org.opendaylight.controller.cluster.raft.behaviors.Follower)1 FollowerInfo (org.opendaylight.controller.cluster.raft.client.messages.FollowerInfo)1 GetOnDemandRaftState (org.opendaylight.controller.cluster.raft.client.messages.GetOnDemandRaftState)1 OnDemandRaftState (org.opendaylight.controller.cluster.raft.client.messages.OnDemandRaftState)1 RemoveServer (org.opendaylight.controller.cluster.raft.messages.RemoveServer)1