Fix empty get failing on mounted devices when using xml 86/99186/6
authorTomas Cere <tomas.cere@pantheon.tech>
Tue, 4 Jan 2022 11:14:38 +0000 (12:14 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Thu, 20 Jan 2022 15:56:54 +0000 (16:56 +0100)
The ParameterAwareNormalizedNodeWriter was not setting an
empty container node with root path as handled so fix that.
Also make sure we actually return an empty data node when
its processed instead of empty response.

JIRA: NETCONF-847
Change-Id: Iab271a93fd13176dd061d5c26ab1d7f9a8b8263b
Signed-off-by: Tomas Cere <tomas.cere@pantheon.tech>
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/ParameterAwareNormalizedNodeWriter.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/XmlNormalizedNodeBodyWriter.java
restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/ParameterAwareNormalizedNodeWriterParametersTest.java
restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/XmlNormalizedNodeBodyWriterTest.java [new file with mode: 0644]

index d023f4b13f706739b40afbadf94373156bf40486..378e9ddda8d38f65c2b0dc399a92d24cf7f56046 100644 (file)
@@ -273,8 +273,8 @@ public class ParameterAwareNormalizedNodeWriter implements RestconfNormalizedNod
                         write(child);
                     }
                     currentDepth--;
-                    processedAsCompositeNode = true;
                 }
+                processedAsCompositeNode = true;
             }
         } else if (node instanceof MapEntryNode) {
             processedAsCompositeNode = writeMapEntryNode((MapEntryNode) node);
index b5c085ca679df8856e9fae5e6d9b0578b4237e1a..d9af3d4c80a74295f91b5f2518875c3af8c16c83 100644 (file)
@@ -116,7 +116,8 @@ public class XmlNormalizedNodeBodyWriter extends AbstractNormalizedNodeBodyWrite
                 ((ActionDefinition) pathContext.getSchemaNode()).getOutput().getPath(), depth, fields);
             writeElements(xmlWriter, nnWriter, (ContainerNode) data);
         } else {
-            if (SchemaPath.ROOT.equals(path)) {
+            final boolean isRoot = SchemaPath.ROOT.equals(path);
+            if (isRoot) {
                 nnWriter = createNormalizedNodeWriter(xmlWriter, schemaCtx, path, depth, fields);
             } else {
                 nnWriter = createNormalizedNodeWriter(xmlWriter, schemaCtx, path.getParent(), depth, fields);
@@ -129,13 +130,31 @@ public class XmlNormalizedNodeBodyWriter extends AbstractNormalizedNodeBodyWrite
                     .addChild((MapEntryNode) data)
                     .build());
             } else {
-                nnWriter.write(data);
+                if (isRoot && data instanceof ContainerNode && ((ContainerNode) data).isEmpty()) {
+                    writeEmptyDataNode(xmlWriter, data);
+                } else {
+                    nnWriter.write(data);
+                }
             }
         }
 
         nnWriter.flush();
     }
 
+    private static void writeEmptyDataNode(final XMLStreamWriter xmlWriter, final NormalizedNode data)
+            throws IOException {
+        final QName nodeType = data.getIdentifier().getNodeType();
+        final String namespace = nodeType.getNamespace().toString();
+        try {
+            xmlWriter.writeStartElement(XMLConstants.DEFAULT_NS_PREFIX, nodeType.getLocalName(), namespace);
+            xmlWriter.writeDefaultNamespace(namespace);
+            xmlWriter.writeEndElement();
+            xmlWriter.flush();
+        } catch (XMLStreamException e) {
+            throw new IOException("Failed to write elements", e);
+        }
+    }
+
     private static RestconfNormalizedNodeWriter createNormalizedNodeWriter(final XMLStreamWriter xmlWriter,
             final EffectiveModelContext schemaContext, final SchemaPath schemaPath, final DepthParam depth,
             final List<Set<QName>> fields) {
index 5443e4b8b8bed334ca1b4265f4113b94dffb62d3..70ac6e80e7c9957f6612f2392e17f047871fc27e 100644 (file)
@@ -30,6 +30,8 @@ import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
 /**
  * Unit test for {@link ParameterAwareNormalizedNodeWriter} used with all parameters.
@@ -131,4 +133,13 @@ public class ParameterAwareNormalizedNodeWriterParametersTest {
         inOrder.verify(writer, Mockito.times(2)).endNode();
         Mockito.verifyNoMoreInteractions(writer);
     }
+
+    @Test
+    public void writeEmptyRootContainerTest() throws Exception {
+        final ParameterAwareNormalizedNodeWriter parameterWriter = ParameterAwareNormalizedNodeWriter.forStreamWriter(
+                writer, null, null);
+
+        parameterWriter.write(ImmutableContainerNodeBuilder.create()
+                .withNodeIdentifier(new NodeIdentifier(SchemaContext.NAME)).build());
+    }
 }
\ No newline at end of file
diff --git a/restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/XmlNormalizedNodeBodyWriterTest.java b/restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/XmlNormalizedNodeBodyWriterTest.java
new file mode 100644 (file)
index 0000000..f45ce5d
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * 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.restconf.nb.rfc8040.jersey.providers;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import javax.ws.rs.core.MediaType;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
+import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+public class XmlNormalizedNodeBodyWriterTest {
+
+    private static final String EMPTY_OUTPUT = "<data xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"></data>";
+
+    private static EffectiveModelContext schemaContext;
+
+    @BeforeClass
+    public static void initialization() throws Exception {
+        schemaContext = Mockito.mock(EffectiveModelContext.class);
+    }
+
+    @Test
+    public void testWriteEmptyRootContainer() throws Exception {
+        final SchemaNode schemaNode = Mockito.mock(SchemaNode.class);
+        when(schemaNode.getPath()).thenReturn(SchemaPath.ROOT);
+
+        final InstanceIdentifierContext<SchemaNode> identifierContext =
+                new InstanceIdentifierContext<>(YangInstanceIdentifier.empty(), schemaNode, null, schemaContext);
+        final ContainerNode data = ImmutableContainerNodeBuilder.create()
+                .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(SchemaContext.NAME)).build();
+        final NormalizedNodePayload nodePayload = NormalizedNodePayload.of(identifierContext, data);
+
+        final OutputStream output = new ByteArrayOutputStream();
+        final XmlNormalizedNodeBodyWriter xmlWriter = new XmlNormalizedNodeBodyWriter();
+        xmlWriter.writeTo(nodePayload, null, null, null, MediaType.APPLICATION_XML_TYPE, null, output);
+
+        assertEquals(EMPTY_OUTPUT, output.toString());
+    }
+}
\ No newline at end of file