BUG 1848 : Use OrderedNormalizedNodeWriter in rpc transformation.
[controller.git] / opendaylight / md-sal / sal-netconf-connector / src / main / java / org / opendaylight / controller / sal / connect / netconf / schema / mapping / NetconfMessageTransformer.java
index 9e32dd0663a079fc2bde071a5287bf12369a2d4e..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;
@@ -152,7 +152,7 @@ public class NetconfMessageTransformer implements MessageTransformer<NetconfMess
     }
 
     @Override
-    public NetconfMessage toRpcRequest(SchemaPath rpc, final ContainerNode payload) {
+    public NetconfMessage toRpcRequest(SchemaPath rpc, final NormalizedNode<?, ?> payload) {
         // In case no input for rpc is defined, we can simply construct the payload here
         final QName rpcQName = rpc.getLastComponent();
         Map<QName, RpcDefinition> currentMappedRpcs = mappedRpcs;
@@ -166,12 +166,13 @@ public class NetconfMessageTransformer implements MessageTransformer<NetconfMess
 
         Preconditions.checkNotNull(currentMappedRpcs.get(rpcQName), "Unknown rpc %s, available rpcs: %s", rpcQName, currentMappedRpcs.keySet());
         if(currentMappedRpcs.get(rpcQName).getInput() == null) {
-            final Document document = XmlUtil.newDocument();
-            final Element elementNS = document.createElementNS(rpcQName.getNamespace().toString(), rpcQName.getLocalName());
-            document.appendChild(elementNS);
-            return new NetconfMessage(document);
+            return new NetconfMessage(prepareDomResultForRpcRequest(rpcQName).getNode().getOwnerDocument());
         }
 
+        Preconditions.checkNotNull(payload, "Transforming an rpc with input: %s, payload cannot be null", rpcQName);
+        Preconditions.checkArgument(payload instanceof ContainerNode,
+                "Transforming an rpc with input: %s, payload has to be a container, but was: %s", rpcQName, payload);
+
         // Set the path to the input of rpc for the node stream writer
         rpc = rpc.createChild(QName.cachedReference(QName.create(rpcQName, "input")));
         final DOMResult result = prepareDomResultForRpcRequest(rpcQName);
@@ -179,14 +180,13 @@ public class NetconfMessageTransformer implements MessageTransformer<NetconfMess
         try {
             // If the schema context for netconf device does not contain model for base netconf operations, use default pre build context with just the base model
             // This way operations like lock/unlock are supported even if the source for base model was not provided
-            writeNormalizedRpc(payload, result, rpc, needToUseBaseCtx ? BASE_NETCONF_CTX : schemaContext);
+            writeNormalizedRpc(((ContainerNode) payload), result, rpc, needToUseBaseCtx ? BASE_NETCONF_CTX : schemaContext);
         } catch (final XMLStreamException | IOException | IllegalStateException e) {
             throw new IllegalStateException("Unable to serialize " + rpc, e);
         }
 
         final Document node = result.getNode().getOwnerDocument();
 
-        node.getDocumentElement().setAttribute(NetconfMessageTransformUtil.MESSAGE_ID_ATTR, counter.getNewMessageId(MESSAGE_ID_PREFIX));
         return new NetconfMessage(node);
     }
 
@@ -197,6 +197,8 @@ public class NetconfMessageTransformer implements MessageTransformer<NetconfMess
     private DOMResult prepareDomResultForRpcRequest(final QName rpcQName) {
         final Document document = XmlUtil.newDocument();
         final Element rpcNS = document.createElementNS(NETCONF_RPC_QNAME.getNamespace().toString(), NETCONF_RPC_QNAME.getLocalName());
+        // set msg id
+        rpcNS.setAttribute(NetconfMessageTransformUtil.MESSAGE_ID_ATTR, counter.getNewMessageId(MESSAGE_ID_PREFIX));
         final Element elementNS = document.createElementNS(rpcQName.getNamespace().toString(), rpcQName.getLocalName());
         rpcNS.appendChild(elementNS);
         document.appendChild(rpcNS);
@@ -204,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 {