Teach SchemaAwareApplyOperation about anydata/anyxml 01/90001/1
authorRobert Varga <robert.varga@pantheon.tech>
Wed, 27 May 2020 10:12:40 +0000 (12:12 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Wed, 27 May 2020 11:47:47 +0000 (13:47 +0200)
When we encounter an anydata/anyxml element in schema, we should
not be ignoring it, cascading to a silent failure, but rather
treat it as a leaf-like node.

JIRA: YANGTOOLS-1104
Change-Id: I896a3b6e65fe8e5b897e71103d616b3e03f3c1b3
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit 4b64f1f8c65d362ce3447aa7f2c97132c253fffa)

yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/SchemaAwareApplyOperation.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/ValueNodeModificationStrategy.java
yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/YT1104Test.java [new file with mode: 0644]
yang/yang-data-impl/src/test/resources/yt1104.yang [new file with mode: 0644]

index 654a9805a540f1451a269c4323f4003a34ddb42f..7dcce6019a4f5bd8aa8f27d87fa30aa23f82fbd9 100644 (file)
@@ -16,6 +16,8 @@ import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.AnydataNode;
+import org.opendaylight.yangtools.yang.data.api.schema.AnyxmlNode;
 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.ConflictingModificationAppliedException;
@@ -25,6 +27,8 @@ import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.TreeType;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version;
+import org.opendaylight.yangtools.yang.model.api.AnyDataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
@@ -58,6 +62,10 @@ abstract class SchemaAwareApplyOperation<T extends WithStatus> extends Modificat
                 treeConfig));
         } else if (schemaNode instanceof LeafSchemaNode) {
             return new ValueNodeModificationStrategy<>(LeafNode.class, (LeafSchemaNode) schemaNode);
+        } else if (schemaNode instanceof AnyDataSchemaNode) {
+            return new ValueNodeModificationStrategy<>(AnydataNode.class, (AnyDataSchemaNode) schemaNode);
+        } else if (schemaNode instanceof AnyXmlSchemaNode) {
+            return new ValueNodeModificationStrategy<>(AnyxmlNode.class, (AnyXmlSchemaNode) schemaNode);
         }
         throw new IllegalArgumentException("Not supported schema node type for " + schemaNode.getClass());
     }
index 6b03863c12a67b9cc919ee8844da4d149965b26f..3f6188bcb4aae7a399109bd7eca639283dcf6d9a 100644 (file)
@@ -14,7 +14,6 @@ import java.util.Optional;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.ValueNode;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.IncorrectDataStructureException;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
@@ -22,11 +21,12 @@ import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNodeFactory;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.Version;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 
-final class ValueNodeModificationStrategy<T extends DataSchemaNode> extends SchemaAwareApplyOperation<T> {
-    private final Class<? extends ValueNode> nodeClass;
+final class ValueNodeModificationStrategy<T extends DataSchemaNode, V extends NormalizedNode<?, ?>>
+        extends SchemaAwareApplyOperation<T> {
+    private final @NonNull Class<V> nodeClass;
     private final @NonNull T schema;
 
-    ValueNodeModificationStrategy(final Class<? extends ValueNode> nodeClass, final T schema) {
+    ValueNodeModificationStrategy(final Class<V> nodeClass, final T schema) {
         this.nodeClass = requireNonNull(nodeClass);
         this.schema = requireNonNull(schema);
     }
diff --git a/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/YT1104Test.java b/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/YT1104Test.java
new file mode 100644 (file)
index 0000000..d60222a
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2020 Pantheon Technologies, 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.impl.schema.tree;
+
+import static org.opendaylight.yangtools.yang.data.impl.schema.Builders.anyXmlBuilder;
+import static org.opendaylight.yangtools.yang.data.impl.schema.Builders.anydataBuilder;
+import static org.opendaylight.yangtools.yang.data.impl.schema.Builders.choiceBuilder;
+
+import javax.xml.transform.dom.DOMSource;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+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.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class YT1104Test {
+    private static final QName MODULE = QName.create("yt1104", "yt1104");
+    private static final NodeIdentifier FOO = new NodeIdentifier(QName.create(MODULE, "foo"));
+    private static final NodeIdentifier BAR = new NodeIdentifier(QName.create(MODULE, "bar"));
+    private static final NodeIdentifier BAZ = new NodeIdentifier(QName.create(MODULE, "baz"));
+
+    private static SchemaContext SCHEMA_CONTEXT;
+
+    private DataTree dataTree;
+
+    @BeforeClass
+    public static void beforeClass() {
+        SCHEMA_CONTEXT = TestModel.createTestContext("/yt1104.yang");
+    }
+
+    @AfterClass
+    public static void afterClass() {
+        SCHEMA_CONTEXT = null;
+    }
+
+    @Before
+    public void init() {
+        dataTree = new InMemoryDataTreeFactory().create(DataTreeConfiguration.DEFAULT_CONFIGURATION, SCHEMA_CONTEXT);
+    }
+
+    @Test
+    public void testAnydata() throws DataValidationFailedException {
+        writeChoice(anydataBuilder(String.class).withNodeIdentifier(BAR).withValue("anydata").build());
+    }
+
+    @Test
+    public void testAnyxml() throws DataValidationFailedException {
+        writeChoice(anyXmlBuilder().withNodeIdentifier(BAZ).withValue(new DOMSource()).build());
+    }
+
+    private void writeChoice(final DataContainerChild<?, ?> child) throws DataValidationFailedException {
+        final DataTreeModification mod = dataTree.takeSnapshot().newModification();
+        mod.write(YangInstanceIdentifier.create(FOO), choiceBuilder().withNodeIdentifier(FOO).withChild(child).build());
+        mod.ready();
+        dataTree.validate(mod);
+        dataTree.commit(dataTree.prepare(mod));
+    }
+}
diff --git a/yang/yang-data-impl/src/test/resources/yt1104.yang b/yang/yang-data-impl/src/test/resources/yt1104.yang
new file mode 100644 (file)
index 0000000..ed71c0d
--- /dev/null
@@ -0,0 +1,11 @@
+module yt1104 {
+  yang-version 1.1;
+  namespace yt1104;
+  prefix yt1104;
+
+  choice foo {
+    anydata bar;
+    anyxml baz;
+  }
+}
+