Search in sources :

Example 51 with MapEntryNode

use of org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode in project controller by opendaylight.

the class DOMDataTreeListenerTest method listEntryChangeNonRootRegistrationTest.

@Test
public void listEntryChangeNonRootRegistrationTest() throws InterruptedException, TransactionCommitFailedException {
    final CountDownLatch latch = new CountDownLatch(2);
    DOMDataTreeChangeService dataTreeChangeService = getDOMDataTreeChangeService();
    assertNotNull("DOMDataTreeChangeService not found, cannot continue with test!", dataTreeChangeService);
    DOMDataWriteTransaction writeTx = domBroker.newWriteOnlyTransaction();
    writeTx.put(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH, TEST_CONTAINER);
    writeTx.submit().checkedGet();
    final TestDataTreeListener listener = new TestDataTreeListener(latch);
    final ListenerRegistration<TestDataTreeListener> listenerReg = dataTreeChangeService.registerDataTreeChangeListener(OUTER_LIST_DATA_TREE_ID, listener);
    final YangInstanceIdentifier.NodeIdentifierWithPredicates outerListEntryId1 = new YangInstanceIdentifier.NodeIdentifierWithPredicates(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, 1);
    final YangInstanceIdentifier.NodeIdentifierWithPredicates outerListEntryId2 = new YangInstanceIdentifier.NodeIdentifierWithPredicates(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, 2);
    final YangInstanceIdentifier.NodeIdentifierWithPredicates outerListEntryId3 = new YangInstanceIdentifier.NodeIdentifierWithPredicates(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, 3);
    final MapEntryNode outerListEntry1 = ImmutableNodes.mapEntry(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, 1);
    final MapEntryNode outerListEntry2 = ImmutableNodes.mapEntry(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, 2);
    final MapEntryNode outerListEntry3 = ImmutableNodes.mapEntry(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, 3);
    final MapNode listAfter = ImmutableNodes.mapNodeBuilder(TestModel.OUTER_LIST_QNAME).withChild(outerListEntry2).withChild(outerListEntry3).build();
    writeTx = domBroker.newWriteOnlyTransaction();
    writeTx.delete(LogicalDatastoreType.CONFIGURATION, TestModel.OUTER_LIST_PATH.node(outerListEntryId1));
    writeTx.put(LogicalDatastoreType.CONFIGURATION, TestModel.OUTER_LIST_PATH.node(outerListEntryId2), outerListEntry2);
    writeTx.put(LogicalDatastoreType.CONFIGURATION, TestModel.OUTER_LIST_PATH.node(outerListEntryId3), outerListEntry3);
    writeTx.submit();
    latch.await(5, TimeUnit.SECONDS);
    assertEquals(2, listener.getReceivedChanges().size());
    Collection<DataTreeCandidate> changes = listener.getReceivedChanges().get(0);
    assertEquals(1, changes.size());
    DataTreeCandidate candidate = changes.iterator().next();
    assertNotNull(candidate);
    DataTreeCandidateNode candidateRoot = candidate.getRootNode();
    checkChange(null, OUTER_LIST, ModificationType.WRITE, candidateRoot);
    changes = listener.getReceivedChanges().get(1);
    assertEquals(1, changes.size());
    candidate = changes.iterator().next();
    assertNotNull(candidate);
    candidateRoot = candidate.getRootNode();
    checkChange(OUTER_LIST, listAfter, ModificationType.SUBTREE_MODIFIED, candidateRoot);
    final DataTreeCandidateNode entry1Canditate = candidateRoot.getModifiedChild(outerListEntryId1);
    checkChange(outerListEntry1, null, ModificationType.DELETE, entry1Canditate);
    final DataTreeCandidateNode entry2Canditate = candidateRoot.getModifiedChild(outerListEntryId2);
    checkChange(null, outerListEntry2, ModificationType.WRITE, entry2Canditate);
    final DataTreeCandidateNode entry3Canditate = candidateRoot.getModifiedChild(outerListEntryId3);
    checkChange(null, outerListEntry3, ModificationType.WRITE, entry3Canditate);
    listenerReg.close();
}
Also used : MapNode(org.opendaylight.yangtools.yang.data.api.schema.MapNode) CountDownLatch(java.util.concurrent.CountDownLatch) MapEntryNode(org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode) YangInstanceIdentifier(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier) DataTreeCandidate(org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate) DOMDataTreeChangeService(org.opendaylight.controller.md.sal.dom.api.DOMDataTreeChangeService) DataTreeCandidateNode(org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode) DOMDataWriteTransaction(org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction) Test(org.junit.Test)

Example 52 with MapEntryNode

use of org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode in project controller by opendaylight.

the class DistributedDataStoreIntegrationTest method testTransactionChainWithMultipleShards.

@Test
public void testTransactionChainWithMultipleShards() throws Exception {
    new IntegrationTestKit(getSystem(), datastoreContextBuilder) {

        {
            try (AbstractDataStore dataStore = setupAbstractDataStore(testParameter, "testTransactionChainWithMultipleShards", "cars-1", "people-1")) {
                final DOMStoreTransactionChain txChain = dataStore.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());
                final DOMStoreThreePhaseCommitCohort cohort1 = 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(carPath);
                final DOMStoreThreePhaseCommitCohort cohort3 = writeTx.ready();
                final ListenableFuture<Boolean> canCommit1 = cohort1.canCommit();
                final ListenableFuture<Boolean> canCommit2 = cohort2.canCommit();
                doCommit(canCommit1, cohort1);
                doCommit(canCommit2, cohort2);
                doCommit(cohort3);
                txChain.close();
                final DOMStoreReadTransaction readTx = dataStore.newReadOnlyTransaction();
                optional = readTx.read(carPath).get(5, TimeUnit.SECONDS);
                assertEquals("isPresent", false, optional.isPresent());
                optional = readTx.read(personPath).get(5, TimeUnit.SECONDS);
                assertEquals("isPresent", true, optional.isPresent());
                assertEquals("Data node", person, optional.get());
            }
        }
    };
}
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) YangInstanceIdentifier(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier) DOMStoreThreePhaseCommitCohort(org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort) NormalizedNode(org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode) Test(org.junit.Test)

Example 53 with MapEntryNode

use of org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode in project controller by opendaylight.

the class DistributedDataStoreRemotingIntegrationTest method testSingleShardTransactionsWithLeaderChanges.

@Test
public void testSingleShardTransactionsWithLeaderChanges() throws Exception {
    followerDatastoreContextBuilder.backendAlivenessTimerIntervalInSeconds(2);
    final String testName = "testSingleShardTransactionsWithLeaderChanges";
    initDatastoresWithCars(testName);
    final String followerCarShardName = "member-2-shard-cars-" + testName;
    InMemoryJournal.addWriteMessagesCompleteLatch(followerCarShardName, 1, ApplyJournalEntries.class);
    // Write top-level car container from the follower so it uses a remote Tx.
    DOMStoreWriteTransaction writeTx = followerDistributedDataStore.newWriteOnlyTransaction();
    writeTx.write(CarsModel.BASE_PATH, CarsModel.emptyContainer());
    writeTx.write(CarsModel.CAR_LIST_PATH, CarsModel.newCarMapNode());
    followerTestKit.doCommit(writeTx.ready());
    InMemoryJournal.waitForWriteMessagesComplete(followerCarShardName);
    // Switch the leader to the follower
    sendDatastoreContextUpdate(followerDistributedDataStore, followerDatastoreContextBuilder.shardElectionTimeoutFactor(1).customRaftPolicyImplementation(null));
    TestKit.shutdownActorSystem(leaderSystem, true);
    Cluster.get(followerSystem).leave(MEMBER_1_ADDRESS);
    followerTestKit.waitUntilNoLeader(followerDistributedDataStore.getActorContext(), CARS);
    leaderSystem = ActorSystem.create("cluster-test", ConfigFactory.load().getConfig("Member1"));
    Cluster.get(leaderSystem).join(MEMBER_2_ADDRESS);
    final DatastoreContext.Builder newMember1Builder = DatastoreContext.newBuilder().shardHeartbeatIntervalInMillis(100).shardElectionTimeoutFactor(5);
    IntegrationTestKit newMember1TestKit = new IntegrationTestKit(leaderSystem, newMember1Builder, commitTimeout);
    try (AbstractDataStore ds = newMember1TestKit.setupAbstractDataStore(testParameter, testName, MODULE_SHARDS_CARS_ONLY_1_2, false, CARS)) {
        followerTestKit.waitUntilLeader(followerDistributedDataStore.getActorContext(), CARS);
        // Write a car entry to the new leader - should switch to local Tx
        writeTx = followerDistributedDataStore.newWriteOnlyTransaction();
        MapEntryNode car1 = CarsModel.newCarEntry("optima", BigInteger.valueOf(20000));
        YangInstanceIdentifier car1Path = CarsModel.newCarPath("optima");
        writeTx.merge(car1Path, car1);
        followerTestKit.doCommit(writeTx.ready());
        verifyCars(followerDistributedDataStore.newReadOnlyTransaction(), car1);
    }
}
Also used : DOMStoreWriteTransaction(org.opendaylight.mdsal.dom.spi.store.DOMStoreWriteTransaction) Builder(org.opendaylight.controller.cluster.datastore.DatastoreContext.Builder) AddressFromURIString(akka.actor.AddressFromURIString) MapEntryNode(org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode) YangInstanceIdentifier(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier) Test(org.junit.Test)

Example 54 with MapEntryNode

use of org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode in project controller by opendaylight.

the class DistributedDataStoreRemotingIntegrationTest method testWriteTransactionWithSingleShard.

@Test
public void testWriteTransactionWithSingleShard() throws Exception {
    final String testName = "testWriteTransactionWithSingleShard";
    initDatastoresWithCars(testName);
    final String followerCarShardName = "member-2-shard-cars-" + testName;
    DOMStoreWriteTransaction writeTx = followerDistributedDataStore.newWriteOnlyTransaction();
    assertNotNull("newWriteOnlyTransaction returned null", writeTx);
    writeTx.write(CarsModel.BASE_PATH, CarsModel.emptyContainer());
    writeTx.write(CarsModel.CAR_LIST_PATH, CarsModel.newCarMapNode());
    final MapEntryNode car1 = CarsModel.newCarEntry("optima", BigInteger.valueOf(20000));
    final YangInstanceIdentifier car1Path = CarsModel.newCarPath("optima");
    writeTx.merge(car1Path, car1);
    final MapEntryNode car2 = CarsModel.newCarEntry("sportage", BigInteger.valueOf(25000));
    final YangInstanceIdentifier car2Path = CarsModel.newCarPath("sportage");
    writeTx.merge(car2Path, car2);
    followerTestKit.doCommit(writeTx.ready());
    verifyCars(followerDistributedDataStore.newReadOnlyTransaction(), car1, car2);
    verifyCars(leaderDistributedDataStore.newReadOnlyTransaction(), car1, car2);
    // Test delete
    writeTx = followerDistributedDataStore.newWriteOnlyTransaction();
    writeTx.delete(car1Path);
    followerTestKit.doCommit(writeTx.ready());
    verifyExists(followerDistributedDataStore.newReadOnlyTransaction(), car2Path);
    verifyCars(followerDistributedDataStore.newReadOnlyTransaction(), car2);
    verifyCars(leaderDistributedDataStore.newReadOnlyTransaction(), car2);
    // Re-instate the follower member 2 as a single-node to verify replication and recovery.
    // The following is a bit tricky. Before we reinstate the follower we need to ensure it has persisted and
    // applied and all the log entries from the leader. Since we've verified the car data above we know that
    // all the transactions have been applied on the leader so we first read and capture its lastAppliedIndex.
    final AtomicLong leaderLastAppliedIndex = new AtomicLong();
    IntegrationTestKit.verifyShardState(leaderDistributedDataStore, CARS[0], state -> leaderLastAppliedIndex.set(state.getLastApplied()));
    // Now we need to make sure the follower has persisted the leader's lastAppliedIndex via ApplyJournalEntries.
    // However we don't know exactly how many ApplyJournalEntries messages there will be as it can differ between
    // the tell-based and ask-based front-ends. For ask-based there will be exactly 2 ApplyJournalEntries but
    // tell-based persists additional payloads which could be replicated and applied in a batch resulting in
    // either 2 or 3 ApplyJournalEntries. To handle this we read the follower's persisted ApplyJournalEntries
    // until we find the one that encompasses the leader's lastAppliedIndex.
    Stopwatch sw = Stopwatch.createStarted();
    boolean done = false;
    while (!done) {
        final List<ApplyJournalEntries> entries = InMemoryJournal.get(followerCarShardName, ApplyJournalEntries.class);
        for (ApplyJournalEntries aje : entries) {
            if (aje.getToIndex() >= leaderLastAppliedIndex.get()) {
                done = true;
                break;
            }
        }
        assertTrue("Follower did not persist ApplyJournalEntries containing leader's lastAppliedIndex " + leaderLastAppliedIndex + ". Entries persisted: " + entries, sw.elapsed(TimeUnit.SECONDS) <= 5);
        Uninterruptibles.sleepUninterruptibly(50, TimeUnit.MILLISECONDS);
    }
    TestKit.shutdownActorSystem(leaderSystem, Boolean.TRUE);
    TestKit.shutdownActorSystem(followerSystem, Boolean.TRUE);
    final ActorSystem newSystem = newActorSystem("reinstated-member2", "Member2");
    try (AbstractDataStore member2Datastore = new IntegrationTestKit(newSystem, leaderDatastoreContextBuilder, commitTimeout).setupAbstractDataStore(testParameter, testName, "module-shards-member2", true, CARS)) {
        verifyCars(member2Datastore.newReadOnlyTransaction(), car2);
    }
}
Also used : ActorSystem(akka.actor.ActorSystem) AtomicLong(java.util.concurrent.atomic.AtomicLong) DOMStoreWriteTransaction(org.opendaylight.mdsal.dom.spi.store.DOMStoreWriteTransaction) ApplyJournalEntries(org.opendaylight.controller.cluster.raft.persisted.ApplyJournalEntries) Stopwatch(com.google.common.base.Stopwatch) AddressFromURIString(akka.actor.AddressFromURIString) MapEntryNode(org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode) YangInstanceIdentifier(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier) Test(org.junit.Test)

Example 55 with MapEntryNode

use of org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode in project controller by opendaylight.

the class DistributedDataStoreRemotingIntegrationTest method testLeadershipTransferOnShutdown.

@Test
public void testLeadershipTransferOnShutdown() throws Exception {
    // TODO remove when test passes also for ClientBackedDataStore
    Assume.assumeTrue(testParameter.equals(DistributedDataStore.class));
    leaderDatastoreContextBuilder.shardBatchedModificationCount(1);
    followerDatastoreContextBuilder.shardElectionTimeoutFactor(10).customRaftPolicyImplementation(null);
    final String testName = "testLeadershipTransferOnShutdown";
    initDatastores(testName, MODULE_SHARDS_CARS_PEOPLE_1_2_3, CARS_AND_PEOPLE);
    final IntegrationTestKit follower2TestKit = new IntegrationTestKit(follower2System, DatastoreContext.newBuilderFrom(followerDatastoreContextBuilder.build()).operationTimeoutInMillis(100), commitTimeout);
    try (AbstractDataStore follower2DistributedDataStore = follower2TestKit.setupAbstractDataStore(testParameter, testName, MODULE_SHARDS_CARS_PEOPLE_1_2_3, false)) {
        followerTestKit.waitForMembersUp("member-3");
        follower2TestKit.waitForMembersUp("member-1", "member-2");
        // Create and submit a couple tx's so they're pending.
        DOMStoreWriteTransaction writeTx = followerDistributedDataStore.newWriteOnlyTransaction();
        writeTx.write(CarsModel.BASE_PATH, CarsModel.emptyContainer());
        writeTx.write(CarsModel.CAR_LIST_PATH, CarsModel.newCarMapNode());
        writeTx.write(PeopleModel.BASE_PATH, PeopleModel.emptyContainer());
        final DOMStoreThreePhaseCommitCohort cohort1 = writeTx.ready();
        IntegrationTestKit.verifyShardStats(leaderDistributedDataStore, "cars", stats -> assertEquals("getTxCohortCacheSize", 1, stats.getTxCohortCacheSize()));
        writeTx = followerDistributedDataStore.newWriteOnlyTransaction();
        final MapEntryNode car = CarsModel.newCarEntry("optima", BigInteger.valueOf(20000));
        writeTx.write(CarsModel.newCarPath("optima"), car);
        final DOMStoreThreePhaseCommitCohort cohort2 = writeTx.ready();
        IntegrationTestKit.verifyShardStats(leaderDistributedDataStore, "cars", stats -> assertEquals("getTxCohortCacheSize", 2, stats.getTxCohortCacheSize()));
        // Gracefully stop the leader via a Shutdown message.
        sendDatastoreContextUpdate(leaderDistributedDataStore, leaderDatastoreContextBuilder.shardElectionTimeoutFactor(100));
        final FiniteDuration duration = FiniteDuration.create(5, TimeUnit.SECONDS);
        final Future<ActorRef> future = leaderDistributedDataStore.getActorContext().findLocalShardAsync("cars");
        final ActorRef leaderActor = Await.result(future, duration);
        final Future<Boolean> stopFuture = Patterns.gracefulStop(leaderActor, duration, Shutdown.INSTANCE);
        // Commit the 2 transactions. They should finish and succeed.
        followerTestKit.doCommit(cohort1);
        followerTestKit.doCommit(cohort2);
        // Wait for the leader actor stopped.
        final Boolean stopped = Await.result(stopFuture, duration);
        assertEquals("Stopped", Boolean.TRUE, stopped);
        // Verify leadership was transferred by reading the committed data from the other nodes.
        verifyCars(followerDistributedDataStore.newReadOnlyTransaction(), car);
        verifyCars(follower2DistributedDataStore.newReadOnlyTransaction(), car);
    }
}
Also used : DOMStoreWriteTransaction(org.opendaylight.mdsal.dom.spi.store.DOMStoreWriteTransaction) ActorRef(akka.actor.ActorRef) FiniteDuration(scala.concurrent.duration.FiniteDuration) AddressFromURIString(akka.actor.AddressFromURIString) MapEntryNode(org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode) DOMStoreThreePhaseCommitCohort(org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort) Test(org.junit.Test)

Aggregations

MapEntryNode (org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode)95 Test (org.junit.Test)55 NodeIdentifierWithPredicates (org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates)50 ArrayList (java.util.ArrayList)39 Flowspec (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev171207.flowspec.destination.Flowspec)34 FlowspecBuilder (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev171207.flowspec.destination.FlowspecBuilder)34 YangInstanceIdentifier (org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier)29 NumericOperand (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev171207.NumericOperand)20 MapNode (org.opendaylight.yangtools.yang.data.api.schema.MapNode)17 DestinationFlowspecBuilder (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev171207.flowspec.destination.ipv4.DestinationFlowspecBuilder)12 ContainerNode (org.opendaylight.yangtools.yang.data.api.schema.ContainerNode)11 NormalizedNode (org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode)10 DOMStoreWriteTransaction (org.opendaylight.mdsal.dom.spi.store.DOMStoreWriteTransaction)9 NodeIdentifier (org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier)9 DOMDataWriteTransaction (org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction)7 DOMStoreReadWriteTransaction (org.opendaylight.mdsal.dom.spi.store.DOMStoreReadWriteTransaction)6 Ipv4Prefix (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix)6 BitmaskOperand (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev171207.BitmaskOperand)6 BigInteger (java.math.BigInteger)5 TransactionCommitFailedException (org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException)5