Search in sources :

Example 1 with NoShardLeaderException

use of org.opendaylight.controller.cluster.datastore.exceptions.NoShardLeaderException in project controller by opendaylight.

the class ActorContext method findPrimaryShardAsync.

public Future<PrimaryShardInfo> findPrimaryShardAsync(final String shardName) {
    Future<PrimaryShardInfo> ret = primaryShardInfoCache.getIfPresent(shardName);
    if (ret != null) {
        return ret;
    }
    Future<Object> future = executeOperationAsync(shardManager, new FindPrimary(shardName, true), shardInitializationTimeout);
    return future.transform(new Mapper<Object, PrimaryShardInfo>() {

        @Override
        public PrimaryShardInfo checkedApply(Object response) throws UnknownMessageException {
            if (response instanceof RemotePrimaryShardFound) {
                LOG.debug("findPrimaryShardAsync received: {}", response);
                RemotePrimaryShardFound found = (RemotePrimaryShardFound) response;
                return onPrimaryShardFound(shardName, found.getPrimaryPath(), found.getPrimaryVersion(), null);
            } else if (response instanceof LocalPrimaryShardFound) {
                LOG.debug("findPrimaryShardAsync received: {}", response);
                LocalPrimaryShardFound found = (LocalPrimaryShardFound) response;
                return onPrimaryShardFound(shardName, found.getPrimaryPath(), DataStoreVersions.CURRENT_VERSION, found.getLocalShardDataTree());
            } else if (response instanceof NotInitializedException) {
                throw (NotInitializedException) response;
            } else if (response instanceof PrimaryNotFoundException) {
                throw (PrimaryNotFoundException) response;
            } else if (response instanceof NoShardLeaderException) {
                throw (NoShardLeaderException) response;
            }
            throw new UnknownMessageException(String.format("FindPrimary returned unkown response: %s", response));
        }
    }, FIND_PRIMARY_FAILURE_TRANSFORMER, getClientDispatcher());
}
Also used : PrimaryNotFoundException(org.opendaylight.controller.cluster.datastore.exceptions.PrimaryNotFoundException) UnknownMessageException(org.opendaylight.controller.cluster.datastore.exceptions.UnknownMessageException) NotInitializedException(org.opendaylight.controller.cluster.datastore.exceptions.NotInitializedException) RemotePrimaryShardFound(org.opendaylight.controller.cluster.datastore.messages.RemotePrimaryShardFound) NoShardLeaderException(org.opendaylight.controller.cluster.datastore.exceptions.NoShardLeaderException) FindPrimary(org.opendaylight.controller.cluster.datastore.messages.FindPrimary) LocalPrimaryShardFound(org.opendaylight.controller.cluster.datastore.messages.LocalPrimaryShardFound) PrimaryShardInfo(org.opendaylight.controller.cluster.datastore.messages.PrimaryShardInfo)

Example 2 with NoShardLeaderException

use of org.opendaylight.controller.cluster.datastore.exceptions.NoShardLeaderException in project controller by opendaylight.

the class DistributedDataStoreIntegrationTest method testTransactionCommitFailureWithNoShardLeader.

@SuppressWarnings("checkstyle:IllegalCatch")
private void testTransactionCommitFailureWithNoShardLeader(final boolean writeOnly, final String testName) throws Exception {
    new IntegrationTestKit(getSystem(), datastoreContextBuilder) {

        {
            final String shardName = "default";
            // We don't want the shard to become the leader so prevent shard
            // elections.
            datastoreContextBuilder.customRaftPolicyImplementation("org.opendaylight.controller.cluster.raft.policy.DisableElectionsRaftPolicy");
            // The ShardManager uses the election timeout for FindPrimary so
            // reset it low so it will timeout quickly.
            datastoreContextBuilder.shardHeartbeatIntervalInMillis(100).shardElectionTimeoutFactor(1).shardInitializationTimeout(200, TimeUnit.MILLISECONDS).frontendRequestTimeoutInSeconds(2);
            try (AbstractDataStore dataStore = setupAbstractDataStore(testParameter, testName, false, shardName)) {
                final Object result = dataStore.getActorContext().executeOperation(dataStore.getActorContext().getShardManager(), new FindLocalShard(shardName, true));
                assertTrue("Expected LocalShardFound. Actual: " + result, result instanceof LocalShardFound);
                // Create the write Tx.
                DOMStoreWriteTransaction writeTxToClose = null;
                try {
                    writeTxToClose = writeOnly ? dataStore.newWriteOnlyTransaction() : dataStore.newReadWriteTransaction();
                    final DOMStoreWriteTransaction writeTx = writeTxToClose;
                    assertNotNull("newReadWriteTransaction returned null", writeTx);
                    // Do some modifications and ready the Tx on a separate
                    // thread.
                    final AtomicReference<DOMStoreThreePhaseCommitCohort> txCohort = new AtomicReference<>();
                    final AtomicReference<Exception> caughtEx = new AtomicReference<>();
                    final CountDownLatch txReady = new CountDownLatch(1);
                    final Thread txThread = new Thread(() -> {
                        try {
                            writeTx.write(TestModel.JUNK_PATH, ImmutableNodes.containerNode(TestModel.JUNK_QNAME));
                            txCohort.set(writeTx.ready());
                        } catch (Exception e) {
                            caughtEx.set(e);
                        } finally {
                            txReady.countDown();
                        }
                    });
                    txThread.start();
                    // Wait for the Tx operations to complete.
                    boolean done = Uninterruptibles.awaitUninterruptibly(txReady, 5, TimeUnit.SECONDS);
                    if (caughtEx.get() != null) {
                        throw caughtEx.get();
                    }
                    assertEquals("Tx ready", true, done);
                    // exception cause.
                    try {
                        txCohort.get().canCommit().get(10, TimeUnit.SECONDS);
                        fail("Expected NoShardLeaderException");
                    } catch (final ExecutionException e) {
                        final String msg = "Unexpected exception: " + Throwables.getStackTraceAsString(e.getCause());
                        if (DistributedDataStore.class.equals(testParameter)) {
                            assertTrue(Throwables.getRootCause(e) instanceof NoShardLeaderException);
                        } else {
                            assertTrue(msg, Throwables.getRootCause(e) instanceof RequestTimeoutException);
                        }
                    }
                } finally {
                    try {
                        if (writeTxToClose != null) {
                            writeTxToClose.close();
                        }
                    } catch (Exception e) {
                    // FIXME TransactionProxy.close throws IllegalStateException:
                    // Transaction is ready, it cannot be closed
                    }
                }
            }
        }
    };
}
Also used : LocalShardFound(org.opendaylight.controller.cluster.datastore.messages.LocalShardFound) DOMStoreWriteTransaction(org.opendaylight.mdsal.dom.spi.store.DOMStoreWriteTransaction) FindLocalShard(org.opendaylight.controller.cluster.datastore.messages.FindLocalShard) AtomicReference(java.util.concurrent.atomic.AtomicReference) AddressFromURIString(akka.actor.AddressFromURIString) CountDownLatch(java.util.concurrent.CountDownLatch) DOMStoreThreePhaseCommitCohort(org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort) ReadFailedException(org.opendaylight.mdsal.common.api.ReadFailedException) NotInitializedException(org.opendaylight.controller.cluster.datastore.exceptions.NotInitializedException) TransactionChainClosedException(org.opendaylight.mdsal.common.api.TransactionChainClosedException) RequestTimeoutException(org.opendaylight.controller.cluster.access.client.RequestTimeoutException) NoShardLeaderException(org.opendaylight.controller.cluster.datastore.exceptions.NoShardLeaderException) IOException(java.io.IOException) TransactionCommitFailedException(org.opendaylight.mdsal.common.api.TransactionCommitFailedException) ExecutionException(java.util.concurrent.ExecutionException) NoShardLeaderException(org.opendaylight.controller.cluster.datastore.exceptions.NoShardLeaderException) RequestTimeoutException(org.opendaylight.controller.cluster.access.client.RequestTimeoutException) ExecutionException(java.util.concurrent.ExecutionException)

Example 3 with NoShardLeaderException

use of org.opendaylight.controller.cluster.datastore.exceptions.NoShardLeaderException in project controller by opendaylight.

the class DistributedDataStoreRemotingIntegrationTest method testTransactionWithIsolatedLeader.

@Test
public void testTransactionWithIsolatedLeader() throws Exception {
    // TODO remove when test passes also for ClientBackedDataStore
    Assume.assumeTrue(testParameter.equals(DistributedDataStore.class));
    // Set the isolated leader check interval high so we can control the switch to IsolatedLeader.
    leaderDatastoreContextBuilder.shardIsolatedLeaderCheckIntervalInMillis(10000000);
    final String testName = "testTransactionWithIsolatedLeader";
    initDatastoresWithCars(testName);
    // Tx that is submitted after the follower is stopped but before the leader transitions to IsolatedLeader.
    final DOMStoreWriteTransaction preIsolatedLeaderWriteTx = leaderDistributedDataStore.newWriteOnlyTransaction();
    preIsolatedLeaderWriteTx.write(CarsModel.BASE_PATH, CarsModel.emptyContainer());
    // Tx that is submitted after the leader transitions to IsolatedLeader.
    final DOMStoreWriteTransaction noShardLeaderWriteTx = leaderDistributedDataStore.newWriteOnlyTransaction();
    noShardLeaderWriteTx.write(CarsModel.BASE_PATH, CarsModel.emptyContainer());
    // Tx that is submitted after the follower is reinstated.
    final DOMStoreWriteTransaction successWriteTx = leaderDistributedDataStore.newWriteOnlyTransaction();
    successWriteTx.merge(CarsModel.BASE_PATH, CarsModel.emptyContainer());
    // Stop the follower
    followerTestKit.watch(followerDistributedDataStore.getActorContext().getShardManager());
    followerDistributedDataStore.close();
    followerTestKit.expectTerminated(followerDistributedDataStore.getActorContext().getShardManager());
    // Submit the preIsolatedLeaderWriteTx so it's pending
    final DOMStoreThreePhaseCommitCohort preIsolatedLeaderTxCohort = preIsolatedLeaderWriteTx.ready();
    // Change the isolated leader check interval low so it changes to IsolatedLeader.
    sendDatastoreContextUpdate(leaderDistributedDataStore, leaderDatastoreContextBuilder.shardIsolatedLeaderCheckIntervalInMillis(200));
    MemberNode.verifyRaftState(leaderDistributedDataStore, "cars", raftState -> assertEquals("getRaftState", "IsolatedLeader", raftState.getRaftState()));
    try {
        leaderTestKit.doCommit(noShardLeaderWriteTx.ready());
        fail("Expected NoShardLeaderException");
    } catch (final ExecutionException e) {
        assertEquals("getCause", NoShardLeaderException.class, Throwables.getRootCause(e).getClass());
    }
    sendDatastoreContextUpdate(leaderDistributedDataStore, leaderDatastoreContextBuilder.shardElectionTimeoutFactor(100));
    final DOMStoreThreePhaseCommitCohort successTxCohort = successWriteTx.ready();
    followerDistributedDataStore = followerTestKit.setupAbstractDataStore(testParameter, testName, MODULE_SHARDS_CARS_ONLY_1_2, false, CARS);
    leaderTestKit.doCommit(preIsolatedLeaderTxCohort);
    leaderTestKit.doCommit(successTxCohort);
}
Also used : DOMStoreWriteTransaction(org.opendaylight.mdsal.dom.spi.store.DOMStoreWriteTransaction) AddressFromURIString(akka.actor.AddressFromURIString) ExecutionException(java.util.concurrent.ExecutionException) DOMStoreThreePhaseCommitCohort(org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort) NoShardLeaderException(org.opendaylight.controller.cluster.datastore.exceptions.NoShardLeaderException) Test(org.junit.Test)

Example 4 with NoShardLeaderException

use of org.opendaylight.controller.cluster.datastore.exceptions.NoShardLeaderException in project controller by opendaylight.

the class LegacyDOMDataBrokerAdapterTest method testWriteOnlyTransaction.

@Test
public void testWriteOnlyTransaction() throws Exception {
    // Test successful write operations and submit
    DOMDataWriteTransaction tx = adapter.newWriteOnlyTransaction();
    tx.put(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH, dataNode);
    verify(mockWriteTx).write(TestModel.TEST_PATH, dataNode);
    tx.merge(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH, dataNode);
    verify(mockWriteTx).merge(TestModel.TEST_PATH, dataNode);
    tx.delete(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH);
    verify(mockWriteTx).delete(TestModel.TEST_PATH);
    CheckedFuture<Void, TransactionCommitFailedException> submitFuture = tx.submit();
    submitFuture.get(5, TimeUnit.SECONDS);
    InOrder inOrder = inOrder(mockCommitCohort);
    inOrder.verify(mockCommitCohort).canCommit();
    inOrder.verify(mockCommitCohort).preCommit();
    inOrder.verify(mockCommitCohort).commit();
    // Test cancel
    tx = adapter.newWriteOnlyTransaction();
    tx.put(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH, dataNode);
    tx.cancel();
    verify(mockWriteTx).close();
    // Test submit with OptimisticLockFailedException
    String errorMsg = "mock OptimisticLockFailedException";
    Throwable cause = new ConflictingModificationAppliedException(TestModel.TEST_PATH, "mock");
    doReturn(Futures.immediateFailedFuture(new org.opendaylight.mdsal.common.api.OptimisticLockFailedException(errorMsg, cause))).when(mockCommitCohort).canCommit();
    try {
        tx = adapter.newWriteOnlyTransaction();
        tx.put(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH, dataNode);
        submitFuture = tx.submit();
        submitFuture.checkedGet(5, TimeUnit.SECONDS);
        fail("Expected OptimisticLockFailedException");
    } catch (OptimisticLockFailedException e) {
        assertEquals("getMessage", errorMsg, e.getMessage());
        assertEquals("getCause", cause, e.getCause());
    }
    // Test submit with TransactionCommitFailedException
    errorMsg = "mock TransactionCommitFailedException";
    cause = new DataValidationFailedException(TestModel.TEST_PATH, "mock");
    doReturn(Futures.immediateFailedFuture(new org.opendaylight.mdsal.common.api.TransactionCommitFailedException(errorMsg, cause))).when(mockCommitCohort).canCommit();
    try {
        tx = adapter.newWriteOnlyTransaction();
        tx.put(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH, dataNode);
        submitFuture = tx.submit();
        submitFuture.checkedGet(5, TimeUnit.SECONDS);
        fail("Expected TransactionCommitFailedException");
    } catch (TransactionCommitFailedException e) {
        assertEquals("getMessage", errorMsg, e.getMessage());
        assertEquals("getCause", cause, e.getCause());
    }
    // Test submit with DataStoreUnavailableException
    errorMsg = "mock NoShardLeaderException";
    cause = new NoShardLeaderException("mock");
    doReturn(Futures.immediateFailedFuture(cause)).when(mockCommitCohort).canCommit();
    try {
        tx = adapter.newWriteOnlyTransaction();
        tx.put(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH, dataNode);
        submitFuture = tx.submit();
        submitFuture.checkedGet(5, TimeUnit.SECONDS);
        fail("Expected TransactionCommitFailedException");
    } catch (TransactionCommitFailedException e) {
        assertEquals("getCause type", DataStoreUnavailableException.class, e.getCause().getClass());
        assertEquals("Root cause", cause, e.getCause().getCause());
    }
    // Test submit with RuntimeException
    errorMsg = "mock RuntimeException";
    cause = new RuntimeException(errorMsg);
    doReturn(Futures.immediateFailedFuture(cause)).when(mockCommitCohort).canCommit();
    try {
        tx = adapter.newWriteOnlyTransaction();
        tx.put(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH, dataNode);
        submitFuture = tx.submit();
        submitFuture.checkedGet(5, TimeUnit.SECONDS);
        fail("Expected TransactionCommitFailedException");
    } catch (TransactionCommitFailedException e) {
        assertEquals("getCause", cause, e.getCause());
    }
}
Also used : DataValidationFailedException(org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException) InOrder(org.mockito.InOrder) DataStoreUnavailableException(org.opendaylight.controller.md.sal.common.api.data.DataStoreUnavailableException) NoShardLeaderException(org.opendaylight.controller.cluster.datastore.exceptions.NoShardLeaderException) TransactionCommitFailedException(org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException) ConflictingModificationAppliedException(org.opendaylight.yangtools.yang.data.api.schema.tree.ConflictingModificationAppliedException) DOMDataWriteTransaction(org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction) OptimisticLockFailedException(org.opendaylight.controller.md.sal.common.api.data.OptimisticLockFailedException) Test(org.junit.Test)

Example 5 with NoShardLeaderException

use of org.opendaylight.controller.cluster.datastore.exceptions.NoShardLeaderException in project controller by opendaylight.

the class ConcurrentDOMDataBroker method handleException.

@SuppressFBWarnings(value = "BC_UNCONFIRMED_CAST_OF_RETURN_VALUE", justification = "Pertains to the assignment of the 'clientException' var. FindBugs flags this as an " + "uncomfirmed cast but the generic type in TransactionCommitFailedExceptionMapper is " + "TransactionCommitFailedException and thus should be deemed as confirmed.")
private static void handleException(final AsyncNotifyingSettableFuture clientSubmitFuture, final DOMDataTreeWriteTransaction transaction, final Collection<DOMStoreThreePhaseCommitCohort> cohorts, final String phase, final TransactionCommitFailedExceptionMapper exMapper, final Throwable throwable) {
    if (clientSubmitFuture.isDone()) {
        // We must have had failures from multiple cohorts.
        return;
    }
    // Use debug instead of warn level here because this exception gets propagate back to the caller via the Future
    LOG.debug("Tx: {} Error during phase {}, starting Abort", transaction.getIdentifier(), phase, throwable);
    // Transaction failed - tell all cohorts to abort.
    @SuppressWarnings("unchecked") ListenableFuture<Void>[] canCommitFutures = new ListenableFuture[cohorts.size()];
    int index = 0;
    for (DOMStoreThreePhaseCommitCohort cohort : cohorts) {
        canCommitFutures[index++] = cohort.abort();
    }
    // Propagate the original exception
    final Exception e;
    if (throwable instanceof NoShardLeaderException || throwable instanceof ShardLeaderNotRespondingException) {
        e = new DataStoreUnavailableException(throwable.getMessage(), throwable);
    } else if (throwable instanceof Exception) {
        e = (Exception) throwable;
    } else {
        e = new RuntimeException("Unexpected error occurred", throwable);
    }
    clientSubmitFuture.setException(exMapper.apply(e));
    ListenableFuture<List<Void>> combinedFuture = Futures.allAsList(canCommitFutures);
    Futures.addCallback(combinedFuture, new FutureCallback<List<Void>>() {

        @Override
        public void onSuccess(final List<Void> notUsed) {
            // Propagate the original exception to the client.
            LOG.debug("Tx: {} aborted successfully", transaction.getIdentifier());
        }

        @Override
        public void onFailure(final Throwable failure) {
            LOG.error("Tx: {} Error during Abort.", transaction.getIdentifier(), failure);
        }
    }, MoreExecutors.directExecutor());
}
Also used : DataStoreUnavailableException(org.opendaylight.mdsal.common.api.DataStoreUnavailableException) DOMStoreThreePhaseCommitCohort(org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort) ShardLeaderNotRespondingException(org.opendaylight.controller.cluster.datastore.exceptions.ShardLeaderNotRespondingException) DataStoreUnavailableException(org.opendaylight.mdsal.common.api.DataStoreUnavailableException) NoShardLeaderException(org.opendaylight.controller.cluster.datastore.exceptions.NoShardLeaderException) TransactionCommitFailedException(org.opendaylight.mdsal.common.api.TransactionCommitFailedException) NoShardLeaderException(org.opendaylight.controller.cluster.datastore.exceptions.NoShardLeaderException) ShardLeaderNotRespondingException(org.opendaylight.controller.cluster.datastore.exceptions.ShardLeaderNotRespondingException) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) List(java.util.List) SuppressFBWarnings(edu.umd.cs.findbugs.annotations.SuppressFBWarnings)

Aggregations

NoShardLeaderException (org.opendaylight.controller.cluster.datastore.exceptions.NoShardLeaderException)12 Test (org.junit.Test)7 AddressFromURIString (akka.actor.AddressFromURIString)5 ExecutionException (java.util.concurrent.ExecutionException)4 RequestTimeoutException (org.opendaylight.controller.cluster.access.client.RequestTimeoutException)3 ShardLeaderNotRespondingException (org.opendaylight.controller.cluster.datastore.exceptions.ShardLeaderNotRespondingException)3 DataStoreUnavailableException (org.opendaylight.mdsal.common.api.DataStoreUnavailableException)3 TransactionCommitFailedException (org.opendaylight.mdsal.common.api.TransactionCommitFailedException)3 DOMStoreThreePhaseCommitCohort (org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort)3 ActorRef (akka.actor.ActorRef)2 TestActorRef (akka.testkit.TestActorRef)2 TestKit (akka.testkit.javadsl.TestKit)2 NotInitializedException (org.opendaylight.controller.cluster.datastore.exceptions.NotInitializedException)2 RemotePrimaryShardFound (org.opendaylight.controller.cluster.datastore.messages.RemotePrimaryShardFound)2 ReadFailedException (org.opendaylight.mdsal.common.api.ReadFailedException)2 DOMStoreReadTransaction (org.opendaylight.mdsal.dom.spi.store.DOMStoreReadTransaction)2 DOMStoreReadWriteTransaction (org.opendaylight.mdsal.dom.spi.store.DOMStoreReadWriteTransaction)2 DOMStoreWriteTransaction (org.opendaylight.mdsal.dom.spi.store.DOMStoreWriteTransaction)2 Status (akka.actor.Status)1 Failure (akka.actor.Status.Failure)1