2b6fd9eab72a1a9d832539f395ed09c6548188e7
[oam/tr069-adapter.git] / mapper / src / main / java / org / commscope / tr069adapter / mapper / netconf / NetConfNotificationSender.java
1 /*\r
2  * ============LICENSE_START========================================================================\r
3  * ONAP : tr-069-adapter\r
4  * =================================================================================================\r
5  * Copyright (C) 2020 CommScope Inc Intellectual Property.\r
6  * =================================================================================================\r
7  * This tr-069-adapter software file is distributed by CommScope Inc under the Apache License,\r
8  * Version 2.0 (the "License"); you may not use this file except in compliance with the License. You\r
9  * may obtain a copy of the License at\r
10  *\r
11  * http://www.apache.org/licenses/LICENSE-2.0\r
12  *\r
13  * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\r
14  * either express or implied. See the License for the specific language governing permissions and\r
15  * limitations under the License.\r
16  * ===============LICENSE_END=======================================================================\r
17  */\r
18 \r
19 package org.commscope.tr069adapter.mapper.netconf;\r
20 \r
21 import java.io.StringWriter;\r
22 import java.text.SimpleDateFormat;\r
23 import java.util.ArrayList;\r
24 import java.util.Date;\r
25 import java.util.HashMap;\r
26 import java.util.List;\r
27 import java.util.Map;\r
28 import java.util.StringTokenizer;\r
29 import javax.xml.parsers.DocumentBuilder;\r
30 import javax.xml.parsers.DocumentBuilderFactory;\r
31 import javax.xml.parsers.ParserConfigurationException;\r
32 import javax.xml.transform.Transformer;\r
33 import javax.xml.transform.TransformerFactory;\r
34 import javax.xml.transform.dom.DOMSource;\r
35 import javax.xml.transform.stream.StreamResult;\r
36 import org.commscope.tr069adapter.acs.common.DeviceInform;\r
37 import org.commscope.tr069adapter.acs.common.ParameterDTO;\r
38 import org.commscope.tr069adapter.mapper.MOMetaData;\r
39 import org.commscope.tr069adapter.mapper.MapperConfigProperties;\r
40 import org.commscope.tr069adapter.mapper.model.NetConfNotificationDTO;\r
41 import org.commscope.tr069adapter.mapper.util.MOMetaDataUtil;\r
42 import org.slf4j.Logger;\r
43 import org.slf4j.LoggerFactory;\r
44 import org.springframework.beans.factory.annotation.Autowired;\r
45 import org.springframework.http.ResponseEntity;\r
46 import org.springframework.stereotype.Component;\r
47 import org.springframework.web.client.RestTemplate;\r
48 import org.w3c.dom.Document;\r
49 import org.w3c.dom.Element;\r
50 \r
51 @Component\r
52 public class NetConfNotificationSender {\r
53 \r
54   private static final Logger LOG = LoggerFactory.getLogger(NetConfNotificationSender.class);\r
55   private static final String BOOLEAN_TRUE_VALUE = "1";\r
56   private static final String BOOLEAN_FALSE_VALUE = "0";\r
57   private static final String BOOLEAN_DATA_TYPE = "boolean";\r
58   public static final String NOTIFICATION_ELEMENT_NAME = "notification";\r
59   public static final String EVENT_TIME = "eventTime";\r
60   private static final String INDEX_STR = "index";\r
61   private static final String INDEX_REGEX = "[0-9]{1,}";\r
62 \r
63 \r
64   @Autowired\r
65   MapperConfigProperties config;\r
66 \r
67   @Autowired\r
68   MOMetaDataUtil metaDataUtil;\r
69 \r
70   @Autowired\r
71   RestTemplate restTemplate;\r
72 \r
73   public ResponseEntity sendNotification(DeviceInform deviceInform) {\r
74     ResponseEntity response = null;\r
75     final String uri = getUri();\r
76     LOG.debug("Posting notification to netconf server {}", uri);\r
77 \r
78     try {\r
79       LOG.debug("deviceInform : {} {}", deviceInform.getInformTypeList(),\r
80           deviceInform.getParameters());\r
81       List<ParameterDTO> parameters = new ArrayList<>();\r
82       for (ParameterDTO parameterDTO : deviceInform.getParameters()) {\r
83         parameters.add(parameterDTO);\r
84       }\r
85 \r
86       convertTR069ToNetConfParams(parameters, deviceInform.getDeviceDetails().getSoftwareVersion(),\r
87           deviceInform.getDeviceDetails().getHardwareVersion());\r
88 \r
89       String notificationXml =\r
90           getNetconfResponseXML(parameters, deviceInform.getInformType().toString(), null,\r
91               deviceInform.getDeviceDetails().getSoftwareVersion(),\r
92               deviceInform.getDeviceDetails().getHardwareVersion());\r
93       NetConfNotificationDTO netConfDTO = new NetConfNotificationDTO(\r
94           deviceInform.getDeviceDetails().getDeviceId(), notificationXml);\r
95 \r
96       LOG.debug("Posting notification to netconf server");\r
97       response = restTemplate.postForObject(uri, netConfDTO, ResponseEntity.class);\r
98       LOG.debug("Posting notification to netconf server completed ");\r
99     } catch (Exception e) {\r
100       LOG.error("Exception while sending the notification.", e);\r
101     }\r
102     return response;\r
103   }\r
104 \r
105   public ResponseEntity sendCustomNotification(String deviceId, List<ParameterDTO> parameters,\r
106       String nameSpace) {\r
107     ResponseEntity response = null;\r
108     final String uri = getUri();\r
109     LOG.debug("Posting custom notification to netconf server " + uri);\r
110     try {\r
111       String notificationXml = getNetconfResponseXML(parameters, null, nameSpace, null, null);\r
112       NetConfNotificationDTO netConfDTO = new NetConfNotificationDTO(deviceId, notificationXml);\r
113 \r
114       response = restTemplate.postForObject(uri, netConfDTO, ResponseEntity.class);\r
115       LOG.debug("Posting custom notification to netconf server sucessfull");\r
116     } catch (Exception e) {\r
117       LOG.error("Exception while sending the custom notification.", e.toString());\r
118     }\r
119     return response;\r
120   }\r
121 \r
122   private void convertTR069ToNetConfParams(List<ParameterDTO> parameters, String swVersion,\r
123       String hwVersion) {\r
124     List<ParameterDTO> removeList = new ArrayList<>();\r
125     if (null != parameters) {\r
126       for (ParameterDTO param : parameters) {\r
127         if (param.getParamValue() == null || param.getParamValue().trim().length() <= 0) {\r
128           continue;\r
129         }\r
130         handleBooleanParameters(param, swVersion, hwVersion);\r
131         if (null != param.getParamName()) {\r
132           String netConfMOName = metaDataUtil\r
133               .getNetconfNameByTR69NameWithIndexes(param.getParamName(), swVersion, hwVersion);\r
134           if (null != netConfMOName)\r
135             param.setParamName(netConfMOName);\r
136           else\r
137             removeList.add(param); // unknown parameter found.\r
138         }\r
139       }\r
140       parameters.removeAll(removeList);\r
141     }\r
142   }\r
143 \r
144   private void handleBooleanParameters(ParameterDTO param, String swVersion, String hwVersion) {\r
145     MOMetaData metaData =\r
146         metaDataUtil.getMetaDataByTR69Name(param.getParamName(), swVersion, hwVersion);\r
147     if (null != metaData && BOOLEAN_DATA_TYPE.equalsIgnoreCase(metaData.getDataType())) {\r
148       if (BOOLEAN_TRUE_VALUE.equalsIgnoreCase(param.getParamValue().trim())) {\r
149         param.setParamValue(Boolean.TRUE.toString());\r
150       } else if (BOOLEAN_FALSE_VALUE.equalsIgnoreCase(param.getParamValue().trim())) {\r
151         param.setParamValue(Boolean.FALSE.toString());\r
152       }\r
153     }\r
154   }\r
155 \r
156   private String getUri() {\r
157     return config.getNbiNotificationUri();\r
158   }\r
159 \r
160   private String getNetconfResponseXML(List<ParameterDTO> parameters, String notificationType,\r
161       String nameSpace, String swVersion, String hwVersion) {\r
162     if (parameters == null || parameters.isEmpty()) {\r
163       LOG.debug("There are no parameters found in the response.");\r
164       return null;\r
165     }\r
166 \r
167     String result = null;\r
168     try {\r
169       DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();\r
170       DocumentBuilder docBuilder = docFactory.newDocumentBuilder();\r
171       Document doc = docBuilder.newDocument();\r
172 \r
173       Map<String, Element> parentNodeMap = new HashMap<>();\r
174       Element dataNode = null; // root of all nodes\r
175 \r
176       for (ParameterDTO paramDto : parameters) {\r
177         String paramName = paramDto.getParamName();\r
178         String paramValue = paramDto.getParamValue();\r
179         StringTokenizer tokenizer = new StringTokenizer(paramName, ".");\r
180         String parentNodeName = null;\r
181         String parentNodeKey = null;\r
182         Element parentNode = null;\r
183         while (tokenizer.hasMoreElements()) {\r
184           String nodeName = (String) tokenizer.nextElement();\r
185           if (null == parentNodeName) { // construct first node or\r
186                                         // Device node\r
187             parentNodeName = nodeName;\r
188             parentNodeKey = nodeName;\r
189             // check if the node already exists in parentNodeMap\r
190             parentNode = parentNodeMap.get(parentNodeKey);\r
191             if (null == dataNode) {\r
192               dataNode = parentNode;\r
193             }\r
194             continue;\r
195           } else if (nodeName.matches(INDEX_REGEX)) { // construct\r
196                                                       // tabular and\r
197                                                       // index nodes\r
198 \r
199             // get parent tabular node from parent MAP\r
200             parentNodeKey = parentNodeKey + "." + nodeName;\r
201             Element node = parentNodeMap.get(parentNodeKey);\r
202 \r
203             // create a tabular parent node if doesn't exit in MAP\r
204             if (null == node) {\r
205               node = doc.createElement(parentNodeName);\r
206               parentNodeMap.put(parentNodeKey, node);\r
207 \r
208               // update current tabular parent node.\r
209               if (null != parentNode)\r
210                 parentNode.appendChild(node);\r
211               else\r
212                 parentNode = node;\r
213 \r
214               // prepare and add index node to tabular parent node\r
215               Element indexNode = doc.createElement(INDEX_STR);\r
216               indexNode.setTextContent(nodeName);\r
217               node.appendChild(indexNode);\r
218             }\r
219             parentNode = node; // move parent to child\r
220             parentNodeName = nodeName;\r
221           } else if (parentNodeName.matches(INDEX_REGEX)) { // move to\r
222                                                             // next\r
223                                                             // node\r
224                                                             // if\r
225                                                             // tabular\r
226                                                             // attribute\r
227                                                             // is\r
228                                                             // found\r
229             parentNodeKey = parentNodeKey + "." + nodeName;\r
230             parentNodeName = nodeName;\r
231           } else {\r
232             // construct intermediate nodes\r
233             Element node = parentNodeMap.get(parentNodeKey);\r
234             if (null == node) {\r
235               if (null == dataNode) {\r
236                 node = doc.createElementNS(nameSpace, parentNodeName);\r
237                 dataNode = node;\r
238               } else {\r
239                 node = doc.createElement(parentNodeName);\r
240               }\r
241               parentNodeMap.put(parentNodeKey, node);\r
242               if (null != parentNode)\r
243                 parentNode.appendChild(node);\r
244             }\r
245             parentNodeKey = parentNodeKey + "." + nodeName;\r
246             parentNodeName = nodeName;\r
247             parentNode = node;\r
248           }\r
249         }\r
250         // construct leaf node\r
251         Element leafNode = doc.createElement(parentNodeName);\r
252         leafNode.setTextContent(paramValue);\r
253         parentNode.appendChild(leafNode);\r
254       }\r
255 \r
256       if (null != dataNode) {\r
257         final Element element = doc.createElement(NOTIFICATION_ELEMENT_NAME);\r
258         final Element eventTime = doc.createElement(EVENT_TIME);\r
259         eventTime\r
260             .setTextContent(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX").format(new Date()));\r
261         element.appendChild(element.getOwnerDocument().importNode(eventTime, true));\r
262 \r
263         if (notificationType != null) {\r
264           if (nameSpace == null && metaDataUtil.getMetaDataByTR69Name(notificationType, swVersion,\r
265               hwVersion) != null) {\r
266             nameSpace =\r
267                 metaDataUtil.getMetaDataByTR69Name(notificationType, swVersion, hwVersion).getURI();\r
268           }\r
269 \r
270           final Element evtTypeElement = doc.createElementNS(nameSpace, notificationType);\r
271           evtTypeElement.appendChild(dataNode);\r
272           element.appendChild(element.getOwnerDocument().importNode(evtTypeElement, true));\r
273         } else {\r
274           element.appendChild(element.getOwnerDocument().importNode(dataNode, true));\r
275         }\r
276 \r
277         result = convertDocumentToString(element);\r
278       }\r
279     } catch (ParserConfigurationException pce) {\r
280       LOG.error("Error occured while preparing the notification");\r
281     }\r
282 \r
283     return result;\r
284   }\r
285 \r
286   public static String convertDocumentToString(Element element) {\r
287     String strxml = null;\r
288     try {\r
289       TransformerFactory transformerFactory = TransformerFactory.newInstance();\r
290       Transformer transformer = transformerFactory.newTransformer();\r
291       DOMSource source = new DOMSource(element);\r
292       StreamResult result = new StreamResult(new StringWriter());\r
293       transformer.transform(source, result);\r
294       strxml = result.getWriter().toString();\r
295     } catch (Exception e) {\r
296       LOG.error("Error while converting Element to String" + e);\r
297     }\r
298     LOG.debug("Converted XML is : " + strxml);\r
299     return strxml;\r
300   }\r
301 \r
302 }\r