Device Software version management
[oam/tr069-adapter.git] / mapper / src / main / java / org / commscope / tr069adapter / mapper / netconf / NetConfNotificationSender.java
index 5ec31e7..2b6fd9e 100644 (file)
 \r
 package org.commscope.tr069adapter.mapper.netconf;\r
 \r
+import java.io.StringWriter;\r
+import java.text.SimpleDateFormat;\r
 import java.util.ArrayList;\r
+import java.util.Date;\r
+import java.util.HashMap;\r
 import java.util.List;\r
-\r
+import java.util.Map;\r
+import java.util.StringTokenizer;\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
 import org.commscope.tr069adapter.acs.common.DeviceInform;\r
 import org.commscope.tr069adapter.acs.common.ParameterDTO;\r
 import org.commscope.tr069adapter.mapper.MOMetaData;\r
@@ -33,6 +45,8 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.ResponseEntity;\r
 import org.springframework.stereotype.Component;\r
 import org.springframework.web.client.RestTemplate;\r
+import org.w3c.dom.Document;\r
+import org.w3c.dom.Element;\r
 \r
 @Component\r
 public class NetConfNotificationSender {\r
@@ -41,6 +55,11 @@ public class NetConfNotificationSender {
   private static final String BOOLEAN_TRUE_VALUE = "1";\r
   private static final String BOOLEAN_FALSE_VALUE = "0";\r
   private static final String BOOLEAN_DATA_TYPE = "boolean";\r
+  public static final String NOTIFICATION_ELEMENT_NAME = "notification";\r
+  public static final String EVENT_TIME = "eventTime";\r
+  private static final String INDEX_STR = "index";\r
+  private static final String INDEX_REGEX = "[0-9]{1,}";\r
+\r
 \r
   @Autowired\r
   MapperConfigProperties config;\r
@@ -59,11 +78,21 @@ public class NetConfNotificationSender {
     try {\r
       LOG.debug("deviceInform : {} {}", deviceInform.getInformTypeList(),\r
           deviceInform.getParameters());\r
-      NetConfNotificationDTO netConfDTO =\r
-          new NetConfNotificationDTO(deviceInform.getDeviceDetails().getDeviceId(),\r
-              deviceInform.getInformType().toString(), false);\r
-      netConfDTO.setParameters(deviceInform.getParameters());\r
-      convertTR069ToNetConfParams(netConfDTO);\r
+      List<ParameterDTO> parameters = new ArrayList<>();\r
+      for (ParameterDTO parameterDTO : deviceInform.getParameters()) {\r
+        parameters.add(parameterDTO);\r
+      }\r
+\r
+      convertTR069ToNetConfParams(parameters, deviceInform.getDeviceDetails().getSoftwareVersion(),\r
+          deviceInform.getDeviceDetails().getHardwareVersion());\r
+\r
+      String notificationXml =\r
+          getNetconfResponseXML(parameters, deviceInform.getInformType().toString(), null,\r
+              deviceInform.getDeviceDetails().getSoftwareVersion(),\r
+              deviceInform.getDeviceDetails().getHardwareVersion());\r
+      NetConfNotificationDTO netConfDTO = new NetConfNotificationDTO(\r
+          deviceInform.getDeviceDetails().getDeviceId(), notificationXml);\r
+\r
       LOG.debug("Posting notification to netconf server");\r
       response = restTemplate.postForObject(uri, netConfDTO, ResponseEntity.class);\r
       LOG.debug("Posting notification to netconf server completed ");\r
@@ -73,11 +102,15 @@ public class NetConfNotificationSender {
     return response;\r
   }\r
 \r
-  public ResponseEntity sendCustomNotification(NetConfNotificationDTO netConfDTO) {\r
+  public ResponseEntity sendCustomNotification(String deviceId, List<ParameterDTO> parameters,\r
+      String nameSpace) {\r
     ResponseEntity response = null;\r
     final String uri = getUri();\r
     LOG.debug("Posting custom notification to netconf server " + uri);\r
     try {\r
+      String notificationXml = getNetconfResponseXML(parameters, null, nameSpace, null, null);\r
+      NetConfNotificationDTO netConfDTO = new NetConfNotificationDTO(deviceId, notificationXml);\r
+\r
       response = restTemplate.postForObject(uri, netConfDTO, ResponseEntity.class);\r
       LOG.debug("Posting custom notification to netconf server sucessfull");\r
     } catch (Exception e) {\r
@@ -86,29 +119,31 @@ public class NetConfNotificationSender {
     return response;\r
   }\r
 \r
-  private void convertTR069ToNetConfParams(NetConfNotificationDTO netConfDTO) {\r
+  private void convertTR069ToNetConfParams(List<ParameterDTO> parameters, String swVersion,\r
+      String hwVersion) {\r
     List<ParameterDTO> removeList = new ArrayList<>();\r
-    if (null != netConfDTO) {\r
-      for (ParameterDTO param : netConfDTO.getParameters()) {\r
+    if (null != parameters) {\r
+      for (ParameterDTO param : parameters) {\r
         if (param.getParamValue() == null || param.getParamValue().trim().length() <= 0) {\r
           continue;\r
         }\r
-        handleBooleanParameters(param);\r
+        handleBooleanParameters(param, swVersion, hwVersion);\r
         if (null != param.getParamName()) {\r
-          String netConfMOName =\r
-              metaDataUtil.getNetconfNameByTR69NameWithIndexes(param.getParamName());\r
+          String netConfMOName = metaDataUtil\r
+              .getNetconfNameByTR69NameWithIndexes(param.getParamName(), swVersion, hwVersion);\r
           if (null != netConfMOName)\r
             param.setParamName(netConfMOName);\r
           else\r
             removeList.add(param); // unknown parameter found.\r
         }\r
       }\r
-      netConfDTO.getParameters().removeAll(removeList);\r
+      parameters.removeAll(removeList);\r
     }\r
   }\r
 \r
-  private void handleBooleanParameters(ParameterDTO param) {\r
-    MOMetaData metaData = metaDataUtil.getMetaDataByTR69Name(param.getParamName());\r
+  private void handleBooleanParameters(ParameterDTO param, String swVersion, String hwVersion) {\r
+    MOMetaData metaData =\r
+        metaDataUtil.getMetaDataByTR69Name(param.getParamName(), swVersion, hwVersion);\r
     if (null != metaData && BOOLEAN_DATA_TYPE.equalsIgnoreCase(metaData.getDataType())) {\r
       if (BOOLEAN_TRUE_VALUE.equalsIgnoreCase(param.getParamValue().trim())) {\r
         param.setParamValue(Boolean.TRUE.toString());\r
@@ -122,4 +157,146 @@ public class NetConfNotificationSender {
     return config.getNbiNotificationUri();\r
   }\r
 \r
+  private String getNetconfResponseXML(List<ParameterDTO> parameters, String notificationType,\r
+      String nameSpace, String swVersion, String hwVersion) {\r
+    if (parameters == null || parameters.isEmpty()) {\r
+      LOG.debug("There are no parameters found in the response.");\r
+      return null;\r
+    }\r
+\r
+    String result = null;\r
+    try {\r
+      DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();\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
+        String 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 = nodeName;\r
+            // check if the node already exists in parentNodeMap\r
+            parentNode = parentNodeMap.get(parentNodeKey);\r
+            if (null == dataNode) {\r
+              dataNode = parentNode;\r
+            }\r
+            continue;\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 + "." + nodeName;\r
+            Element node = parentNodeMap.get(parentNodeKey);\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, node);\r
+\r
+              // update current tabular parent node.\r
+              if (null != parentNode)\r
+                parentNode.appendChild(node);\r
+              else\r
+                parentNode = 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 + "." + nodeName;\r
+            parentNodeName = nodeName;\r
+          } else {\r
+            // construct intermediate nodes\r
+            Element node = parentNodeMap.get(parentNodeKey);\r
+            if (null == node) {\r
+              if (null == dataNode) {\r
+                node = doc.createElementNS(nameSpace, parentNodeName);\r
+                dataNode = node;\r
+              } else {\r
+                node = doc.createElement(parentNodeName);\r
+              }\r
+              parentNodeMap.put(parentNodeKey, node);\r
+              if (null != parentNode)\r
+                parentNode.appendChild(node);\r
+            }\r
+            parentNodeKey = parentNodeKey + "." + nodeName;\r
+            parentNodeName = nodeName;\r
+            parentNode = node;\r
+          }\r
+        }\r
+        // construct leaf node\r
+        Element leafNode = doc.createElement(parentNodeName);\r
+        leafNode.setTextContent(paramValue);\r
+        parentNode.appendChild(leafNode);\r
+      }\r
+\r
+      if (null != dataNode) {\r
+        final Element element = doc.createElement(NOTIFICATION_ELEMENT_NAME);\r
+        final Element eventTime = doc.createElement(EVENT_TIME);\r
+        eventTime\r
+            .setTextContent(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX").format(new Date()));\r
+        element.appendChild(element.getOwnerDocument().importNode(eventTime, true));\r
+\r
+        if (notificationType != null) {\r
+          if (nameSpace == null && metaDataUtil.getMetaDataByTR69Name(notificationType, swVersion,\r
+              hwVersion) != null) {\r
+            nameSpace =\r
+                metaDataUtil.getMetaDataByTR69Name(notificationType, swVersion, hwVersion).getURI();\r
+          }\r
+\r
+          final Element evtTypeElement = doc.createElementNS(nameSpace, notificationType);\r
+          evtTypeElement.appendChild(dataNode);\r
+          element.appendChild(element.getOwnerDocument().importNode(evtTypeElement, true));\r
+        } else {\r
+          element.appendChild(element.getOwnerDocument().importNode(dataNode, true));\r
+        }\r
+\r
+        result = convertDocumentToString(element);\r
+      }\r
+    } catch (ParserConfigurationException pce) {\r
+      LOG.error("Error occured while preparing the notification");\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
+      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);\r
+    }\r
+    LOG.debug("Converted XML is : " + strxml);\r
+    return strxml;\r
+  }\r
+\r
 }\r