Search in sources :

Example 6 with TransactionCommitFailedException

use of org.opendaylight.mdsal.common.api.TransactionCommitFailedException in project controller by opendaylight.

the class DistributedDataStoreRemotingIntegrationTest method testChainedTransactionFailureWithSingleShard.

@Test
public void testChainedTransactionFailureWithSingleShard() throws Exception {
    initDatastoresWithCars("testChainedTransactionFailureWithSingleShard");
    final ConcurrentDOMDataBroker broker = new ConcurrentDOMDataBroker(ImmutableMap.<LogicalDatastoreType, DOMStore>builder().put(LogicalDatastoreType.CONFIGURATION, followerDistributedDataStore).build(), MoreExecutors.directExecutor());
    final TransactionChainListener listener = Mockito.mock(TransactionChainListener.class);
    final DOMTransactionChain txChain = broker.createTransactionChain(listener);
    final DOMDataTreeWriteTransaction writeTx = txChain.newWriteOnlyTransaction();
    final ContainerNode invalidData = ImmutableContainerNodeBuilder.create().withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(CarsModel.BASE_QNAME)).withChild(ImmutableNodes.leafNode(TestModel.JUNK_QNAME, "junk")).build();
    writeTx.merge(LogicalDatastoreType.CONFIGURATION, CarsModel.BASE_PATH, invalidData);
    try {
        writeTx.submit().checkedGet(5, TimeUnit.SECONDS);
        fail("Expected TransactionCommitFailedException");
    } catch (final TransactionCommitFailedException e) {
    // Expected
    }
    verify(listener, timeout(5000)).onTransactionChainFailed(eq(txChain), eq(writeTx), any(Throwable.class));
    txChain.close();
    broker.close();
}
Also used : TransactionCommitFailedException(org.opendaylight.mdsal.common.api.TransactionCommitFailedException) ConcurrentDOMDataBroker(org.opendaylight.controller.cluster.databroker.ConcurrentDOMDataBroker) TransactionChainListener(org.opendaylight.mdsal.common.api.TransactionChainListener) DOMDataTreeWriteTransaction(org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction) ContainerNode(org.opendaylight.yangtools.yang.data.api.schema.ContainerNode) DOMTransactionChain(org.opendaylight.mdsal.dom.api.DOMTransactionChain) YangInstanceIdentifier(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier) Test(org.junit.Test)

Example 7 with TransactionCommitFailedException

use of org.opendaylight.mdsal.common.api.TransactionCommitFailedException in project controller by opendaylight.

the class ConcurrentDOMDataBroker method doCanCommit.

private void doCanCommit(final AsyncNotifyingSettableFuture clientSubmitFuture, final DOMDataTreeWriteTransaction transaction, final Collection<DOMStoreThreePhaseCommitCohort> cohorts) {
    final long startTime = System.nanoTime();
    final Iterator<DOMStoreThreePhaseCommitCohort> cohortIterator = cohorts.iterator();
    // Not using Futures.allAsList here to avoid its internal overhead.
    FutureCallback<Boolean> futureCallback = new FutureCallback<Boolean>() {

        @Override
        public void onSuccess(final Boolean result) {
            if (result == null || !result) {
                handleException(clientSubmitFuture, transaction, cohorts, CAN_COMMIT, CAN_COMMIT_ERROR_MAPPER, new TransactionCommitFailedException("Can Commit failed, no detailed cause available."));
            } else if (!cohortIterator.hasNext()) {
                // All cohorts completed successfully - we can move on to the preCommit phase
                doPreCommit(startTime, clientSubmitFuture, transaction, cohorts);
            } else {
                Futures.addCallback(cohortIterator.next().canCommit(), this, MoreExecutors.directExecutor());
            }
        }

        @Override
        public void onFailure(final Throwable failure) {
            handleException(clientSubmitFuture, transaction, cohorts, CAN_COMMIT, CAN_COMMIT_ERROR_MAPPER, failure);
        }
    };
    ListenableFuture<Boolean> canCommitFuture = cohortIterator.next().canCommit();
    Futures.addCallback(canCommitFuture, futureCallback, MoreExecutors.directExecutor());
}
Also used : TransactionCommitFailedException(org.opendaylight.mdsal.common.api.TransactionCommitFailedException) DOMStoreThreePhaseCommitCohort(org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort) FutureCallback(com.google.common.util.concurrent.FutureCallback)

Example 8 with TransactionCommitFailedException

use of org.opendaylight.mdsal.common.api.TransactionCommitFailedException 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)

Example 9 with TransactionCommitFailedException

use of org.opendaylight.mdsal.common.api.TransactionCommitFailedException in project controller by opendaylight.

the class ShardDataTree method processNextPendingTransaction.

@SuppressWarnings("checkstyle:IllegalCatch")
private void processNextPendingTransaction() {
    ++currentTransactionBatch;
    if (currentTransactionBatch > MAX_TRANSACTION_BATCH) {
        LOG.debug("{}: Already processed {}, scheduling continuation", logContext, currentTransactionBatch);
        shard.scheduleNextPendingTransaction();
        return;
    }
    processNextPending(pendingTransactions, State.CAN_COMMIT_PENDING, entry -> {
        final SimpleShardDataTreeCohort cohort = entry.cohort;
        final DataTreeModification modification = cohort.getDataTreeModification();
        LOG.debug("{}: Validating transaction {}", logContext, cohort.getIdentifier());
        Exception cause;
        try {
            tip.validate(modification);
            LOG.debug("{}: Transaction {} validated", logContext, cohort.getIdentifier());
            cohort.successfulCanCommit();
            entry.lastAccess = readTime();
            return;
        } catch (ConflictingModificationAppliedException e) {
            LOG.warn("{}: Store Tx {}: Conflicting modification for path {}.", logContext, cohort.getIdentifier(), e.getPath());
            cause = new OptimisticLockFailedException("Optimistic lock failed.", e);
        } catch (DataValidationFailedException e) {
            LOG.warn("{}: Store Tx {}: Data validation failed for path {}.", logContext, cohort.getIdentifier(), e.getPath(), e);
            // For debugging purposes, allow dumping of the modification. Coupled with the above
            // precondition log, it should allow us to understand what went on.
            LOG.debug("{}: Store Tx {}: modifications: {} tree: {}", cohort.getIdentifier(), modification, dataTree);
            cause = new TransactionCommitFailedException("Data did not pass validation.", e);
        } catch (Exception e) {
            LOG.warn("{}: Unexpected failure in validation phase", logContext, e);
            cause = e;
        }
        // Failure path: propagate the failure, remove the transaction from the queue and loop to the next one
        pendingTransactions.poll().cohort.failedCanCommit(cause);
    });
}
Also used : DataTreeModification(org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification) PruningDataTreeModification(org.opendaylight.controller.cluster.datastore.utils.PruningDataTreeModification) TransactionCommitFailedException(org.opendaylight.mdsal.common.api.TransactionCommitFailedException) DataValidationFailedException(org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException) ConflictingModificationAppliedException(org.opendaylight.yangtools.yang.data.api.schema.tree.ConflictingModificationAppliedException) TimeoutException(java.util.concurrent.TimeoutException) ConflictingModificationAppliedException(org.opendaylight.yangtools.yang.data.api.schema.tree.ConflictingModificationAppliedException) IOException(java.io.IOException) DataValidationFailedException(org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException) TransactionCommitFailedException(org.opendaylight.mdsal.common.api.TransactionCommitFailedException) OptimisticLockFailedException(org.opendaylight.mdsal.common.api.OptimisticLockFailedException) OptimisticLockFailedException(org.opendaylight.mdsal.common.api.OptimisticLockFailedException)

Example 10 with TransactionCommitFailedException

use of org.opendaylight.mdsal.common.api.TransactionCommitFailedException in project controller by opendaylight.

the class ConcurrentDOMDataBrokerTest method testSubmitWithCanCommitDataStoreUnavailableException.

@Test
public void testSubmitWithCanCommitDataStoreUnavailableException() throws Exception {
    doReturn(Futures.immediateFuture(true)).when(mockCohort1).canCommit();
    doReturn(Futures.immediateFuture(null)).when(mockCohort1).abort();
    NoShardLeaderException rootCause = new NoShardLeaderException("mock");
    DataStoreUnavailableException cause = new DataStoreUnavailableException(rootCause.getMessage(), rootCause);
    doReturn(Futures.immediateFailedFuture(rootCause)).when(mockCohort2).canCommit();
    doReturn(Futures.immediateFuture(null)).when(mockCohort2).abort();
    CheckedFuture<Void, TransactionCommitFailedException> future = coordinator.submit(transaction, Arrays.asList(mockCohort1, mockCohort2));
    assertFailure(future, cause, mockCohort1, mockCohort2);
}
Also used : TransactionCommitFailedException(org.opendaylight.mdsal.common.api.TransactionCommitFailedException) DataStoreUnavailableException(org.opendaylight.mdsal.common.api.DataStoreUnavailableException) NoShardLeaderException(org.opendaylight.controller.cluster.datastore.exceptions.NoShardLeaderException) Test(org.junit.Test)

Aggregations

TransactionCommitFailedException (org.opendaylight.mdsal.common.api.TransactionCommitFailedException)15 Test (org.junit.Test)12 DOMStoreThreePhaseCommitCohort (org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort)7 DOMDataTreeWriteTransaction (org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction)6 ConcurrentDOMDataBroker (org.opendaylight.controller.cluster.databroker.ConcurrentDOMDataBroker)5 TransactionChainListener (org.opendaylight.mdsal.common.api.TransactionChainListener)5 DOMTransactionChain (org.opendaylight.mdsal.dom.api.DOMTransactionChain)5 DOMDataTreeReadWriteTransaction (org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction)4 YangInstanceIdentifier (org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier)4 ContainerNode (org.opendaylight.yangtools.yang.data.api.schema.ContainerNode)4 ArrayList (java.util.ArrayList)3 DOMStore (org.opendaylight.mdsal.dom.spi.store.DOMStore)3 Collection (java.util.Collection)2 CountDownLatch (java.util.concurrent.CountDownLatch)2 NoShardLeaderException (org.opendaylight.controller.cluster.datastore.exceptions.NoShardLeaderException)2 DataStoreUnavailableException (org.opendaylight.mdsal.common.api.DataStoreUnavailableException)2 DOMStoreReadWriteTransaction (org.opendaylight.mdsal.dom.spi.store.DOMStoreReadWriteTransaction)2 NormalizedNode (org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode)2 CheckedFuture (com.google.common.util.concurrent.CheckedFuture)1 FutureCallback (com.google.common.util.concurrent.FutureCallback)1