use of org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException 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);
});
}
use of org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException in project controller by opendaylight.
the class ShardTest method testCanCommitPhaseFailure.
@Test
public void testCanCommitPhaseFailure() throws Exception {
new ShardTestKit(getSystem()) {
{
final DataTree dataTree = createDelegatingMockDataTree();
final TestActorRef<Shard> shard = actorFactory.createTestActor(newShardBuilder().dataTree(dataTree).props().withDispatcher(Dispatchers.DefaultDispatcherId()), "testCanCommitPhaseFailure");
waitUntilLeader(shard);
final FiniteDuration duration = duration("5 seconds");
final TransactionIdentifier transactionID1 = nextTransactionId();
doThrow(new DataValidationFailedException(YangInstanceIdentifier.EMPTY, "mock canCommit failure")).doNothing().when(dataTree).validate(any(DataTreeModification.class));
shard.tell(newBatchedModifications(transactionID1, TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME), true, false, 1), getRef());
expectMsgClass(duration, ReadyTransactionReply.class);
// Send the CanCommitTransaction message.
shard.tell(new CanCommitTransaction(transactionID1, CURRENT_VERSION).toSerializable(), getRef());
expectMsgClass(duration, akka.actor.Status.Failure.class);
// Send another can commit to ensure the failed one got cleaned
// up.
final TransactionIdentifier transactionID2 = nextTransactionId();
shard.tell(newBatchedModifications(transactionID2, TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME), true, false, 1), getRef());
expectMsgClass(duration, ReadyTransactionReply.class);
shard.tell(new CanCommitTransaction(transactionID2, CURRENT_VERSION).toSerializable(), getRef());
final CanCommitTransactionReply reply = CanCommitTransactionReply.fromSerializable(expectMsgClass(CanCommitTransactionReply.class));
assertEquals("getCanCommit", true, reply.getCanCommit());
}
};
}
Aggregations