use of org.opendaylight.controller.cluster.datastore.persisted.CommitTransactionPayload in project controller by opendaylight.
the class ShardDataTreeTest method testPipelinedTransactionsWithCoordinatedCommits.
@Test
public void testPipelinedTransactionsWithCoordinatedCommits() throws Exception {
final ShardDataTreeCohort cohort1 = newShardDataTreeCohort(snapshot -> snapshot.write(CarsModel.BASE_PATH, CarsModel.emptyContainer()));
final ShardDataTreeCohort cohort2 = newShardDataTreeCohort(snapshot -> snapshot.write(CarsModel.CAR_LIST_PATH, CarsModel.newCarMapNode()));
NormalizedNode<?, ?> peopleNode = PeopleModel.create();
final ShardDataTreeCohort cohort3 = newShardDataTreeCohort(snapshot -> snapshot.write(PeopleModel.BASE_PATH, peopleNode));
YangInstanceIdentifier carPath = CarsModel.newCarPath("optima");
MapEntryNode carNode = CarsModel.newCarEntry("optima", new BigInteger("100"));
final ShardDataTreeCohort cohort4 = newShardDataTreeCohort(snapshot -> snapshot.write(carPath, carNode));
immediateCanCommit(cohort1);
final FutureCallback<Void> canCommitCallback2 = coordinatedCanCommit(cohort2);
final FutureCallback<Void> canCommitCallback3 = coordinatedCanCommit(cohort3);
final FutureCallback<Void> canCommitCallback4 = coordinatedCanCommit(cohort4);
final FutureCallback<DataTreeCandidate> preCommitCallback1 = coordinatedPreCommit(cohort1);
verify(preCommitCallback1).onSuccess(cohort1.getCandidate());
verify(canCommitCallback2).onSuccess(null);
final FutureCallback<DataTreeCandidate> preCommitCallback2 = coordinatedPreCommit(cohort2);
verify(preCommitCallback2).onSuccess(cohort2.getCandidate());
verify(canCommitCallback3).onSuccess(null);
final FutureCallback<DataTreeCandidate> preCommitCallback3 = coordinatedPreCommit(cohort3);
verify(preCommitCallback3).onSuccess(cohort3.getCandidate());
verify(canCommitCallback4).onSuccess(null);
final FutureCallback<DataTreeCandidate> preCommitCallback4 = coordinatedPreCommit(cohort4);
verify(preCommitCallback4).onSuccess(cohort4.getCandidate());
final FutureCallback<UnsignedLong> commitCallback2 = coordinatedCommit(cohort2);
verify(mockShard, never()).persistPayload(eq(cohort1.getIdentifier()), any(CommitTransactionPayload.class), anyBoolean());
verifyNoMoreInteractions(commitCallback2);
final FutureCallback<UnsignedLong> commitCallback4 = coordinatedCommit(cohort4);
verify(mockShard, never()).persistPayload(eq(cohort4.getIdentifier()), any(CommitTransactionPayload.class), anyBoolean());
verifyNoMoreInteractions(commitCallback4);
final FutureCallback<UnsignedLong> commitCallback1 = coordinatedCommit(cohort1);
InOrder inOrder = inOrder(mockShard);
inOrder.verify(mockShard).persistPayload(eq(cohort1.getIdentifier()), any(CommitTransactionPayload.class), eq(true));
inOrder.verify(mockShard).persistPayload(eq(cohort2.getIdentifier()), any(CommitTransactionPayload.class), eq(false));
verifyNoMoreInteractions(commitCallback1);
verifyNoMoreInteractions(commitCallback2);
final FutureCallback<UnsignedLong> commitCallback3 = coordinatedCommit(cohort3);
inOrder = inOrder(mockShard);
inOrder.verify(mockShard).persistPayload(eq(cohort3.getIdentifier()), any(CommitTransactionPayload.class), eq(true));
inOrder.verify(mockShard).persistPayload(eq(cohort4.getIdentifier()), any(CommitTransactionPayload.class), eq(false));
verifyNoMoreInteractions(commitCallback3);
verifyNoMoreInteractions(commitCallback4);
final ShardDataTreeCohort cohort5 = newShardDataTreeCohort(snapshot -> snapshot.merge(CarsModel.BASE_PATH, CarsModel.emptyContainer()));
final FutureCallback<Void> canCommitCallback5 = coordinatedCanCommit(cohort5);
// The payload instance doesn't matter - it just needs to be of type CommitTransactionPayload.
CommitTransactionPayload mockPayload = CommitTransactionPayload.create(nextTransactionId(), cohort1.getCandidate());
shardDataTree.applyReplicatedPayload(cohort1.getIdentifier(), mockPayload);
shardDataTree.applyReplicatedPayload(cohort2.getIdentifier(), mockPayload);
shardDataTree.applyReplicatedPayload(cohort3.getIdentifier(), mockPayload);
shardDataTree.applyReplicatedPayload(cohort4.getIdentifier(), mockPayload);
inOrder = inOrder(commitCallback1, commitCallback2, commitCallback3, commitCallback4);
inOrder.verify(commitCallback1).onSuccess(any(UnsignedLong.class));
inOrder.verify(commitCallback2).onSuccess(any(UnsignedLong.class));
inOrder.verify(commitCallback3).onSuccess(any(UnsignedLong.class));
inOrder.verify(commitCallback4).onSuccess(any(UnsignedLong.class));
verify(canCommitCallback5).onSuccess(null);
final DataTreeSnapshot snapshot = shardDataTree.newReadOnlyTransaction(nextTransactionId()).getSnapshot();
Optional<NormalizedNode<?, ?>> optional = snapshot.readNode(carPath);
assertEquals("Car node present", true, optional.isPresent());
assertEquals("Car node", carNode, optional.get());
optional = snapshot.readNode(PeopleModel.BASE_PATH);
assertEquals("People node present", true, optional.isPresent());
assertEquals("People node", peopleNode, optional.get());
}
use of org.opendaylight.controller.cluster.datastore.persisted.CommitTransactionPayload in project controller by opendaylight.
the class ShardDataTreeTest method testAbortWithPendingCommits.
@SuppressWarnings("unchecked")
@Test
public void testAbortWithPendingCommits() throws Exception {
final ShardDataTreeCohort cohort1 = newShardDataTreeCohort(snapshot -> snapshot.write(CarsModel.BASE_PATH, CarsModel.emptyContainer()));
final ShardDataTreeCohort cohort2 = newShardDataTreeCohort(snapshot -> snapshot.write(PeopleModel.BASE_PATH, PeopleModel.create()));
final ShardDataTreeCohort cohort3 = newShardDataTreeCohort(snapshot -> snapshot.write(CarsModel.CAR_LIST_PATH, CarsModel.newCarMapNode()));
YangInstanceIdentifier carPath = CarsModel.newCarPath("optima");
MapEntryNode carNode = CarsModel.newCarEntry("optima", new BigInteger("100"));
final ShardDataTreeCohort cohort4 = newShardDataTreeCohort(snapshot -> snapshot.write(carPath, carNode));
coordinatedCanCommit(cohort2);
immediateCanCommit(cohort1);
coordinatedCanCommit(cohort3);
coordinatedCanCommit(cohort4);
coordinatedPreCommit(cohort1);
coordinatedPreCommit(cohort2);
coordinatedPreCommit(cohort3);
FutureCallback<Void> mockAbortCallback = mock(FutureCallback.class);
doNothing().when(mockAbortCallback).onSuccess(null);
cohort2.abort(mockAbortCallback);
verify(mockAbortCallback).onSuccess(null);
coordinatedPreCommit(cohort4);
coordinatedCommit(cohort1);
coordinatedCommit(cohort3);
coordinatedCommit(cohort4);
InOrder inOrder = inOrder(mockShard);
inOrder.verify(mockShard).persistPayload(eq(cohort1.getIdentifier()), any(CommitTransactionPayload.class), eq(false));
inOrder.verify(mockShard).persistPayload(eq(cohort3.getIdentifier()), any(CommitTransactionPayload.class), eq(false));
inOrder.verify(mockShard).persistPayload(eq(cohort4.getIdentifier()), any(CommitTransactionPayload.class), eq(false));
// The payload instance doesn't matter - it just needs to be of type CommitTransactionPayload.
CommitTransactionPayload mockPayload = CommitTransactionPayload.create(nextTransactionId(), cohort1.getCandidate());
shardDataTree.applyReplicatedPayload(cohort1.getIdentifier(), mockPayload);
shardDataTree.applyReplicatedPayload(cohort3.getIdentifier(), mockPayload);
shardDataTree.applyReplicatedPayload(cohort4.getIdentifier(), mockPayload);
final DataTreeSnapshot snapshot = shardDataTree.newReadOnlyTransaction(nextTransactionId()).getSnapshot();
Optional<NormalizedNode<?, ?>> optional = snapshot.readNode(carPath);
assertEquals("Car node present", true, optional.isPresent());
assertEquals("Car node", carNode, optional.get());
}
use of org.opendaylight.controller.cluster.datastore.persisted.CommitTransactionPayload in project controller by opendaylight.
the class ShardDataTreeTest method testPipelinedTransactionsWithImmediateCommits.
@Test
public void testPipelinedTransactionsWithImmediateCommits() throws Exception {
final ShardDataTreeCohort cohort1 = newShardDataTreeCohort(snapshot -> snapshot.write(CarsModel.BASE_PATH, CarsModel.emptyContainer()));
final ShardDataTreeCohort cohort2 = newShardDataTreeCohort(snapshot -> snapshot.write(CarsModel.CAR_LIST_PATH, CarsModel.newCarMapNode()));
YangInstanceIdentifier carPath = CarsModel.newCarPath("optima");
MapEntryNode carNode = CarsModel.newCarEntry("optima", new BigInteger("100"));
final ShardDataTreeCohort cohort3 = newShardDataTreeCohort(snapshot -> snapshot.write(carPath, carNode));
final FutureCallback<UnsignedLong> commitCallback2 = immediate3PhaseCommit(cohort2);
final FutureCallback<UnsignedLong> commitCallback3 = immediate3PhaseCommit(cohort3);
final FutureCallback<UnsignedLong> commitCallback1 = immediate3PhaseCommit(cohort1);
InOrder inOrder = inOrder(mockShard);
inOrder.verify(mockShard).persistPayload(eq(cohort1.getIdentifier()), any(CommitTransactionPayload.class), eq(true));
inOrder.verify(mockShard).persistPayload(eq(cohort2.getIdentifier()), any(CommitTransactionPayload.class), eq(true));
inOrder.verify(mockShard).persistPayload(eq(cohort3.getIdentifier()), any(CommitTransactionPayload.class), eq(false));
// The payload instance doesn't matter - it just needs to be of type CommitTransactionPayload.
CommitTransactionPayload mockPayload = CommitTransactionPayload.create(nextTransactionId(), cohort1.getCandidate());
shardDataTree.applyReplicatedPayload(cohort1.getIdentifier(), mockPayload);
shardDataTree.applyReplicatedPayload(cohort2.getIdentifier(), mockPayload);
shardDataTree.applyReplicatedPayload(cohort3.getIdentifier(), mockPayload);
inOrder = inOrder(commitCallback1, commitCallback2, commitCallback3);
inOrder.verify(commitCallback1).onSuccess(any(UnsignedLong.class));
inOrder.verify(commitCallback2).onSuccess(any(UnsignedLong.class));
inOrder.verify(commitCallback3).onSuccess(any(UnsignedLong.class));
final DataTreeSnapshot snapshot = shardDataTree.newReadOnlyTransaction(nextTransactionId()).getSnapshot();
Optional<NormalizedNode<?, ?>> optional = snapshot.readNode(carPath);
assertEquals("Car node present", true, optional.isPresent());
assertEquals("Car node", carNode, optional.get());
}
use of org.opendaylight.controller.cluster.datastore.persisted.CommitTransactionPayload in project controller by opendaylight.
the class ShardDataTree method applyReplicatedPayload.
/**
* Apply a payload coming from the leader, which could actually be us. This method assumes the leader and follower
* SchemaContexts match and does not perform any pruning.
*
* @param identifier Payload identifier as returned from RaftActor
* @param payload Payload
* @throws IOException when the snapshot fails to deserialize
* @throws DataValidationFailedException when the snapshot fails to apply
*/
void applyReplicatedPayload(final Identifier identifier, final Payload payload) throws IOException, DataValidationFailedException {
/*
* This is a bit more involved than it needs to be due to to the fact we do not want to be touching the payload
* if we are the leader and it has originated with us.
*
* The identifier will only ever be non-null when we were the leader which achieved consensus. Unfortunately,
* though, this may not be the case anymore, as we are being called some time afterwards and we may not be
* acting in that capacity anymore.
*
* In any case, we know that this is an entry coming from replication, hence we can be sure we will not observe
* pre-Boron state -- which limits the number of options here.
*/
if (payload instanceof CommitTransactionPayload) {
final TransactionIdentifier txId;
if (identifier == null) {
final Entry<TransactionIdentifier, DataTreeCandidate> e = ((CommitTransactionPayload) payload).getCandidate();
txId = e.getKey();
applyReplicatedCandidate(txId, e.getValue());
} else {
Verify.verify(identifier instanceof TransactionIdentifier);
txId = (TransactionIdentifier) identifier;
payloadReplicationComplete(txId);
}
allMetadataCommittedTransaction(txId);
} else if (payload instanceof AbortTransactionPayload) {
if (identifier != null) {
payloadReplicationComplete((AbortTransactionPayload) payload);
}
allMetadataAbortedTransaction(((AbortTransactionPayload) payload).getIdentifier());
} else if (payload instanceof PurgeTransactionPayload) {
if (identifier != null) {
payloadReplicationComplete((PurgeTransactionPayload) payload);
}
allMetadataPurgedTransaction(((PurgeTransactionPayload) payload).getIdentifier());
} else if (payload instanceof CloseLocalHistoryPayload) {
if (identifier != null) {
payloadReplicationComplete((CloseLocalHistoryPayload) payload);
}
allMetadataClosedLocalHistory(((CloseLocalHistoryPayload) payload).getIdentifier());
} else if (payload instanceof CreateLocalHistoryPayload) {
if (identifier != null) {
payloadReplicationComplete((CreateLocalHistoryPayload) payload);
}
allMetadataCreatedLocalHistory(((CreateLocalHistoryPayload) payload).getIdentifier());
} else if (payload instanceof PurgeLocalHistoryPayload) {
if (identifier != null) {
payloadReplicationComplete((PurgeLocalHistoryPayload) payload);
}
allMetadataPurgedLocalHistory(((PurgeLocalHistoryPayload) payload).getIdentifier());
} else {
LOG.warn("{}: ignoring unhandled identifier {} payload {}", logContext, identifier, payload);
}
}
Aggregations