Fix nested augmentations 35/101035/11
authorRobert Varga <robert.varga@pantheon.tech>
Tue, 10 May 2022 06:01:21 +0000 (08:01 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Tue, 10 May 2022 19:41:52 +0000 (21:41 +0200)
When we are entering an augmentation, we need to look at the effective
instantiation. For DataNodeContainers that means using
EffectiveAugmentationSchema to get the correct filter, for choices we do
not have a utility, so just retain the same parent.

JIRA: YANGTOOLS-1433
Change-Id: I0aa36499a5bcf6088be5b49b79d202f8985f5eca
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
data/yang-data-api/pom.xml
data/yang-data-api/src/main/java/module-info.java
data/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/stream/YangInstanceIdentifierWriter.java
data/yang-data-api/src/test/java/org/opendaylight/yangtools/yang/data/api/schema/stream/YT1433Test.java [new file with mode: 0644]
data/yang-data-api/src/test/resources/YT1433/bar.yang [new file with mode: 0644]
data/yang-data-api/src/test/resources/YT1433/foo.yang [new file with mode: 0644]

index 6f9f7107a1c616cf5a461c77deb55e0261574378..97e3fd5aeccefbc56418492cd45235cd0abe7d51 100644 (file)
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>yang-model-api</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>yang-model-util</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.immutables</groupId>
             <artifactId>value</artifactId>
index 55f01a1fa2fd460a180c3a4d6a001548272db341..1c8c7cd8b57303a0b9f1afb795adae3c6a78454e 100644 (file)
@@ -19,6 +19,7 @@ module org.opendaylight.yangtools.yang.data.api {
     requires transitive org.opendaylight.yangtools.util;
     requires transitive org.opendaylight.yangtools.yang.common;
     requires transitive org.opendaylight.yangtools.yang.model.api;
+    requires org.opendaylight.yangtools.yang.model.util;
     requires org.slf4j;
 
     // Annotations
index 6eca0982e4b8f5460daebcca764ea56c345b5193..4976ec62e386f3b926d2d49a5523c8808015496d 100644 (file)
@@ -37,6 +37,7 @@ import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+import org.opendaylight.yangtools.yang.model.util.EffectiveAugmentationSchema;
 
 /**
  * Utility for emitting a {@link YangInstanceIdentifier} into a {@link NormalizedNodeStreamWriter} as a set of
@@ -97,13 +98,19 @@ public final class YangInstanceIdentifierWriter implements AutoCloseable {
             final var arg = it.next();
             if (arg instanceof AugmentationIdentifier augId) {
                 if (!(parent instanceof AugmentationTarget target)) {
-                    throw new IOException(parent + " does not support augmentations, cannot resolve" + arg);
+                    throw new IOException(parent + " does not support augmentations, cannot resolve " + arg);
                 }
                 if (reuse) {
                     throw new IOException(parent + " is expecting a nested item, cannot resolve " + arg);
                 }
 
-                parent = enterAugmentation(target, augId);
+                if (target instanceof DataNodeContainer container) {
+                    parent = new EffectiveAugmentationSchema(enterAugmentation(target, augId), container);
+                } else if (target instanceof ChoiceSchemaNode) {
+                    throw new IOException(parent + " should not use addressing through " + arg);
+                } else {
+                    throw new IOException("Unhandled parent " + target + " while resolving " + arg);
+                }
                 writer.startAugmentationNode(augId);
             } else if (arg instanceof NodeWithValue<?> nodeId) {
                 if (!(parent instanceof LeafListSchemaNode)) {
diff --git a/data/yang-data-api/src/test/java/org/opendaylight/yangtools/yang/data/api/schema/stream/YT1433Test.java b/data/yang-data-api/src/test/java/org/opendaylight/yangtools/yang/data/api/schema/stream/YT1433Test.java
new file mode 100644 (file)
index 0000000..6bc5b5d
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * 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.api.schema.stream;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.io.IOException;
+import java.util.Set;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.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.model.api.EffectiveModelContext;
+import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
+
+public class YT1433Test {
+    private static EffectiveModelContext CONTEXT;
+
+    @BeforeAll
+    public static void beforeAll() {
+        CONTEXT = YangParserTestUtils.parseYangResourceDirectory("/YT1433");
+    }
+
+    @Test
+    public void testContainerAugmentContainer() throws IOException {
+        final FormattingNormalizedNodeStreamWriter streamWriter = new FormattingNormalizedNodeStreamWriter();
+
+        final QName bar = QName.create("foo", "bar");
+        final QName baz = QName.create("foo", "baz");
+
+        final YangInstanceIdentifier path = YangInstanceIdentifier.builder()
+            .node(QName.create("foo", "foo"))
+            .node(AugmentationIdentifier.create(Set.of(bar)))
+            .node(bar)
+            .node(AugmentationIdentifier.create(Set.of(baz)))
+            .node(baz)
+            .build();
+
+        try (var iidWriter = YangInstanceIdentifierWriter.open(streamWriter, CONTEXT, path)) {
+            try (var nnWriter = new NormalizedNodeWriter(streamWriter)) {
+                // No-op
+            }
+        }
+
+        assertEquals("(foo)foo(container)\n"
+            + "  AugmentationIdentifier{childNames=[(foo)bar]}(augmentation)\n"
+            + "    (foo)bar(container)\n"
+            + "      AugmentationIdentifier{childNames=[(foo)baz]}(augmentation)\n"
+            + "        (foo)baz(container)\n"
+            + "        (end)\n"
+            + "      (end)\n"
+            + "    (end)\n"
+            + "  (end)\n"
+            + "(end)\n", streamWriter.result());
+    }
+
+    @Test
+    public void testChoiceAugmentCointainer() throws IOException {
+        final FormattingNormalizedNodeStreamWriter streamWriter = new FormattingNormalizedNodeStreamWriter();
+
+        final QName bar = QName.create("bar", "bar");
+        final QName baz = QName.create("bar", "baz");
+
+        final YangInstanceIdentifier path = YangInstanceIdentifier.builder()
+            .node(QName.create("bar", "foo"))
+            .node(bar)
+            .node(baz)
+            .build();
+
+        try (var iidWriter = YangInstanceIdentifierWriter.open(streamWriter, CONTEXT, path)) {
+            try (var nnWriter = new NormalizedNodeWriter(streamWriter)) {
+                // No-op
+            }
+        }
+
+        assertEquals("(bar)foo(choice)\n"
+            + "  (bar)bar(container)\n"
+            + "    (bar)baz(container)\n"
+            + "    (end)\n"
+            + "  (end)\n"
+            + "(end)\n", streamWriter.result());
+    }
+}
diff --git a/data/yang-data-api/src/test/resources/YT1433/bar.yang b/data/yang-data-api/src/test/resources/YT1433/bar.yang
new file mode 100644 (file)
index 0000000..81ef6d5
--- /dev/null
@@ -0,0 +1,14 @@
+module bar {
+  namespace bar;
+  prefix bar;
+
+  choice foo;
+
+  augment /foo {
+    container bar;
+  }
+
+  augment /foo/bar/bar {
+    container baz;
+  }
+}
diff --git a/data/yang-data-api/src/test/resources/YT1433/foo.yang b/data/yang-data-api/src/test/resources/YT1433/foo.yang
new file mode 100644 (file)
index 0000000..129bc8b
--- /dev/null
@@ -0,0 +1,14 @@
+module foo {
+  namespace foo;
+  prefix foo;
+
+  container foo;
+
+  augment /foo {
+    container bar;
+  }
+
+  augment /foo/bar {
+    container baz;
+  }
+}