Search in sources :

Example 11 with DOMStoreThreePhaseCommitCohort

use of org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort in project controller by opendaylight.

the class DistributedDataStoreRemotingIntegrationTest method testTransactionChainWithMultipleShards.

@Test
public void testTransactionChainWithMultipleShards() throws Exception {
    initDatastoresWithCarsAndPeople("testTransactionChainWithMultipleShards");
    final DOMStoreTransactionChain txChain = followerDistributedDataStore.createTransactionChain();
    DOMStoreWriteTransaction writeTx = txChain.newWriteOnlyTransaction();
    assertNotNull("newWriteOnlyTransaction returned null", writeTx);
    writeTx.write(CarsModel.BASE_PATH, CarsModel.emptyContainer());
    writeTx.write(PeopleModel.BASE_PATH, PeopleModel.emptyContainer());
    writeTx.write(CarsModel.CAR_LIST_PATH, CarsModel.newCarMapNode());
    writeTx.write(PeopleModel.PERSON_LIST_PATH, PeopleModel.newPersonMapNode());
    followerTestKit.doCommit(writeTx.ready());
    final DOMStoreReadWriteTransaction readWriteTx = txChain.newReadWriteTransaction();
    final MapEntryNode car = CarsModel.newCarEntry("optima", BigInteger.valueOf(20000));
    final YangInstanceIdentifier carPath = CarsModel.newCarPath("optima");
    readWriteTx.write(carPath, car);
    final MapEntryNode person = PeopleModel.newPersonEntry("jack");
    final YangInstanceIdentifier personPath = PeopleModel.newPersonPath("jack");
    readWriteTx.merge(personPath, person);
    Optional<NormalizedNode<?, ?>> optional = readWriteTx.read(carPath).get(5, TimeUnit.SECONDS);
    assertEquals("isPresent", true, optional.isPresent());
    assertEquals("Data node", car, optional.get());
    optional = readWriteTx.read(personPath).get(5, TimeUnit.SECONDS);
    assertEquals("isPresent", true, optional.isPresent());
    assertEquals("Data node", person, optional.get());
    final DOMStoreThreePhaseCommitCohort cohort2 = readWriteTx.ready();
    writeTx = txChain.newWriteOnlyTransaction();
    writeTx.delete(personPath);
    final DOMStoreThreePhaseCommitCohort cohort3 = writeTx.ready();
    followerTestKit.doCommit(cohort2);
    followerTestKit.doCommit(cohort3);
    txChain.close();
    final DOMStoreReadTransaction readTx = followerDistributedDataStore.newReadOnlyTransaction();
    verifyCars(readTx, car);
    optional = readTx.read(personPath).get(5, TimeUnit.SECONDS);
    assertEquals("isPresent", false, optional.isPresent());
}
Also used : DOMStoreWriteTransaction(org.opendaylight.mdsal.dom.spi.store.DOMStoreWriteTransaction) DOMStoreReadTransaction(org.opendaylight.mdsal.dom.spi.store.DOMStoreReadTransaction) DOMStoreTransactionChain(org.opendaylight.mdsal.dom.spi.store.DOMStoreTransactionChain) DOMStoreReadWriteTransaction(org.opendaylight.mdsal.dom.spi.store.DOMStoreReadWriteTransaction) MapEntryNode(org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode) NormalizedNode(org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode) YangInstanceIdentifier(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier) DOMStoreThreePhaseCommitCohort(org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort) Test(org.junit.Test)

Example 12 with DOMStoreThreePhaseCommitCohort

use of org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort in project controller by opendaylight.

the class DistributedDataStoreRemotingIntegrationTest method testTransactionWithIsolatedLeader.

@Test
public void testTransactionWithIsolatedLeader() throws Exception {
    // TODO remove when test passes also for ClientBackedDataStore
    Assume.assumeTrue(testParameter.equals(DistributedDataStore.class));
    // Set the isolated leader check interval high so we can control the switch to IsolatedLeader.
    leaderDatastoreContextBuilder.shardIsolatedLeaderCheckIntervalInMillis(10000000);
    final String testName = "testTransactionWithIsolatedLeader";
    initDatastoresWithCars(testName);
    // Tx that is submitted after the follower is stopped but before the leader transitions to IsolatedLeader.
    final DOMStoreWriteTransaction preIsolatedLeaderWriteTx = leaderDistributedDataStore.newWriteOnlyTransaction();
    preIsolatedLeaderWriteTx.write(CarsModel.BASE_PATH, CarsModel.emptyContainer());
    // Tx that is submitted after the leader transitions to IsolatedLeader.
    final DOMStoreWriteTransaction noShardLeaderWriteTx = leaderDistributedDataStore.newWriteOnlyTransaction();
    noShardLeaderWriteTx.write(CarsModel.BASE_PATH, CarsModel.emptyContainer());
    // Tx that is submitted after the follower is reinstated.
    final DOMStoreWriteTransaction successWriteTx = leaderDistributedDataStore.newWriteOnlyTransaction();
    successWriteTx.merge(CarsModel.BASE_PATH, CarsModel.emptyContainer());
    // Stop the follower
    followerTestKit.watch(followerDistributedDataStore.getActorContext().getShardManager());
    followerDistributedDataStore.close();
    followerTestKit.expectTerminated(followerDistributedDataStore.getActorContext().getShardManager());
    // Submit the preIsolatedLeaderWriteTx so it's pending
    final DOMStoreThreePhaseCommitCohort preIsolatedLeaderTxCohort = preIsolatedLeaderWriteTx.ready();
    // Change the isolated leader check interval low so it changes to IsolatedLeader.
    sendDatastoreContextUpdate(leaderDistributedDataStore, leaderDatastoreContextBuilder.shardIsolatedLeaderCheckIntervalInMillis(200));
    MemberNode.verifyRaftState(leaderDistributedDataStore, "cars", raftState -> assertEquals("getRaftState", "IsolatedLeader", raftState.getRaftState()));
    try {
        leaderTestKit.doCommit(noShardLeaderWriteTx.ready());
        fail("Expected NoShardLeaderException");
    } catch (final ExecutionException e) {
        assertEquals("getCause", NoShardLeaderException.class, Throwables.getRootCause(e).getClass());
    }
    sendDatastoreContextUpdate(leaderDistributedDataStore, leaderDatastoreContextBuilder.shardElectionTimeoutFactor(100));
    final DOMStoreThreePhaseCommitCohort successTxCohort = successWriteTx.ready();
    followerDistributedDataStore = followerTestKit.setupAbstractDataStore(testParameter, testName, MODULE_SHARDS_CARS_ONLY_1_2, false, CARS);
    leaderTestKit.doCommit(preIsolatedLeaderTxCohort);
    leaderTestKit.doCommit(successTxCohort);
}
Also used : DOMStoreWriteTransaction(org.opendaylight.mdsal.dom.spi.store.DOMStoreWriteTransaction) AddressFromURIString(akka.actor.AddressFromURIString) ExecutionException(java.util.concurrent.ExecutionException) DOMStoreThreePhaseCommitCohort(org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort) NoShardLeaderException(org.opendaylight.controller.cluster.datastore.exceptions.NoShardLeaderException) Test(org.junit.Test)

Example 13 with DOMStoreThreePhaseCommitCohort

use of org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort in project controller by opendaylight.

the class DistributedDataStoreRemotingIntegrationTest method testTransactionChainWithSingleShard.

@Test
public void testTransactionChainWithSingleShard() throws Exception {
    initDatastoresWithCars("testTransactionChainWithSingleShard");
    final DOMStoreTransactionChain txChain = followerDistributedDataStore.createTransactionChain();
    // Add the top-level cars container with write-only.
    final DOMStoreWriteTransaction writeTx = txChain.newWriteOnlyTransaction();
    assertNotNull("newWriteOnlyTransaction returned null", writeTx);
    writeTx.write(CarsModel.BASE_PATH, CarsModel.emptyContainer());
    final DOMStoreThreePhaseCommitCohort writeTxReady = writeTx.ready();
    // Verify the top-level cars container with read-only.
    verifyNode(txChain.newReadOnlyTransaction(), CarsModel.BASE_PATH, CarsModel.emptyContainer());
    // Perform car operations with read-write.
    final DOMStoreReadWriteTransaction rwTx = txChain.newReadWriteTransaction();
    verifyNode(rwTx, CarsModel.BASE_PATH, CarsModel.emptyContainer());
    rwTx.merge(CarsModel.CAR_LIST_PATH, CarsModel.newCarMapNode());
    final MapEntryNode car1 = CarsModel.newCarEntry("optima", BigInteger.valueOf(20000));
    final YangInstanceIdentifier car1Path = CarsModel.newCarPath("optima");
    rwTx.write(car1Path, car1);
    verifyExists(rwTx, car1Path);
    verifyCars(rwTx, car1);
    final MapEntryNode car2 = CarsModel.newCarEntry("sportage", BigInteger.valueOf(25000));
    rwTx.merge(CarsModel.newCarPath("sportage"), car2);
    rwTx.delete(car1Path);
    followerTestKit.doCommit(writeTxReady);
    followerTestKit.doCommit(rwTx.ready());
    txChain.close();
    verifyCars(followerDistributedDataStore.newReadOnlyTransaction(), car2);
}
Also used : DOMStoreWriteTransaction(org.opendaylight.mdsal.dom.spi.store.DOMStoreWriteTransaction) DOMStoreTransactionChain(org.opendaylight.mdsal.dom.spi.store.DOMStoreTransactionChain) DOMStoreReadWriteTransaction(org.opendaylight.mdsal.dom.spi.store.DOMStoreReadWriteTransaction) MapEntryNode(org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode) YangInstanceIdentifier(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier) DOMStoreThreePhaseCommitCohort(org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort) Test(org.junit.Test)

Example 14 with DOMStoreThreePhaseCommitCohort

use of org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort in project controller by opendaylight.

the class DistributedDataStoreRemotingIntegrationTest method testTransactionForwardedToLeaderAfterRetry.

@Test
public void testTransactionForwardedToLeaderAfterRetry() throws Exception {
    // TODO remove when test passes also for ClientBackedDataStore
    Assume.assumeTrue(testParameter.equals(DistributedDataStore.class));
    followerDatastoreContextBuilder.shardBatchedModificationCount(2);
    leaderDatastoreContextBuilder.shardBatchedModificationCount(2);
    initDatastoresWithCarsAndPeople("testTransactionForwardedToLeaderAfterRetry");
    // Do an initial write to get the primary shard info cached.
    final DOMStoreWriteTransaction initialWriteTx = followerDistributedDataStore.newWriteOnlyTransaction();
    initialWriteTx.write(CarsModel.BASE_PATH, CarsModel.emptyContainer());
    initialWriteTx.write(PeopleModel.BASE_PATH, PeopleModel.emptyContainer());
    followerTestKit.doCommit(initialWriteTx.ready());
    // Wait for the commit to be replicated to the follower.
    MemberNode.verifyRaftState(followerDistributedDataStore, "cars", raftState -> assertEquals("getLastApplied", 1, raftState.getLastApplied()));
    MemberNode.verifyRaftState(followerDistributedDataStore, "people", raftState -> assertEquals("getLastApplied", 1, raftState.getLastApplied()));
    // Prepare, ready and canCommit a WO tx that writes to 2 shards. This will become the current tx in
    // the leader shard.
    final DOMStoreWriteTransaction writeTx1 = followerDistributedDataStore.newWriteOnlyTransaction();
    writeTx1.write(CarsModel.CAR_LIST_PATH, CarsModel.newCarMapNode());
    writeTx1.write(PeopleModel.BASE_PATH, PeopleModel.emptyContainer());
    final DOMStoreThreePhaseCommitCohort writeTx1Cohort = writeTx1.ready();
    final ListenableFuture<Boolean> writeTx1CanCommit = writeTx1Cohort.canCommit();
    writeTx1CanCommit.get(5, TimeUnit.SECONDS);
    // Prepare and ready another WO tx that writes to 2 shards but don't canCommit yet. This will be queued
    // in the leader shard.
    final DOMStoreWriteTransaction writeTx2 = followerDistributedDataStore.newWriteOnlyTransaction();
    final LinkedList<MapEntryNode> cars = new LinkedList<>();
    int carIndex = 1;
    cars.add(CarsModel.newCarEntry("car" + carIndex, BigInteger.valueOf(carIndex)));
    writeTx2.write(CarsModel.newCarPath("car" + carIndex), cars.getLast());
    carIndex++;
    NormalizedNode<?, ?> people = PeopleModel.newPersonMapNode();
    writeTx2.write(PeopleModel.PERSON_LIST_PATH, people);
    final DOMStoreThreePhaseCommitCohort writeTx2Cohort = writeTx2.ready();
    // Prepare another WO that writes to a single shard and thus will be directly committed on ready. This
    // tx writes 5 cars so 2 BatchedModidifications messages will be sent initially and cached in the
    // leader shard (with shardBatchedModificationCount set to 2). The 3rd BatchedModidifications will be
    // sent on ready.
    final DOMStoreWriteTransaction writeTx3 = followerDistributedDataStore.newWriteOnlyTransaction();
    for (int i = 1; i <= 5; i++, carIndex++) {
        cars.add(CarsModel.newCarEntry("car" + carIndex, BigInteger.valueOf(carIndex)));
        writeTx3.write(CarsModel.newCarPath("car" + carIndex), cars.getLast());
    }
    // Prepare another WO that writes to a single shard. This will send a single BatchedModidifications
    // message on ready.
    final DOMStoreWriteTransaction writeTx4 = followerDistributedDataStore.newWriteOnlyTransaction();
    cars.add(CarsModel.newCarEntry("car" + carIndex, BigInteger.valueOf(carIndex)));
    writeTx4.write(CarsModel.newCarPath("car" + carIndex), cars.getLast());
    carIndex++;
    // Prepare a RW tx that will create a tx actor and send a ForwardedReadyTransaciton message to the
    // leader shard on ready.
    final DOMStoreReadWriteTransaction readWriteTx = followerDistributedDataStore.newReadWriteTransaction();
    cars.add(CarsModel.newCarEntry("car" + carIndex, BigInteger.valueOf(carIndex)));
    readWriteTx.write(CarsModel.newCarPath("car" + carIndex), cars.getLast());
    IntegrationTestKit.verifyShardStats(leaderDistributedDataStore, "cars", stats -> assertEquals("getReadWriteTransactionCount", 1, stats.getReadWriteTransactionCount()));
    // Disable elections on the leader so it switches to follower.
    sendDatastoreContextUpdate(leaderDistributedDataStore, leaderDatastoreContextBuilder.customRaftPolicyImplementation(DisableElectionsRaftPolicy.class.getName()).shardElectionTimeoutFactor(10));
    leaderTestKit.waitUntilNoLeader(leaderDistributedDataStore.getActorContext(), "cars");
    // Submit all tx's - the messages should get queued for retry.
    final ListenableFuture<Boolean> writeTx2CanCommit = writeTx2Cohort.canCommit();
    final DOMStoreThreePhaseCommitCohort writeTx3Cohort = writeTx3.ready();
    final DOMStoreThreePhaseCommitCohort writeTx4Cohort = writeTx4.ready();
    final DOMStoreThreePhaseCommitCohort rwTxCohort = readWriteTx.ready();
    // Enable elections on the other follower so it becomes the leader, at which point the
    // tx's should get forwarded from the previous leader to the new leader to complete the commits.
    sendDatastoreContextUpdate(followerDistributedDataStore, followerDatastoreContextBuilder.customRaftPolicyImplementation(null).shardElectionTimeoutFactor(1));
    IntegrationTestKit.findLocalShard(followerDistributedDataStore.getActorContext(), "cars").tell(TimeoutNow.INSTANCE, ActorRef.noSender());
    IntegrationTestKit.findLocalShard(followerDistributedDataStore.getActorContext(), "people").tell(TimeoutNow.INSTANCE, ActorRef.noSender());
    followerTestKit.doCommit(writeTx1CanCommit, writeTx1Cohort);
    followerTestKit.doCommit(writeTx2CanCommit, writeTx2Cohort);
    followerTestKit.doCommit(writeTx3Cohort);
    followerTestKit.doCommit(writeTx4Cohort);
    followerTestKit.doCommit(rwTxCohort);
    DOMStoreReadTransaction readTx = leaderDistributedDataStore.newReadOnlyTransaction();
    verifyCars(readTx, cars.toArray(new MapEntryNode[cars.size()]));
    verifyNode(readTx, PeopleModel.PERSON_LIST_PATH, people);
}
Also used : DOMStoreWriteTransaction(org.opendaylight.mdsal.dom.spi.store.DOMStoreWriteTransaction) DOMStoreReadTransaction(org.opendaylight.mdsal.dom.spi.store.DOMStoreReadTransaction) DOMStoreReadWriteTransaction(org.opendaylight.mdsal.dom.spi.store.DOMStoreReadWriteTransaction) MapEntryNode(org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode) DOMStoreThreePhaseCommitCohort(org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort) LinkedList(java.util.LinkedList) DisableElectionsRaftPolicy(org.opendaylight.controller.cluster.raft.policy.DisableElectionsRaftPolicy) Test(org.junit.Test)

Example 15 with DOMStoreThreePhaseCommitCohort

use of org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort in project controller by opendaylight.

the class DataTreeCohortIntegrationTest method testFailedCanCommit.

@SuppressWarnings("unchecked")
@Test
public void testFailedCanCommit() throws Exception {
    final DOMDataTreeCommitCohort failedCohort = mock(DOMDataTreeCommitCohort.class);
    doReturn(FAILED_CAN_COMMIT_FUTURE).when(failedCohort).canCommit(any(Object.class), any(Collection.class), any(SchemaContext.class));
    IntegrationTestKit kit = new IntegrationTestKit(getSystem(), datastoreContextBuilder);
    try (AbstractDataStore dataStore = kit.setupAbstractDataStore(DistributedDataStore.class, "testFailedCanCommit", "test-1")) {
        dataStore.registerCommitCohort(TEST_ID, failedCohort);
        IntegrationTestKit.verifyShardState(dataStore, "test-1", state -> assertEquals("Cohort registrations", 1, state.getCommitCohortActors().size()));
        DOMStoreWriteTransaction writeTx = dataStore.newWriteOnlyTransaction();
        writeTx.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
        DOMStoreThreePhaseCommitCohort dsCohort = writeTx.ready();
        try {
            dsCohort.canCommit().get(5, TimeUnit.SECONDS);
            fail("Exception should be raised.");
        } catch (ExecutionException e) {
            assertSame(FAILED_CAN_COMMIT, Throwables.getRootCause(e));
        }
    }
}
Also used : DOMStoreWriteTransaction(org.opendaylight.mdsal.dom.spi.store.DOMStoreWriteTransaction) Collection(java.util.Collection) SchemaContext(org.opendaylight.yangtools.yang.model.api.SchemaContext) ExecutionException(java.util.concurrent.ExecutionException) DOMDataTreeCommitCohort(org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohort) DOMStoreThreePhaseCommitCohort(org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort) Test(org.junit.Test)

Aggregations

DOMStoreThreePhaseCommitCohort (org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort)40 Test (org.junit.Test)31 DOMStoreWriteTransaction (org.opendaylight.mdsal.dom.spi.store.DOMStoreWriteTransaction)17 ActorRef (akka.actor.ActorRef)11 TransactionCommitFailedException (org.opendaylight.mdsal.common.api.TransactionCommitFailedException)11 NormalizedNodeAggregatorTest (org.opendaylight.controller.cluster.datastore.utils.NormalizedNodeAggregatorTest)10 DOMStoreReadTransaction (org.opendaylight.mdsal.dom.spi.store.DOMStoreReadTransaction)8 DOMStoreReadWriteTransaction (org.opendaylight.mdsal.dom.spi.store.DOMStoreReadWriteTransaction)8 NormalizedNode (org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode)8 CountDownLatch (java.util.concurrent.CountDownLatch)6 ExecutionException (java.util.concurrent.ExecutionException)6 NoShardLeaderException (org.opendaylight.controller.cluster.datastore.exceptions.NoShardLeaderException)6 CommitTransactionReply (org.opendaylight.controller.cluster.datastore.messages.CommitTransactionReply)6 ReadFailedException (org.opendaylight.mdsal.common.api.ReadFailedException)6 AddressFromURIString (akka.actor.AddressFromURIString)5 BatchedModifications (org.opendaylight.controller.cluster.datastore.messages.BatchedModifications)5 DOMStoreTransactionChain (org.opendaylight.mdsal.dom.spi.store.DOMStoreTransactionChain)5 YangInstanceIdentifier (org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier)5 MapEntryNode (org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode)5 IOException (java.io.IOException)4