use of org.opendaylight.yangtools.yang.data.api.schema.tree.ConflictingModificationAppliedException 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());
}
}
use of org.opendaylight.yangtools.yang.data.api.schema.tree.ConflictingModificationAppliedException 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);
});
}
Aggregations