Search in sources :

Example 11 with MapEntryNode

use of org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode 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 12 with MapEntryNode

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

the class DataTreeCohortIntegrationTest method testCanCommitWithListEntries.

@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testCanCommitWithListEntries() throws Exception {
    final DOMDataTreeCommitCohort cohort = mock(DOMDataTreeCommitCohort.class);
    doReturn(PostCanCommitStep.NOOP_SUCCESS_FUTURE).when(cohort).canCommit(any(Object.class), any(Collection.class), any(SchemaContext.class));
    IntegrationTestKit kit = new IntegrationTestKit(getSystem(), datastoreContextBuilder);
    try (AbstractDataStore dataStore = kit.setupAbstractDataStore(DistributedDataStore.class, "testCanCommitWithMultipleListEntries", "cars-1")) {
        final ObjectRegistration<DOMDataTreeCommitCohort> cohortReg = dataStore.registerCommitCohort(new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, CarsModel.CAR_LIST_PATH.node(CarsModel.CAR_QNAME)), cohort);
        assertNotNull(cohortReg);
        IntegrationTestKit.verifyShardState(dataStore, "cars-1", state -> assertEquals("Cohort registrations", 1, state.getCommitCohortActors().size()));
        // First write an empty base container and verify the cohort isn't invoked.
        DOMStoreWriteTransaction writeTx = dataStore.newWriteOnlyTransaction();
        writeTx.write(CarsModel.BASE_PATH, CarsModel.emptyContainer());
        writeTx.write(CarsModel.CAR_LIST_PATH, CarsModel.newCarMapNode());
        kit.doCommit(writeTx.ready());
        verifyNoMoreInteractions(cohort);
        // Write a single car entry and verify the cohort is invoked.
        writeTx = dataStore.newWriteOnlyTransaction();
        final YangInstanceIdentifier optimaPath = CarsModel.newCarPath("optima");
        final MapEntryNode optimaNode = CarsModel.newCarEntry("optima", BigInteger.valueOf(20000));
        writeTx.write(optimaPath, optimaNode);
        kit.doCommit(writeTx.ready());
        ArgumentCaptor<Collection> candidateCapture = ArgumentCaptor.forClass(Collection.class);
        verify(cohort).canCommit(any(Object.class), candidateCapture.capture(), any(SchemaContext.class));
        assertDataTreeCandidate((DOMDataTreeCandidate) candidateCapture.getValue().iterator().next(), new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, optimaPath), ModificationType.WRITE, Optional.of(optimaNode), Optional.absent());
        // Write replace the cars container with 2 new car entries. The cohort should get invoked with 3
        // DOMDataTreeCandidates: once for each of the 2 new car entries (WRITE mod) and once for the deleted prior
        // car entry (DELETE mod).
        reset(cohort);
        doReturn(PostCanCommitStep.NOOP_SUCCESS_FUTURE).when(cohort).canCommit(any(Object.class), any(Collection.class), any(SchemaContext.class));
        writeTx = dataStore.newWriteOnlyTransaction();
        final YangInstanceIdentifier sportagePath = CarsModel.newCarPath("sportage");
        final MapEntryNode sportageNode = CarsModel.newCarEntry("sportage", BigInteger.valueOf(20000));
        final YangInstanceIdentifier soulPath = CarsModel.newCarPath("soul");
        final MapEntryNode soulNode = CarsModel.newCarEntry("soul", BigInteger.valueOf(20000));
        writeTx.write(CarsModel.BASE_PATH, CarsModel.newCarsNode(CarsModel.newCarsMapNode(sportageNode, soulNode)));
        kit.doCommit(writeTx.ready());
        candidateCapture = ArgumentCaptor.forClass(Collection.class);
        verify(cohort).canCommit(any(Object.class), candidateCapture.capture(), any(SchemaContext.class));
        assertDataTreeCandidate(findCandidate(candidateCapture, sportagePath), new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, sportagePath), ModificationType.WRITE, Optional.of(sportageNode), Optional.absent());
        assertDataTreeCandidate(findCandidate(candidateCapture, soulPath), new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, soulPath), ModificationType.WRITE, Optional.of(soulNode), Optional.absent());
        assertDataTreeCandidate(findCandidate(candidateCapture, optimaPath), new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, optimaPath), ModificationType.DELETE, Optional.absent(), Optional.of(optimaNode));
        // Delete the cars container - cohort should be invoked for the 2 deleted car entries.
        reset(cohort);
        doReturn(PostCanCommitStep.NOOP_SUCCESS_FUTURE).when(cohort).canCommit(any(Object.class), any(Collection.class), any(SchemaContext.class));
        writeTx = dataStore.newWriteOnlyTransaction();
        writeTx.delete(CarsModel.BASE_PATH);
        kit.doCommit(writeTx.ready());
        candidateCapture = ArgumentCaptor.forClass(Collection.class);
        verify(cohort).canCommit(any(Object.class), candidateCapture.capture(), any(SchemaContext.class));
        assertDataTreeCandidate(findCandidate(candidateCapture, sportagePath), new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, sportagePath), ModificationType.DELETE, Optional.absent(), Optional.of(sportageNode));
        assertDataTreeCandidate(findCandidate(candidateCapture, soulPath), new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, soulPath), ModificationType.DELETE, Optional.absent(), Optional.of(soulNode));
    }
}
Also used : DOMDataTreeIdentifier(org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier) DOMStoreWriteTransaction(org.opendaylight.mdsal.dom.spi.store.DOMStoreWriteTransaction) Collection(java.util.Collection) SchemaContext(org.opendaylight.yangtools.yang.model.api.SchemaContext) MapEntryNode(org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode) DOMDataTreeCommitCohort(org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohort) YangInstanceIdentifier(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier) Test(org.junit.Test)

Example 13 with MapEntryNode

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

the class AbstractEntityOwnershipTest method verifyEntityCandidate.

protected void verifyEntityCandidate(final NormalizedNode<?, ?> node, final String entityType, final YangInstanceIdentifier entityId, final String candidateName, final boolean expectPresent) {
    try {
        assertNotNull("Missing " + EntityOwners.QNAME.toString(), node);
        assertTrue(node instanceof ContainerNode);
        ContainerNode entityOwnersNode = (ContainerNode) node;
        MapEntryNode entityTypeEntry = getMapEntryNodeChild(entityOwnersNode, EntityType.QNAME, ENTITY_TYPE_QNAME, entityType, true);
        MapEntryNode entityEntry = getMapEntryNodeChild(entityTypeEntry, ENTITY_QNAME, ENTITY_ID_QNAME, entityId, true);
        getMapEntryNodeChild(entityEntry, Candidate.QNAME, CANDIDATE_NAME_QNAME, candidateName, expectPresent);
    } catch (AssertionError e) {
        throw new AssertionError("Verification of entity candidate failed - returned data was: " + node, e);
    }
}
Also used : ContainerNode(org.opendaylight.yangtools.yang.data.api.schema.ContainerNode) DataContainerNode(org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode) MapEntryNode(org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode)

Example 14 with MapEntryNode

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

the class AbstractDataChangeListenerTest method writeOneTopMultipleNested.

public static final WriteTransactionCustomizer writeOneTopMultipleNested(final String topName, final String... nestedName) {
    final CollectionNodeBuilder<MapEntryNode, OrderedMapNode> nestedMapBuilder = nestedMap();
    for (final String nestedItem : nestedName) {
        nestedMapBuilder.addChild(nestedList(nestedItem).build());
    }
    final ContainerNode data = top().addChild(topLevelMap().addChild(topLevelList(topName).addChild(nestedMapBuilder.build()).build()).build()).build();
    return DatastoreTestTask.simpleWrite(TOP_LEVEL, data);
}
Also used : OrderedMapNode(org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode) ContainerNode(org.opendaylight.yangtools.yang.data.api.schema.ContainerNode) MapEntryNode(org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode)

Example 15 with MapEntryNode

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

the class BindingContext method parseDataElement.

public NormalizedNode<?, ?> parseDataElement(final Element element, final DataSchemaNode dataSchema, final SchemaContext schemaContext) throws XMLStreamException, IOException, ParserConfigurationException, SAXException, URISyntaxException {
    final NormalizedNodeResult resultHolder = new NormalizedNodeResult();
    final NormalizedNodeStreamWriter writer = ImmutableNormalizedNodeStreamWriter.from(resultHolder);
    final XmlParserStream xmlParser = XmlParserStream.create(writer, schemaContext, dataSchema);
    xmlParser.traverse(new DOMSource(element));
    final NormalizedNode<?, ?> result = resultHolder.getResult();
    if (result instanceof MapNode) {
        final MapNode mapNode = (MapNode) result;
        final MapEntryNode mapEntryNode = mapNode.getValue().iterator().next();
        return mapEntryNode;
    }
    return result;
}
Also used : XmlParserStream(org.opendaylight.yangtools.yang.data.codec.xml.XmlParserStream) DOMSource(javax.xml.transform.dom.DOMSource) NormalizedNodeResult(org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult) ImmutableNormalizedNodeStreamWriter(org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter) NormalizedNodeStreamWriter(org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter) MapNode(org.opendaylight.yangtools.yang.data.api.schema.MapNode) MapEntryNode(org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode)

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