Search in sources :

Example 6 with TransactionIdentifier

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);
        }
    };
}
Also used : CanCommitTransaction(org.opendaylight.controller.cluster.datastore.messages.CanCommitTransaction) CommitTransaction(org.opendaylight.controller.cluster.datastore.messages.CommitTransaction) YangInstanceIdentifier(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier) LocalHistoryIdentifier(org.opendaylight.controller.cluster.access.concepts.LocalHistoryIdentifier) ShardIdentifier(org.opendaylight.controller.cluster.datastore.identifiers.ShardIdentifier) TransactionIdentifier(org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier) Identifier(org.opendaylight.yangtools.concepts.Identifier) TransactionIdentifier(org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier) CanCommitTransaction(org.opendaylight.controller.cluster.datastore.messages.CanCommitTransaction) FiniteDuration(scala.concurrent.duration.FiniteDuration) Payload(org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payload) Test(org.junit.Test)

Example 7 with TransactionIdentifier

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);
        }
    };
}
Also used : FollowerInitialSyncUpStatus(org.opendaylight.controller.cluster.raft.base.messages.FollowerInitialSyncUpStatus) CanCommitTransaction(org.opendaylight.controller.cluster.datastore.messages.CanCommitTransaction) CommitTransaction(org.opendaylight.controller.cluster.datastore.messages.CommitTransaction) TransactionIdentifier(org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier) CanCommitTransaction(org.opendaylight.controller.cluster.datastore.messages.CanCommitTransaction) FiniteDuration(scala.concurrent.duration.FiniteDuration) YangInstanceIdentifier(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier) Test(org.junit.Test)

Example 8 with TransactionIdentifier

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);
        }
    };
}
Also used : DataTreeModification(org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification) WriteModification(org.opendaylight.controller.cluster.datastore.modification.WriteModification) MergeModification(org.opendaylight.controller.cluster.datastore.modification.MergeModification) ReadyLocalTransaction(org.opendaylight.controller.cluster.datastore.messages.ReadyLocalTransaction) TransactionIdentifier(org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier) ContainerNode(org.opendaylight.yangtools.yang.data.api.schema.ContainerNode) MapNode(org.opendaylight.yangtools.yang.data.api.schema.MapNode) Test(org.junit.Test)

Example 9 with TransactionIdentifier

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());
            }
        }
    };
}
Also used : FollowerInitialSyncUpStatus(org.opendaylight.controller.cluster.raft.base.messages.FollowerInitialSyncUpStatus) TransactionIdentifier(org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier) Failure(akka.actor.Status.Failure) BatchedModifications(org.opendaylight.controller.cluster.datastore.messages.BatchedModifications) Test(org.junit.Test)

Example 10 with TransactionIdentifier

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());
        }
    };
}
Also used : Timeout(akka.util.Timeout) ElectionTimeout(org.opendaylight.controller.cluster.raft.base.messages.ElectionTimeout) TransactionIdentifier(org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier) CanCommitTransaction(org.opendaylight.controller.cluster.datastore.messages.CanCommitTransaction) FiniteDuration(scala.concurrent.duration.FiniteDuration) AbortTransaction(org.opendaylight.controller.cluster.datastore.messages.AbortTransaction) CanCommitTransactionReply(org.opendaylight.controller.cluster.datastore.messages.CanCommitTransactionReply) Test(org.junit.Test)

Aggregations

TransactionIdentifier (org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier)57 Test (org.junit.Test)37 FiniteDuration (scala.concurrent.duration.FiniteDuration)17 CanCommitTransaction (org.opendaylight.controller.cluster.datastore.messages.CanCommitTransaction)16 CommitTransaction (org.opendaylight.controller.cluster.datastore.messages.CommitTransaction)12 DataTreeModification (org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification)11 CanCommitTransactionReply (org.opendaylight.controller.cluster.datastore.messages.CanCommitTransactionReply)10 ActorRef (akka.actor.ActorRef)8 FollowerInitialSyncUpStatus (org.opendaylight.controller.cluster.raft.base.messages.FollowerInitialSyncUpStatus)8 YangInstanceIdentifier (org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier)8 BatchedModifications (org.opendaylight.controller.cluster.datastore.messages.BatchedModifications)7 WriteModification (org.opendaylight.controller.cluster.datastore.modification.WriteModification)7 ContainerNode (org.opendaylight.yangtools.yang.data.api.schema.ContainerNode)7 DataTree (org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree)7 LocalHistoryIdentifier (org.opendaylight.controller.cluster.access.concepts.LocalHistoryIdentifier)6 CanCommit (org.opendaylight.controller.cluster.datastore.DataTreeCohortActor.CanCommit)6 Failure (akka.actor.Status.Failure)5 Timeout (akka.util.Timeout)5 Response (org.opendaylight.controller.cluster.access.concepts.Response)5 ReadyLocalTransaction (org.opendaylight.controller.cluster.datastore.messages.ReadyLocalTransaction)5