Search in sources :

Example 1 with FindLeaderReply

use of org.opendaylight.controller.cluster.raft.client.messages.FindLeaderReply in project controller by opendaylight.

the class ShardTestKit method waitUntilNoLeader.

@SuppressWarnings("checkstyle:IllegalCatch")
public void waitUntilNoLeader(final ActorRef shard) {
    FiniteDuration duration = Duration.create(100, TimeUnit.MILLISECONDS);
    Object lastResponse = null;
    for (int i = 0; i < 20 * 5; i++) {
        Future<Object> future = Patterns.ask(shard, FindLeader.INSTANCE, new Timeout(duration));
        try {
            final Optional<String> maybeLeader = ((FindLeaderReply) Await.result(future, duration)).getLeaderActor();
            if (!maybeLeader.isPresent()) {
                return;
            }
            lastResponse = maybeLeader.get();
        } catch (TimeoutException e) {
            lastResponse = e;
        } catch (Exception e) {
            LOG.error("FindLeader failed", e);
            lastResponse = e;
        }
        Uninterruptibles.sleepUninterruptibly(50, TimeUnit.MILLISECONDS);
    }
    if (lastResponse instanceof Throwable) {
        throw (AssertionError) new AssertionError(String.format("Unexpected error occurred from FindLeader for shard %s", shard.path())).initCause((Throwable) lastResponse);
    }
    Assert.fail(String.format("Unexpected leader %s found for shard %s", lastResponse, shard.path()));
}
Also used : FindLeaderReply(org.opendaylight.controller.cluster.raft.client.messages.FindLeaderReply) Timeout(akka.util.Timeout) FiniteDuration(scala.concurrent.duration.FiniteDuration) TimeoutException(java.util.concurrent.TimeoutException) TimeoutException(java.util.concurrent.TimeoutException)

Example 2 with FindLeaderReply

use of org.opendaylight.controller.cluster.raft.client.messages.FindLeaderReply in project controller by opendaylight.

the class RaftActorTestKit method waitUntilLeader.

@SuppressWarnings("checkstyle:IllegalCatch")
public static void waitUntilLeader(ActorRef actorRef) {
    FiniteDuration duration = Duration.create(100, TimeUnit.MILLISECONDS);
    for (int i = 0; i < 20 * 5; i++) {
        Future<Object> future = Patterns.ask(actorRef, FindLeader.INSTANCE, new Timeout(duration));
        try {
            final Optional<String> maybeLeader = ((FindLeaderReply) Await.result(future, duration)).getLeaderActor();
            if (maybeLeader.isPresent()) {
                return;
            }
        } catch (Exception e) {
            LOG.error("FindLeader failed", e);
        }
        Uninterruptibles.sleepUninterruptibly(50, TimeUnit.MILLISECONDS);
    }
    Assert.fail("Leader not found for actorRef " + actorRef.path());
}
Also used : FindLeaderReply(org.opendaylight.controller.cluster.raft.client.messages.FindLeaderReply) Timeout(akka.util.Timeout) FiniteDuration(scala.concurrent.duration.FiniteDuration)

Example 3 with FindLeaderReply

use of org.opendaylight.controller.cluster.raft.client.messages.FindLeaderReply 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);
    }
}
Also used : InitiateCaptureSnapshot(org.opendaylight.controller.cluster.raft.base.messages.InitiateCaptureSnapshot) FindLeaderReply(org.opendaylight.controller.cluster.raft.client.messages.FindLeaderReply) Shutdown(org.opendaylight.controller.cluster.raft.client.messages.Shutdown) RequestLeadership(org.opendaylight.controller.cluster.raft.messages.RequestLeadership) FindLeader(org.opendaylight.controller.cluster.raft.client.messages.FindLeader) NoopPayload(org.opendaylight.controller.cluster.raft.persisted.NoopPayload) ApplyJournalEntries(org.opendaylight.controller.cluster.raft.persisted.ApplyJournalEntries) GetOnDemandRaftState(org.opendaylight.controller.cluster.raft.client.messages.GetOnDemandRaftState) LeaderTransitioning(org.opendaylight.controller.cluster.raft.base.messages.LeaderTransitioning) SwitchBehavior(org.opendaylight.controller.cluster.raft.base.messages.SwitchBehavior) ApplyState(org.opendaylight.controller.cluster.raft.base.messages.ApplyState)

Example 4 with FindLeaderReply

use of org.opendaylight.controller.cluster.raft.client.messages.FindLeaderReply in project controller by opendaylight.

the class ShardTest method testChangeListenerNotifiedWhenNotTheLeaderOnRegistration.

@SuppressWarnings("serial")
@Test
public void testChangeListenerNotifiedWhenNotTheLeaderOnRegistration() throws Exception {
    // This test tests the timing window in which a change listener is registered before the
    // shard becomes the leader. We verify that the listener is registered and notified of the
    // existing data when the shard becomes the leader.
    // For this test, we want to send the RegisterChangeListener message after the shard
    // has recovered from persistence and before it becomes the leader. So we subclass
    // Shard to override onReceiveCommand and, when the first ElectionTimeout is received,
    // we know that the shard has been initialized to a follower and has started the
    // election process. The following 2 CountDownLatches are used to coordinate the
    // ElectionTimeout with the sending of the RegisterChangeListener message.
    final CountDownLatch onFirstElectionTimeout = new CountDownLatch(1);
    final CountDownLatch onChangeListenerRegistered = new CountDownLatch(1);
    final Creator<Shard> creator = new Creator<Shard>() {

        boolean firstElectionTimeout = true;

        @Override
        public Shard create() throws Exception {
            // it does do a persist)
            return new Shard(newShardBuilder()) {

                @Override
                public void handleCommand(final Object message) {
                    if (message instanceof ElectionTimeout && firstElectionTimeout) {
                        // Got the first ElectionTimeout. We don't forward it to the
                        // base Shard yet until we've sent the RegisterChangeListener
                        // message. So we signal the onFirstElectionTimeout latch to tell
                        // the main thread to send the RegisterChangeListener message and
                        // start a thread to wait on the onChangeListenerRegistered latch,
                        // which the main thread signals after it has sent the message.
                        // After the onChangeListenerRegistered is triggered, we send the
                        // original ElectionTimeout message to proceed with the election.
                        firstElectionTimeout = false;
                        final ActorRef self = getSelf();
                        new Thread(() -> {
                            Uninterruptibles.awaitUninterruptibly(onChangeListenerRegistered, 5, TimeUnit.SECONDS);
                            self.tell(message, self);
                        }).start();
                        onFirstElectionTimeout.countDown();
                    } else {
                        super.handleCommand(message);
                    }
                }
            };
        }
    };
    setupInMemorySnapshotStore();
    final YangInstanceIdentifier path = TestModel.TEST_PATH;
    final MockDataChangeListener listener = new MockDataChangeListener(1);
    final ActorRef dclActor = actorFactory.createActor(DataChangeListener.props(listener, path), "testRegisterChangeListenerWhenNotLeaderInitially-DataChangeListener");
    final TestActorRef<Shard> shard = actorFactory.createTestActor(Props.create(new DelegatingShardCreator(creator)).withDispatcher(Dispatchers.DefaultDispatcherId()), "testRegisterChangeListenerWhenNotLeaderInitially");
    new ShardTestKit(getSystem()) {

        {
            // Wait until the shard receives the first ElectionTimeout
            // message.
            assertEquals("Got first ElectionTimeout", true, onFirstElectionTimeout.await(5, TimeUnit.SECONDS));
            // Now send the RegisterChangeListener and wait for the reply.
            shard.tell(new RegisterChangeListener(path, dclActor, AsyncDataBroker.DataChangeScope.SUBTREE, false), getRef());
            final RegisterDataTreeNotificationListenerReply reply = expectMsgClass(duration("5 seconds"), RegisterDataTreeNotificationListenerReply.class);
            assertNotNull("getListenerRegistrationPath", reply.getListenerRegistrationPath());
            // Sanity check - verify the shard is not the leader yet.
            shard.tell(FindLeader.INSTANCE, getRef());
            final FindLeaderReply findLeadeReply = expectMsgClass(duration("5 seconds"), FindLeaderReply.class);
            assertFalse("Expected the shard not to be the leader", findLeadeReply.getLeaderActor().isPresent());
            // Signal the onChangeListenerRegistered latch to tell the
            // thread above to proceed
            // with the election process.
            onChangeListenerRegistered.countDown();
            // Wait for the shard to become the leader and notify our
            // listener with the existing
            // data in the store.
            listener.waitForChangeEvents(path);
        }
    };
}
Also used : RegisterDataTreeNotificationListenerReply(org.opendaylight.controller.cluster.datastore.messages.RegisterDataTreeNotificationListenerReply) ElectionTimeout(org.opendaylight.controller.cluster.raft.base.messages.ElectionTimeout) ActorRef(akka.actor.ActorRef) TestActorRef(akka.testkit.TestActorRef) RegisterChangeListener(org.opendaylight.controller.cluster.datastore.messages.RegisterChangeListener) Creator(akka.japi.Creator) CountDownLatch(java.util.concurrent.CountDownLatch) YangInstanceIdentifier(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier) FindLeaderReply(org.opendaylight.controller.cluster.raft.client.messages.FindLeaderReply) MockDataChangeListener(org.opendaylight.controller.cluster.datastore.utils.MockDataChangeListener) Test(org.junit.Test)

Example 5 with FindLeaderReply

use of org.opendaylight.controller.cluster.raft.client.messages.FindLeaderReply in project controller by opendaylight.

the class ShardTest method testDataTreeChangeListenerNotifiedWhenNotTheLeaderOnRegistration.

@SuppressWarnings("serial")
@Test
public void testDataTreeChangeListenerNotifiedWhenNotTheLeaderOnRegistration() throws Exception {
    final CountDownLatch onFirstElectionTimeout = new CountDownLatch(1);
    final CountDownLatch onChangeListenerRegistered = new CountDownLatch(1);
    final Creator<Shard> creator = new Creator<Shard>() {

        boolean firstElectionTimeout = true;

        @Override
        public Shard create() throws Exception {
            return new Shard(newShardBuilder()) {

                @Override
                public void handleCommand(final Object message) {
                    if (message instanceof ElectionTimeout && firstElectionTimeout) {
                        firstElectionTimeout = false;
                        final ActorRef self = getSelf();
                        new Thread(() -> {
                            Uninterruptibles.awaitUninterruptibly(onChangeListenerRegistered, 5, TimeUnit.SECONDS);
                            self.tell(message, self);
                        }).start();
                        onFirstElectionTimeout.countDown();
                    } else {
                        super.handleCommand(message);
                    }
                }
            };
        }
    };
    setupInMemorySnapshotStore();
    final YangInstanceIdentifier path = TestModel.TEST_PATH;
    final MockDataTreeChangeListener listener = new MockDataTreeChangeListener(1);
    final ActorRef dclActor = actorFactory.createActor(DataTreeChangeListenerActor.props(listener, path), "testDataTreeChangeListenerNotifiedWhenNotTheLeaderOnRegistration-DataChangeListener");
    final TestActorRef<Shard> shard = actorFactory.createTestActor(Props.create(new DelegatingShardCreator(creator)).withDispatcher(Dispatchers.DefaultDispatcherId()), "testDataTreeChangeListenerNotifiedWhenNotTheLeaderOnRegistration");
    new ShardTestKit(getSystem()) {

        {
            assertEquals("Got first ElectionTimeout", true, onFirstElectionTimeout.await(5, TimeUnit.SECONDS));
            shard.tell(new RegisterDataTreeChangeListener(path, dclActor, false), getRef());
            final RegisterDataTreeNotificationListenerReply reply = expectMsgClass(duration("5 seconds"), RegisterDataTreeNotificationListenerReply.class);
            assertNotNull("getListenerRegistratioznPath", reply.getListenerRegistrationPath());
            shard.tell(FindLeader.INSTANCE, getRef());
            final FindLeaderReply findLeadeReply = expectMsgClass(duration("5 seconds"), FindLeaderReply.class);
            assertFalse("Expected the shard not to be the leader", findLeadeReply.getLeaderActor().isPresent());
            onChangeListenerRegistered.countDown();
            // TODO: investigate why we do not receive data chage events
            listener.waitForChangeEvents();
        }
    };
}
Also used : RegisterDataTreeNotificationListenerReply(org.opendaylight.controller.cluster.datastore.messages.RegisterDataTreeNotificationListenerReply) ElectionTimeout(org.opendaylight.controller.cluster.raft.base.messages.ElectionTimeout) ActorRef(akka.actor.ActorRef) TestActorRef(akka.testkit.TestActorRef) Creator(akka.japi.Creator) CountDownLatch(java.util.concurrent.CountDownLatch) YangInstanceIdentifier(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier) RegisterDataTreeChangeListener(org.opendaylight.controller.cluster.datastore.messages.RegisterDataTreeChangeListener) FindLeaderReply(org.opendaylight.controller.cluster.raft.client.messages.FindLeaderReply) MockDataTreeChangeListener(org.opendaylight.controller.cluster.datastore.utils.MockDataTreeChangeListener) Test(org.junit.Test)

Aggregations

FindLeaderReply (org.opendaylight.controller.cluster.raft.client.messages.FindLeaderReply)6 Timeout (akka.util.Timeout)3 FiniteDuration (scala.concurrent.duration.FiniteDuration)3 ActorRef (akka.actor.ActorRef)2 Creator (akka.japi.Creator)2 TestActorRef (akka.testkit.TestActorRef)2 CountDownLatch (java.util.concurrent.CountDownLatch)2 TimeoutException (java.util.concurrent.TimeoutException)2 Test (org.junit.Test)2 RegisterDataTreeNotificationListenerReply (org.opendaylight.controller.cluster.datastore.messages.RegisterDataTreeNotificationListenerReply)2 ElectionTimeout (org.opendaylight.controller.cluster.raft.base.messages.ElectionTimeout)2 YangInstanceIdentifier (org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier)2 RegisterChangeListener (org.opendaylight.controller.cluster.datastore.messages.RegisterChangeListener)1 RegisterDataTreeChangeListener (org.opendaylight.controller.cluster.datastore.messages.RegisterDataTreeChangeListener)1 MockDataChangeListener (org.opendaylight.controller.cluster.datastore.utils.MockDataChangeListener)1 MockDataTreeChangeListener (org.opendaylight.controller.cluster.datastore.utils.MockDataTreeChangeListener)1 ApplyState (org.opendaylight.controller.cluster.raft.base.messages.ApplyState)1 InitiateCaptureSnapshot (org.opendaylight.controller.cluster.raft.base.messages.InitiateCaptureSnapshot)1 LeaderTransitioning (org.opendaylight.controller.cluster.raft.base.messages.LeaderTransitioning)1 SwitchBehavior (org.opendaylight.controller.cluster.raft.base.messages.SwitchBehavior)1