From c9543ea06b176ae07a205abe29fc385a7b7548ad Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Wed, 23 Mar 2022 18:31:39 +0100 Subject: [PATCH] Fix ChoiceNodeContextNode's byQName indexing When we are traversing by provided QName, we are meant to encounter each ContextNode significant to PathArgument construction. This works for all cases except for 'choice->case->choice', where ChoiceNodeContextNode's internal indexing does not account for itself: it ends up storing the second ChoiceNodeContextNode under the ChoiceSchemaNode's QName -- and therefore it fails to find it by its consituents' QNames. This has impact primarily on instance-identifier parsers, as evidenced by the corresponding JSON-based unit test. Fix this by properly overriding getQNameIdentifiers() to provide the internal table's keySet(). JIRA: YANGTOOLS-1411 Change-Id: I11df2d4072157e06342c2899dbcf02f74eef8090 Signed-off-by: Robert Varga --- .../codec/gson/AbstractComplexJsonTest.java | 4 +- .../yang/data/codec/gson/YT1411Test.java | 69 +++++++++++++++++++ .../yang/data/util/ChoiceNodeContextNode.java | 6 ++ 3 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 codec/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/YT1411Test.java diff --git a/codec/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/AbstractComplexJsonTest.java b/codec/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/AbstractComplexJsonTest.java index a8815f56ff..c68033032a 100644 --- a/codec/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/AbstractComplexJsonTest.java +++ b/codec/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/AbstractComplexJsonTest.java @@ -20,10 +20,12 @@ import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils; public abstract class AbstractComplexJsonTest { static final QName CONT_1 = QName.create("ns:complex:json", "2014-08-11", "cont1"); + static final NodeIdentifier CONT_1_NODEID = new NodeIdentifier(CONT_1); + private static final QName EMPTY_LEAF = QName.create(CONT_1, "empty"); static final ContainerNode CONT1_WITH_EMPTYLEAF = Builders.containerBuilder() - .withNodeIdentifier(new NodeIdentifier(CONT_1)) + .withNodeIdentifier(CONT_1_NODEID) .addChild(ImmutableNodes.leafNode(EMPTY_LEAF, Empty.value())) .build(); diff --git a/codec/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/YT1411Test.java b/codec/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/YT1411Test.java new file mode 100644 index 0000000000..6e37b346cd --- /dev/null +++ b/codec/yang-data-codec-gson/src/test/java/org/opendaylight/yangtools/yang/data/codec/gson/YT1411Test.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2022 PANTHEON.tech, s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.yang.data.codec.gson; + +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertEquals; + +import com.google.gson.stream.JsonReader; +import java.io.StringReader; +import java.util.Map; +import java.util.Set; +import org.junit.Test; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates; +import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; +import org.opendaylight.yangtools.yang.data.api.schema.LeafNode; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes; +import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter; +import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult; + +public class YT1411Test extends AbstractComplexJsonTest { + @Test + public void testChoiceCaseChoiceIdentifier() { + final var result = new NormalizedNodeResult(); + final var streamWriter = ImmutableNormalizedNodeStreamWriter.from(result); + final var jsonParser = JsonParserStream.create(streamWriter, + JSONCodecFactorySupplier.RFC7951.getShared(schemaContext)); + jsonParser.parse(new JsonReader(new StringReader("{\n" + + " \"complexjson:cont1\": {\n" + + " \"lst11\": [\n" + + " {\n" + + " \"key111\": \"foo\",\n" + + " \"lf111\": \"bar\",\n" + + " \"lf112\": \"/complexjson:cont1/case11-choice-case-container\"\n" + + " }\n" + + " ]\n" + + " }\n" + + "}"))); + final var cont1 = result.getResult(); + assertThat(cont1, instanceOf(ContainerNode.class)); + + final QName lst11 = QName.create(CONT_1, "lst11"); + final var lf112 = NormalizedNodes.findNode(cont1, + new NodeIdentifier(lst11), + NodeIdentifierWithPredicates.of(lst11, + Map.of(QName.create(CONT_1, "key111"), "foo", QName.create(CONT_1, "lf111"), "bar")), + new NodeIdentifier(QName.create(CONT_1, "lf112"))) + .orElseThrow(); + assertThat(lf112, instanceOf(LeafNode.class)); + + final QName augmentChoice1 = QName.create(CONT_1, "augment-choice1"); + assertEquals(YangInstanceIdentifier.create( + CONT_1_NODEID, + AugmentationIdentifier.create(Set.of(augmentChoice1)), + new NodeIdentifier(augmentChoice1), + new NodeIdentifier(QName.create(CONT_1, "augment-choice2")), + new NodeIdentifier(QName.create(CONT_1, "case11-choice-case-container"))), + ((LeafNode) lf112).body()); + } +} diff --git a/data/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/ChoiceNodeContextNode.java b/data/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/ChoiceNodeContextNode.java index 7cd43d7b81..a93d1f1883 100644 --- a/data/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/ChoiceNodeContextNode.java +++ b/data/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/ChoiceNodeContextNode.java @@ -8,6 +8,7 @@ package org.opendaylight.yangtools.yang.data.util; import com.google.common.collect.ImmutableMap; +import java.util.Set; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; @@ -46,4 +47,9 @@ final class ChoiceNodeContextNode extends AbstractMixinContextNode getChild(final QName child) { return byQName.get(child); } + + @Override + protected Set getQNameIdentifiers() { + return byQName.keySet(); + } } -- 2.36.6