BUG 1848 : Use OrderedNormalizedNodeWriter in rpc transformation. 98/17998/2
authorTomas Cere <tcere@cisco.com>
Wed, 8 Apr 2015 13:25:30 +0000 (15:25 +0200)
committerTomas Cere <tcere@cisco.com>
Thu, 9 Apr 2015 11:55:47 +0000 (13:55 +0200)
Makes the rpc processing in netconf northbound and sal-netconf-connector use
the new ordered writer.

Change-Id: I1367ba07069fa5b6525358f265fe664d00d71500
Signed-off-by: Tomas Cere <tcere@cisco.com>
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/schema/mapping/NetconfMessageTransformer.java
opendaylight/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/controller/netconf/mdsal/connector/ops/RuntimeRpc.java
opendaylight/netconf/mdsal-netconf-connector/src/test/java/org/opendaylight/controller/netconf/mdsal/connector/ops/RuntimeRpcTest.java
opendaylight/netconf/mdsal-netconf-connector/src/test/resources/messages/mapping/rpcs/rpc-container-control.xml [new file with mode: 0644]
opendaylight/netconf/mdsal-netconf-connector/src/test/resources/messages/mapping/rpcs/rpc-container.xml [new file with mode: 0644]
opendaylight/netconf/mdsal-netconf-connector/src/test/resources/yang/mdsal-netconf-rpc-test.yang

index e06f572cad7d1a02b3f3491241bed93b9bc001b9..303f3e692390ff8a396781377da9c2b99f2e4cd3 100644 (file)
@@ -31,6 +31,7 @@ import javax.xml.transform.dom.DOMResult;
 import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
 import org.opendaylight.controller.md.sal.dom.spi.DefaultDOMRpcResult;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.netconf.util.OrderedNormalizedNodeWriter;
 import org.opendaylight.controller.netconf.util.exception.MissingNameSpaceException;
 import org.opendaylight.controller.netconf.util.xml.XmlElement;
 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
@@ -44,7 +45,6 @@ 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.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
 import org.opendaylight.yangtools.yang.data.impl.codec.xml.XMLStreamNormalizedNodeStreamWriter;
 import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlUtils;
 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
@@ -206,17 +206,15 @@ public class NetconfMessageTransformer implements MessageTransformer<NetconfMess
     }
 
     private void writeNormalizedRpc(final ContainerNode normalized, final DOMResult result, final SchemaPath schemaPath, final SchemaContext baseNetconfCtx) throws IOException, XMLStreamException {
-        final NormalizedNodeWriter normalizedNodeWriter;
+        final OrderedNormalizedNodeWriter normalizedNodeWriter;
         NormalizedNodeStreamWriter normalizedNodeStreamWriter = null;
         XMLStreamWriter writer = null;
         try {
             writer = NetconfMessageTransformUtil.XML_FACTORY.createXMLStreamWriter(result);
             normalizedNodeStreamWriter = XMLStreamNormalizedNodeStreamWriter.create(writer, baseNetconfCtx, schemaPath);
-            normalizedNodeWriter = NormalizedNodeWriter.forStreamWriter(normalizedNodeStreamWriter);
-
-            for (final DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> editElement : normalized.getValue()) {
-                normalizedNodeWriter.write(editElement);
-            }
+            normalizedNodeWriter = new OrderedNormalizedNodeWriter(normalizedNodeStreamWriter, baseNetconfCtx, schemaPath);
+            Collection<DataContainerChild<?, ?>> value = (Collection) normalized.getValue();
+            normalizedNodeWriter.write(value);
             normalizedNodeWriter.flush();
         } finally {
             try {
index a3cd3c7afa48e655e209672daacf564a76171e55..51f9e220c54ff24c47886c920e5e15aa0d7afda2 100644 (file)
@@ -14,6 +14,7 @@ import com.google.common.util.concurrent.CheckedFuture;
 import java.io.IOException;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Map;
 import javax.annotation.Nullable;
@@ -32,16 +33,15 @@ import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
 import org.opendaylight.controller.netconf.mdsal.connector.CurrentSchemaContext;
+import org.opendaylight.controller.netconf.util.OrderedNormalizedNodeWriter;
 import org.opendaylight.controller.netconf.util.exception.MissingNameSpaceException;
 import org.opendaylight.controller.netconf.util.mapping.AbstractSingletonNetconfOperation;
 import org.opendaylight.controller.netconf.util.xml.XmlElement;
 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
-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.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
 import org.opendaylight.yangtools.yang.data.impl.codec.xml.XMLStreamNormalizedNodeStreamWriter;
 import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.DomUtils;
 import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser.DomToNormalizedNodeParserFactory;
@@ -211,7 +211,7 @@ public class RuntimeRpc extends AbstractSingletonNetconfOperation {
         final NormalizedNodeStreamWriter nnStreamWriter = XMLStreamNormalizedNodeStreamWriter.create(xmlWriter,
                 schemaContext.getCurrentContext(), rpcOutputPath);
 
-        final NormalizedNodeWriter nnWriter = NormalizedNodeWriter.forStreamWriter(nnStreamWriter);
+        final OrderedNormalizedNodeWriter nnWriter = new OrderedNormalizedNodeWriter(nnStreamWriter, schemaContext.getCurrentContext(), rpcOutputPath);
 
         writeRootElement(xmlWriter, nnWriter, (ContainerNode) data);
         try {
@@ -232,11 +232,10 @@ public class RuntimeRpc extends AbstractSingletonNetconfOperation {
         }
     }
 
-    private void writeRootElement(final XMLStreamWriter xmlWriter, final NormalizedNodeWriter nnWriter, final ContainerNode data) {
+    private void writeRootElement(final XMLStreamWriter xmlWriter, final OrderedNormalizedNodeWriter nnWriter, final ContainerNode data) {
         try {
-            for (final DataContainerChild<? extends PathArgument, ?> child : data.getValue()) {
-                nnWriter.write(child);
-            }
+            Collection<DataContainerChild<?, ?>> value = (Collection) data.getValue();
+            nnWriter.write(value);
             nnWriter.flush();
             xmlWriter.flush();
         } catch (XMLStreamException | IOException e) {
index 32eb08c2e73603f73b9a775513769100a32cf54a..040066d91ca4ecbc9a20e6b18361c92672d0ba14 100644 (file)
@@ -30,6 +30,7 @@ import java.util.Collections;
 import java.util.List;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
+import javax.xml.transform.TransformerException;
 import org.custommonkey.xmlunit.DetailedDiff;
 import org.custommonkey.xmlunit.Diff;
 import org.custommonkey.xmlunit.XMLUnit;
@@ -201,6 +202,18 @@ public class RuntimeRpcTest {
         verifyResponse(response, XmlFileLoader.xmlFileToDocument("messages/mapping/rpcs/rpc-nonvoid-control.xml"));
     }
 
+    @Test
+    public void testSuccesfullContainerInvocation() throws Exception {
+        RuntimeRpc rpc = new RuntimeRpc(sessionIdForReporting, currentSchemaContext, rpcServiceSuccesfullInvocation);
+
+        Document rpcDocument = XmlFileLoader.xmlFileToDocument("messages/mapping/rpcs/rpc-container.xml");
+        HandlingPriority priority = rpc.canHandle(rpcDocument);
+        Preconditions.checkState(priority != HandlingPriority.CANNOT_HANDLE);
+
+        Document response = rpc.handle(rpcDocument, NetconfOperationChainedExecution.EXECUTION_TERMINATION_POINT);
+        verifyResponse(response, XmlFileLoader.xmlFileToDocument("messages/mapping/rpcs/rpc-container-control.xml"));
+    }
+
     @Test
     public void testFailedInvocation() throws Exception {
         RuntimeRpc rpc = new RuntimeRpc(sessionIdForReporting, currentSchemaContext, rpcServiceFailedInvocation);
@@ -232,10 +245,11 @@ public class RuntimeRpcTest {
         verifyResponse(response, RPC_REPLY_OK);
     }
 
-    private void verifyResponse(Document response, Document template) {
+    private void verifyResponse(Document response, Document template) throws IOException, TransformerException {
         DetailedDiff dd = new DetailedDiff(new Diff(response, template));
         dd.overrideElementQualifier(new RecursiveElementNameAndTextQualifier());
-        assertTrue(dd.similar());
+        //we care about order so response has to be identical
+        assertTrue(dd.identical());
     }
 
     private RpcDefinition getRpcDefinitionFromModule(Module module, URI namespaceURI, String name) {
diff --git a/opendaylight/netconf/mdsal-netconf-connector/src/test/resources/messages/mapping/rpcs/rpc-container-control.xml b/opendaylight/netconf/mdsal-netconf-connector/src/test/resources/messages/mapping/rpcs/rpc-container-control.xml
new file mode 100644 (file)
index 0000000..1c06ea9
--- /dev/null
@@ -0,0 +1,27 @@
+<!--
+  ~ Copyright (c) 2015 Cisco Systems, Inc. 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
+  -->
+
+<rpc-reply message-id="2"
+     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+    <cont1 xmlns="urn:opendaylight:mdsal:mapping:rpc:test">
+        <test-string>
+            cont1 input string 1
+        </test-string>
+        <test-string2>
+            cont1 input string 2
+        </test-string2>
+    </cont1>
+    <cont2 xmlns="urn:opendaylight:mdsal:mapping:rpc:test">
+        <test-string>
+            cont2 input string 1
+        </test-string>
+        <test-string2>
+            cont2 input string 2
+        </test-string2>
+    </cont2>
+</rpc-reply>
\ No newline at end of file
diff --git a/opendaylight/netconf/mdsal-netconf-connector/src/test/resources/messages/mapping/rpcs/rpc-container.xml b/opendaylight/netconf/mdsal-netconf-connector/src/test/resources/messages/mapping/rpcs/rpc-container.xml
new file mode 100644 (file)
index 0000000..570d6df
--- /dev/null
@@ -0,0 +1,29 @@
+<!--
+  ~ Copyright (c) 2015 Cisco Systems, Inc. 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
+  -->
+
+<rpc message-id="2"
+     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+    <container-rpc xmlns="urn:opendaylight:mdsal:mapping:rpc:test">
+        <cont1>
+            <test-string>
+                cont1 input string 1
+            </test-string>
+            <test-string2>
+                cont1 input string 2
+            </test-string2>
+        </cont1>
+        <cont2>
+            <test-string>
+                cont2 input string 1
+            </test-string>
+            <test-string2>
+                cont2 input string 2
+            </test-string2>
+        </cont2>
+    </container-rpc>
+</rpc>
\ No newline at end of file
index d4938408287d98bb78340bfb0e1a0c5d0b99d646..6a59cdcf6e4638742a11d49facde3459b2ff09ef 100644 (file)
@@ -40,5 +40,51 @@ module rpc-test {
             }
         }
     }
+
+    rpc container-rpc {
+        input {
+            container cont1 {
+                leaf test-string {
+                    type string;
+                }
+
+                leaf test-string2 {
+                    type string;
+                }
+            }
+
+            container cont2 {
+                leaf test-string {
+                    type string;
+                }
+
+                leaf test-string2 {
+                    type string;
+                }
+            }
+        }
+
+        output {
+            container cont1 {
+                leaf test-string {
+                    type string;
+                }
+
+                leaf test-string2 {
+                    type string;
+                }
+            }
+
+            container cont2 {
+                leaf test-string {
+                    type string;
+                }
+
+                leaf test-string2 {
+                    type string;
+                }
+            }
+        }
+    }
 }