Teach AbstractGet how to transform MapNodes 30/84030/3
authorMario Abraham <mario.abraham@pantheon.tech>
Wed, 21 Aug 2019 13:23:52 +0000 (15:23 +0200)
committerMario Abraham <mario.abraham@pantheon.tech>
Tue, 3 Sep 2019 10:29:19 +0000 (12:29 +0200)
Added case for MapNode interface in transformNormalizedNode() method

Issue-ID: NETCONF-538
Signed-off-by: Mario Abraham <mario.abraham@pantheon.tech>
Change-Id: I9fa1d7f364d3d68d715aab73473096795da4ed6b
(cherry picked from commit ca7514e21fca4d18104d5a09d547d540a32d2e2e)

netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/netconf/mdsal/connector/ops/get/AbstractGet.java
netconf/mdsal-netconf-connector/src/test/java/org/opendaylight/netconf/mdsal/connector/ops/get/Netconf538Test.java [new file with mode: 0644]
netconf/mdsal-netconf-connector/src/test/resources/filter/netconf538.xml [new file with mode: 0644]
netconf/mdsal-netconf-connector/src/test/resources/yang/simple-list.yang [new file with mode: 0644]

index 8eaef5545191261dbc535e08036444a56acb975f..f02bc08adf0a1c5c95d34b225a1e64cc1a966049 100644 (file)
@@ -28,6 +28,8 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
@@ -60,6 +62,7 @@ public abstract class AbstractGet extends AbstractSingletonNetconfOperation {
 
     protected Node transformNormalizedNode(final Document document, final NormalizedNode<?, ?> data,
                                            final YangInstanceIdentifier dataRoot) {
+
         final DOMResult result = new DOMResult(document.createElement(XmlNetconfConstants.DATA_KEY));
 
         final XMLStreamWriter xmlWriter = getXmlStreamWriter(result);
@@ -69,7 +72,15 @@ public abstract class AbstractGet extends AbstractSingletonNetconfOperation {
 
         final NormalizedNodeWriter nnWriter = NormalizedNodeWriter.forStreamWriter(nnStreamWriter, true);
 
-        writeRootElement(xmlWriter, nnWriter, (ContainerNode) data);
+        if (data instanceof ContainerNode) {
+            writeRootElement(xmlWriter, nnWriter, (ContainerNode) data);
+        } else if (data instanceof MapNode) {
+            writeRootElement(xmlWriter, nnWriter, (MapNode) data);
+        } else {
+            throw new IllegalArgumentException("Unable to transform node of type: " +  data.getClass().toString()
+                    + " offending node: " + data.toString());
+        }
+
         return result.getNode();
     }
 
@@ -103,6 +114,23 @@ public abstract class AbstractGet extends AbstractSingletonNetconfOperation {
         }
     }
 
+    private static void writeRootElement(final XMLStreamWriter xmlWriter, final NormalizedNodeWriter nnWriter,
+                                         final MapNode data) {
+        try {
+            if (data.getNodeType().equals(SchemaContext.NAME)) {
+                for (final MapEntryNode child : data.getValue()) {
+                    nnWriter.write(child);
+                }
+            } else {
+                nnWriter.write(data);
+            }
+            nnWriter.flush();
+            xmlWriter.flush();
+        } catch (XMLStreamException | IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
     protected Element serializeNodeWithParentStructure(final Document document, final YangInstanceIdentifier dataRoot,
                                                        final NormalizedNode<?, ?> node) {
         if (!dataRoot.equals(ROOT)) {
diff --git a/netconf/mdsal-netconf-connector/src/test/java/org/opendaylight/netconf/mdsal/connector/ops/get/Netconf538Test.java b/netconf/mdsal-netconf-connector/src/test/java/org/opendaylight/netconf/mdsal/connector/ops/get/Netconf538Test.java
new file mode 100644 (file)
index 0000000..3b8babb
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech s.r.o. 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.netconf.mdsal.connector.ops.get;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.opendaylight.netconf.api.xml.XmlUtil;
+import org.opendaylight.netconf.mdsal.connector.CurrentSchemaContext;
+import org.opendaylight.netconf.mdsal.connector.TransactionProvider;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+public class Netconf538Test {
+
+    private static final String SESSION_ID_FOR_REPORTING = "netconf-test-session1";
+    private static final QName BASE = QName.create("urn:dummy:list", "2019-08-21", "user");
+    private static final QName NAME_QNAME = QName.create(BASE, "name");
+    private static final String LEAF_VALUE = "testName";
+
+    @Mock
+    private TransactionProvider transactionProvider;
+
+    @Test
+    public void transformNormalizedNodeTest_mapNodeTest() throws Exception {
+
+        final SchemaContext context = YangParserTestUtils.parseYangResources(Netconf538Test.class,
+                "/yang/simple-list.yang");
+        final CurrentSchemaContext currentContext = mock(CurrentSchemaContext.class);
+        doReturn(context).when(currentContext).getCurrentContext();
+
+        final GetConfig getConfig = new GetConfig(SESSION_ID_FOR_REPORTING, currentContext, transactionProvider);
+
+        final Document document = XmlUtil.readXmlToDocument(FilterContentValidatorTest.class
+                .getResourceAsStream("/filter/netconf538.xml"));
+
+        LeafNode<String> leafNode = Builders.<String>leafBuilder()
+                .withNodeIdentifier(YangInstanceIdentifier.NodeIdentifier.create(NAME_QNAME))
+                .withValue(LEAF_VALUE).build();
+
+        MapEntryNode mapEntryNode = Builders.mapEntryBuilder()
+            .withNodeIdentifier(new YangInstanceIdentifier
+                .NodeIdentifierWithPredicates(BASE, NAME_QNAME, LEAF_VALUE))
+            .withChild(leafNode).build();
+
+        MapNode data = Builders.mapBuilder().withNodeIdentifier(YangInstanceIdentifier.NodeIdentifier.create(BASE))
+                .withChild(mapEntryNode).build();
+
+
+        final YangInstanceIdentifier path = YangInstanceIdentifier.builder().build();
+
+        final Node node = getConfig.transformNormalizedNode(document, data, path);
+
+        Assert.assertNotNull(node);
+        Node nodeUser = node.getFirstChild();
+        Assert.assertEquals(data.getIdentifier().getNodeType().getLocalName(), nodeUser.getLocalName());
+        Node nodeName = nodeUser.getFirstChild();
+        Assert.assertEquals(leafNode.getIdentifier().getNodeType().getLocalName(), nodeName.getLocalName());
+        Assert.assertEquals(leafNode.getValue(), nodeName.getFirstChild().getNodeValue());
+    }
+
+}
diff --git a/netconf/mdsal-netconf-connector/src/test/resources/filter/netconf538.xml b/netconf/mdsal-netconf-connector/src/test/resources/filter/netconf538.xml
new file mode 100644 (file)
index 0000000..004bdc0
--- /dev/null
@@ -0,0 +1,3 @@
+<user xmlns="urn:dummy:list">
+        <name>testName</name>
+</user>
diff --git a/netconf/mdsal-netconf-connector/src/test/resources/yang/simple-list.yang b/netconf/mdsal-netconf-connector/src/test/resources/yang/simple-list.yang
new file mode 100644 (file)
index 0000000..05d2a59
--- /dev/null
@@ -0,0 +1,16 @@
+module simple-list {
+    namespace "urn:dummy:list";
+    prefix "list-0";
+    revision "2019-08-21";
+
+    list user {
+             key "name";
+             config true;
+             description "This is a list of users in the system.";
+
+             leaf name {
+                 type string;
+             }
+     }
+
+}
\ No newline at end of file