Fix nested augmentations 57/101057/1
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 20:22:00 +0000 (22:22 +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>
(cherry picked from commit d79a5579918d5110599bdcc225c927c0225a177f)

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 8e19b31c3f512df61f366fecf1ae9d89719954a1..467161056883663f1a7b1e62c0a83332cffcb054 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 03588ede79e7a0a06a483c8652f27055971b8c47..40fad15103bec7beea5098dfe24f80eff356f735 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,14 +98,21 @@ public final class YangInstanceIdentifierWriter implements AutoCloseable {
             final var arg = it.next();
             if (arg instanceof AugmentationIdentifier) {
                 if (!(parent instanceof AugmentationTarget)) {
-                    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);
                 }
 
                 final var augId = (AugmentationIdentifier) arg;
-                parent = enterAugmentation((AugmentationTarget) parent, augId);
+                if (parent instanceof DataNodeContainer) {
+                    parent = new EffectiveAugmentationSchema(enterAugmentation((AugmentationTarget) parent, augId),
+                        (DataNodeContainer) parent);
+                } else if (parent instanceof ChoiceSchemaNode) {
+                    throw new IOException(parent + " should not use addressing through " + arg);
+                } else {
+                    throw new IOException("Unhandled parent " + parent + " while resolving " + arg);
+                }
                 writer.startAugmentationNode(augId);
             } else if (arg instanceof NodeWithValue) {
                 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;
+  }
+}