Initial source code
[oam/tr069-adapter.git] / netconf-server / src / main / java / org / commscope / tr069adapter / netconf / notification / NetConfSessionUtil.java
diff --git a/netconf-server/src/main/java/org/commscope/tr069adapter/netconf/notification/NetConfSessionUtil.java b/netconf-server/src/main/java/org/commscope/tr069adapter/netconf/notification/NetConfSessionUtil.java
new file mode 100644 (file)
index 0000000..046db19
--- /dev/null
@@ -0,0 +1,214 @@
+/*\r
+ * ============LICENSE_START========================================================================\r
+ * ONAP : tr-069-adapter\r
+ * =================================================================================================\r
+ * Copyright (C) 2020 CommScope Inc Intellectual Property.\r
+ * =================================================================================================\r
+ * This tr-069-adapter software file is distributed by CommScope Inc under the Apache License,\r
+ * Version 2.0 (the "License"); you may not use this file except in compliance with the License. You\r
+ * may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\r
+ * either express or implied. See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ * ===============LICENSE_END=======================================================================\r
+ */\r
+\r
+package org.commscope.tr069adapter.netconf.notification;\r
+\r
+import java.io.IOException;\r
+import java.io.StringWriter;\r
+import java.text.SimpleDateFormat;\r
+import java.util.Date;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.StringTokenizer;\r
+\r
+import javax.xml.XMLConstants;\r
+import javax.xml.parsers.DocumentBuilder;\r
+import javax.xml.parsers.DocumentBuilderFactory;\r
+import javax.xml.parsers.ParserConfigurationException;\r
+import javax.xml.transform.Transformer;\r
+import javax.xml.transform.TransformerFactory;\r
+import javax.xml.transform.dom.DOMSource;\r
+import javax.xml.transform.stream.StreamResult;\r
+\r
+import org.commscope.tr069adapter.acs.common.DeviceInform;\r
+import org.commscope.tr069adapter.acs.common.ParameterDTO;\r
+import org.commscope.tr069adapter.netconf.rpc.CreateSubscription;\r
+import org.opendaylight.netconf.api.NetconfMessage;\r
+import org.opendaylight.netconf.api.xml.XmlNetconfConstants;\r
+import org.opendaylight.netconf.api.xml.XmlUtil;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+import org.springframework.stereotype.Component;\r
+import org.w3c.dom.Document;\r
+import org.w3c.dom.Element;\r
+import org.xml.sax.SAXException;\r
+\r
+@Component\r
+public class NetConfSessionUtil {\r
+\r
+  private static final Logger LOG = LoggerFactory.getLogger(NetConfSessionUtil.class);\r
+\r
+  private static final String INDEX_STR = "index";\r
+  private static final String INDEX_REGEX = "[0-9]{1,}";\r
+  private static final String NS_URI = "urn:onf:otcc:wireless:yang:tr069-notification";\r
+\r
+  public void sendNetConfNotification(DeviceInform notification) {\r
+    NetconfMessage netconfMessage = convertToNetConfMessage(notification);\r
+    LOG.debug("Notification converted to NetConf format {}", netconfMessage);\r
+    CreateSubscription.sendNotification(netconfMessage,\r
+        notification.getDeviceDetails().getDeviceId());\r
+  }\r
+\r
+  private NetconfMessage convertToNetConfMessage(DeviceInform notification) {\r
+    try {\r
+      String netConfXmlMsg = getNetconfResponseXML(notification);\r
+      if (netConfXmlMsg == null)\r
+        throw new IllegalArgumentException("There are no parameters found in the response");\r
+      return new NetconfMessage(XmlUtil.readXmlToDocument(netConfXmlMsg));\r
+    } catch (SAXException | IOException e) {\r
+      throw new IllegalArgumentException("Cannot parse notifications", e);\r
+    }\r
+  }\r
+\r
+  private static String getNetconfResponseXML(DeviceInform notification) {\r
+    if (notification == null || notification.getParameters().isEmpty()) {\r
+      LOG.debug("There are no parameters found in the response.");\r
+      return null;\r
+    }\r
+\r
+    List<ParameterDTO> parameters = notification.getParameters();\r
+\r
+    String result = null;\r
+    try {\r
+      DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();\r
+      docFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");\r
+      docFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");\r
+      DocumentBuilder docBuilder = docFactory.newDocumentBuilder();\r
+      Document doc = docBuilder.newDocument();\r
+\r
+      Map<String, Element> parentNodeMap = new HashMap<>();\r
+      Element dataNode = null; // root of all nodes\r
+\r
+      for (ParameterDTO paramDto : parameters) {\r
+        String paramName = paramDto.getParamName();\r
+        String paramValue = paramDto.getParamValue();\r
+        StringTokenizer tokenizer = new StringTokenizer(paramName, ".");\r
+        String parentNodeName = null;\r
+        StringBuilder parentNodeKey = null;\r
+        Element parentNode = null;\r
+        while (tokenizer.hasMoreElements()) {\r
+          String nodeName = (String) tokenizer.nextElement();\r
+          if (null == parentNodeName) { // construct first node or\r
+                                        // Device node\r
+            parentNodeName = nodeName;\r
+            parentNodeKey = new StringBuilder(nodeName);\r
+            // check if the node already exists in parentNodeMap\r
+            parentNode = parentNodeMap.get(parentNodeKey.toString());\r
+            if (null == dataNode) {\r
+              dataNode = parentNode;\r
+            }\r
+          } else if (nodeName.matches(INDEX_REGEX)) { // construct\r
+                                                      // tabular and\r
+                                                      // index nodes\r
+\r
+            // get parent tabular node from parent MAP\r
+            parentNodeKey = parentNodeKey.append(".").append(nodeName);\r
+            Element node = parentNodeMap.get(parentNodeKey.toString());\r
+\r
+            // create a tabular parent node if doesn't exit in MAP\r
+            if (null == node) {\r
+              node = doc.createElement(parentNodeName);\r
+              parentNodeMap.put(parentNodeKey.toString(), node);\r
+\r
+              // update current tabular parent node.\r
+              if (null != parentNode)\r
+                parentNode.appendChild(node);\r
+\r
+              // prepare and add index node to tabular parent node\r
+              Element indexNode = doc.createElement(INDEX_STR);\r
+              indexNode.setTextContent(nodeName);\r
+              node.appendChild(indexNode);\r
+            }\r
+            parentNode = node; // move parent to child\r
+            parentNodeName = nodeName;\r
+          } else if (parentNodeName.matches(INDEX_REGEX)) { // move to\r
+                                                            // next\r
+                                                            // node\r
+                                                            // if\r
+                                                            // tabular\r
+                                                            // attribute\r
+                                                            // is\r
+                                                            // found\r
+            parentNodeKey = parentNodeKey.append(".").append(nodeName);\r
+            parentNodeName = nodeName;\r
+          } else {\r
+            // construct intermediate nodes\r
+            Element node = parentNodeMap.get(parentNodeKey.toString());\r
+            if (null == node) {\r
+              if (null == dataNode) {\r
+                node = doc.createElementNS(NS_URI, parentNodeName);\r
+                dataNode = node;\r
+              } else {\r
+                node = doc.createElement(parentNodeName);\r
+              }\r
+              parentNodeMap.put(parentNodeKey.toString(), node);\r
+              if (null != parentNode)\r
+                parentNode.appendChild(node);\r
+            }\r
+            parentNodeKey = parentNodeKey.append(".").append(nodeName);\r
+            parentNodeName = nodeName;\r
+            parentNode = node;\r
+          }\r
+        }\r
+        // construct leaf node\r
+        Element leafNode = doc.createElement(parentNodeName);\r
+        leafNode.setTextContent(paramValue);\r
+        if (null != parentNode)\r
+          parentNode.appendChild(leafNode);\r
+      }\r
+\r
+      if (null != dataNode) {\r
+        final Element element = doc.createElement(XmlNetconfConstants.NOTIFICATION_ELEMENT_NAME);\r
+        final Element eventTime = doc.createElement(XmlNetconfConstants.EVENT_TIME);\r
+        eventTime\r
+            .setTextContent(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX").format(new Date()));\r
+\r
+        final Element evtTypeElement =\r
+            doc.createElementNS(NS_URI, notification.getInformTypeList().get(0).toString());\r
+        evtTypeElement.appendChild(dataNode);\r
+        element.appendChild(element.getOwnerDocument().importNode(eventTime, true));\r
+        element.appendChild(element.getOwnerDocument().importNode(evtTypeElement, true));\r
+        result = convertDocumentToString(element);\r
+      }\r
+    } catch (ParserConfigurationException pce) {\r
+      LOG.error("Error while getNetconfResponseXML {}", pce.toString());\r
+    }\r
+\r
+    return result;\r
+  }\r
+\r
+  public static String convertDocumentToString(Element element) {\r
+    String strxml = null;\r
+    try {\r
+      TransformerFactory transformerFactory = TransformerFactory.newInstance();\r
+      transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");\r
+      transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");\r
+      Transformer transformer = transformerFactory.newTransformer();\r
+      DOMSource source = new DOMSource(element);\r
+      StreamResult result = new StreamResult(new StringWriter());\r
+      transformer.transform(source, result);\r
+      strxml = result.getWriter().toString();\r
+    } catch (Exception e) {\r
+      LOG.error("Error while converting Element to String {}", e.toString());\r
+    }\r
+    LOG.debug("Converted XML is : {}", strxml);\r
+    return strxml;\r
+  }\r
+\r
+}\r