use of org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier in project controller by opendaylight.
the class ShardTest method testAbortWithCommitPending.
@Test
public void testAbortWithCommitPending() throws Exception {
new ShardTestKit(getSystem()) {
{
final Creator<Shard> creator = () -> new Shard(newShardBuilder()) {
@Override
void persistPayload(final Identifier id, final Payload payload, final boolean batchHint) {
// Simulate an AbortTransaction message occurring during
// replication, after
// persisting and before finishing the commit to the
// in-memory store.
doAbortTransaction(id, null);
super.persistPayload(id, payload, batchHint);
}
};
final TestActorRef<Shard> shard = actorFactory.createTestActor(Props.create(new DelegatingShardCreator(creator)).withDispatcher(Dispatchers.DefaultDispatcherId()), "testAbortWithCommitPending");
waitUntilLeader(shard);
final FiniteDuration duration = duration("5 seconds");
final TransactionIdentifier transactionID = nextTransactionId();
shard.tell(prepareBatchedModifications(transactionID, TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME), false), getRef());
expectMsgClass(duration, ReadyTransactionReply.class);
shard.tell(new CanCommitTransaction(transactionID, CURRENT_VERSION).toSerializable(), getRef());
expectMsgClass(duration, CanCommitTransactionReply.class);
shard.tell(new CommitTransaction(transactionID, CURRENT_VERSION).toSerializable(), getRef());
expectMsgClass(duration, CommitTransactionReply.class);
final NormalizedNode<?, ?> node = readStore(shard, TestModel.TEST_PATH);
// Since we're simulating an abort occurring during replication
// and before finish commit,
// the data should still get written to the in-memory store
// since we've gotten past
// canCommit and preCommit and persisted the data.
assertNotNull(TestModel.TEST_QNAME.getLocalName() + " not found", node);
}
};
}
use of org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier in project controller by opendaylight.
the class ShardTest method testTransactionCommitTimeout.
@Test
public void testTransactionCommitTimeout() throws Exception {
dataStoreContextBuilder.shardTransactionCommitTimeoutInSeconds(1);
new ShardTestKit(getSystem()) {
{
final TestActorRef<Shard> shard = actorFactory.createTestActor(newShardProps().withDispatcher(Dispatchers.DefaultDispatcherId()), "testTransactionCommitTimeout");
waitUntilLeader(shard);
final FiniteDuration duration = duration("5 seconds");
writeToStore(shard, TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
writeToStore(shard, TestModel.OUTER_LIST_PATH, ImmutableNodes.mapNodeBuilder(TestModel.OUTER_LIST_QNAME).build());
// Ready 2 Tx's - the first will timeout
final TransactionIdentifier transactionID1 = nextTransactionId();
shard.tell(prepareBatchedModifications(transactionID1, YangInstanceIdentifier.builder(TestModel.OUTER_LIST_PATH).nodeWithKey(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, 1).build(), ImmutableNodes.mapEntry(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, 1), false), getRef());
expectMsgClass(duration, ReadyTransactionReply.class);
final TransactionIdentifier transactionID2 = nextTransactionId();
final YangInstanceIdentifier listNodePath = YangInstanceIdentifier.builder(TestModel.OUTER_LIST_PATH).nodeWithKey(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, 2).build();
shard.tell(prepareBatchedModifications(transactionID2, listNodePath, ImmutableNodes.mapEntry(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, 2), false), getRef());
expectMsgClass(duration, ReadyTransactionReply.class);
// canCommit 1st Tx. We don't send the commit so it should
// timeout.
shard.tell(new CanCommitTransaction(transactionID1, CURRENT_VERSION).toSerializable(), getRef());
expectMsgClass(duration, CanCommitTransactionReply.class);
// canCommit the 2nd Tx - it should complete after the 1st Tx
// times out.
shard.tell(new CanCommitTransaction(transactionID2, CURRENT_VERSION).toSerializable(), getRef());
expectMsgClass(duration, CanCommitTransactionReply.class);
// Try to commit the 1st Tx - should fail as it's not the
// current Tx.
shard.tell(new CommitTransaction(transactionID1, CURRENT_VERSION).toSerializable(), getRef());
expectMsgClass(duration, akka.actor.Status.Failure.class);
// Commit the 2nd Tx.
shard.tell(new CommitTransaction(transactionID2, CURRENT_VERSION).toSerializable(), getRef());
expectMsgClass(duration, CommitTransactionReply.class);
final NormalizedNode<?, ?> node = readStore(shard, listNodePath);
assertNotNull(listNodePath + " not found", node);
}
};
}
use of org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier in project controller by opendaylight.
the class ShardTest method testReadyLocalTransactionWithImmediateCommit.
@Test
public void testReadyLocalTransactionWithImmediateCommit() throws Exception {
new ShardTestKit(getSystem()) {
{
final TestActorRef<Shard> shard = actorFactory.createTestActor(newShardProps().withDispatcher(Dispatchers.DefaultDispatcherId()), "testReadyLocalTransactionWithImmediateCommit");
waitUntilLeader(shard);
final ShardDataTree dataStore = shard.underlyingActor().getDataStore();
final DataTreeModification modification = dataStore.newModification();
final ContainerNode writeData = ImmutableNodes.containerNode(TestModel.TEST_QNAME);
new WriteModification(TestModel.TEST_PATH, writeData).apply(modification);
final MapNode mergeData = ImmutableNodes.mapNodeBuilder(TestModel.OUTER_LIST_QNAME).build();
new MergeModification(TestModel.OUTER_LIST_PATH, mergeData).apply(modification);
final TransactionIdentifier txId = nextTransactionId();
modification.ready();
final ReadyLocalTransaction readyMessage = new ReadyLocalTransaction(txId, modification, true);
shard.tell(readyMessage, getRef());
expectMsgClass(CommitTransactionReply.class);
final NormalizedNode<?, ?> actualNode = readStore(shard, TestModel.OUTER_LIST_PATH);
assertEquals(TestModel.OUTER_LIST_QNAME.getLocalName(), mergeData, actualNode);
}
};
}
use of org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier in project controller by opendaylight.
the class ShardTest method testBatchedModificationsReadyWithIncorrectTotalMessageCount.
@Test(expected = IllegalStateException.class)
public void testBatchedModificationsReadyWithIncorrectTotalMessageCount() throws Exception {
new ShardTestKit(getSystem()) {
{
final TestActorRef<Shard> shard = actorFactory.createTestActor(newShardProps().withDispatcher(Dispatchers.DefaultDispatcherId()), "testBatchedModificationsReadyWithIncorrectTotalMessageCount");
waitUntilLeader(shard);
final TransactionIdentifier transactionID = nextTransactionId();
final BatchedModifications batched = new BatchedModifications(transactionID, DataStoreVersions.CURRENT_VERSION);
batched.setReady(true);
batched.setTotalMessagesSent(2);
shard.tell(batched, getRef());
final Failure failure = expectMsgClass(duration("5 seconds"), akka.actor.Status.Failure.class);
if (failure != null) {
Throwables.propagateIfPossible(failure.cause(), Exception.class);
throw new RuntimeException(failure.cause());
}
}
};
}
use of org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier in project controller by opendaylight.
the class ShardTest method testAbortAfterCanCommit.
@Test
public void testAbortAfterCanCommit() throws Exception {
new ShardTestKit(getSystem()) {
{
final TestActorRef<Shard> shard = actorFactory.createTestActor(newShardProps().withDispatcher(Dispatchers.DefaultDispatcherId()), "testAbortAfterCanCommit");
waitUntilLeader(shard);
final FiniteDuration duration = duration("5 seconds");
final Timeout timeout = new Timeout(duration);
// Ready 2 transactions - the first one will be aborted.
final TransactionIdentifier transactionID1 = nextTransactionId();
shard.tell(newBatchedModifications(transactionID1, TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME), true, false, 1), getRef());
expectMsgClass(duration, ReadyTransactionReply.class);
final TransactionIdentifier transactionID2 = nextTransactionId();
shard.tell(newBatchedModifications(transactionID2, TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME), true, false, 1), getRef());
expectMsgClass(duration, ReadyTransactionReply.class);
// Send the CanCommitTransaction message for the first Tx.
shard.tell(new CanCommitTransaction(transactionID1, CURRENT_VERSION).toSerializable(), getRef());
CanCommitTransactionReply canCommitReply = CanCommitTransactionReply.fromSerializable(expectMsgClass(duration, CanCommitTransactionReply.class));
assertEquals("Can commit", true, canCommitReply.getCanCommit());
// Send the CanCommitTransaction message for the 2nd Tx. This
// should get queued and
// processed after the first Tx completes.
final Future<Object> canCommitFuture = Patterns.ask(shard, new CanCommitTransaction(transactionID2, CURRENT_VERSION).toSerializable(), timeout);
// Send the AbortTransaction message for the first Tx. This
// should trigger the 2nd
// Tx to proceed.
shard.tell(new AbortTransaction(transactionID1, CURRENT_VERSION).toSerializable(), getRef());
expectMsgClass(duration, AbortTransactionReply.class);
// Wait for the 2nd Tx to complete the canCommit phase.
canCommitReply = (CanCommitTransactionReply) Await.result(canCommitFuture, duration);
assertEquals("Can commit", true, canCommitReply.getCanCommit());
}
};
}
Aggregations