15024c29508695906566e0433066525d1d78f970
[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           removeList.add(param);\r
129           continue;\r
130         }\r
131         handleBooleanParameters(param, swVersion, hwVersion);\r
132         if (null != param.getParamName()) {\r
133           String netConfMOName = metaDataUtil\r
134               .getNetconfNameByTR69NameWithIndexes(param.getParamName(), swVersion, hwVersion);\r
135           if (null != netConfMOName)\r
136             param.setParamName(netConfMOName);\r
137           else\r
138             removeList.add(param); // unknown parameter found.\r
139         }\r
140       }\r
141       parameters.removeAll(removeList);\r
142     }\r
143   }\r
144 \r
145   private void handleBooleanParameters(ParameterDTO param, String swVersion, String hwVersion) {\r
146     MOMetaData metaData =\r
147         metaDataUtil.getMetaDataByTR69Name(param.getParamName(), swVersion, hwVersion);\r
148     if (null != metaData && BOOLEAN_DATA_TYPE.equalsIgnoreCase(metaData.getDataType())) {\r
149       if (BOOLEAN_TRUE_VALUE.equalsIgnoreCase(param.getParamValue().trim())) {\r
150         param.setParamValue(Boolean.TRUE.toString());\r
151       } else if (BOOLEAN_FALSE_VALUE.equalsIgnoreCase(param.getParamValue().trim())) {\r
152         param.setParamValue(Boolean.FALSE.toString());\r
153       }\r
154     }\r
155   }\r
156 \r
157   private String getUri() {\r
158     return config.getNbiNotificationUri();\r
159   }\r
160 \r
161   private String getNetconfResponseXML(List<ParameterDTO> parameters, String notificationType,\r
162       String nameSpace, String swVersion, String hwVersion) {\r
163     if (parameters == null || parameters.isEmpty()) {\r
164       LOG.debug("There are no parameters found in the response.");\r
165       return null;\r
166     }\r
167 \r
168     String result = null;\r
169     try {\r
170       DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();\r
171       DocumentBuilder docBuilder = docFactory.newDocumentBuilder();\r
172       Document doc = docBuilder.newDocument();\r
173 \r
174       Map<String, Element> parentNodeMap = new HashMap<>();\r
175       Element dataNode = null; // root of all nodes\r
176 \r
177       for (ParameterDTO paramDto : parameters) {\r
178         String paramName = paramDto.getParamName();\r
179         String paramValue = paramDto.getParamValue();\r
180         StringTokenizer tokenizer = new StringTokenizer(paramName, ".");\r
181         String parentNodeName = null;\r
182         String parentNodeKey = null;\r
183         Element parentNode = null;\r
184         while (tokenizer.hasMoreElements()) {\r
185           String nodeName = (String) tokenizer.nextElement();\r
186           if (null == parentNodeName) { // construct first node or\r
187                                         // Device node\r
188             parentNodeName = nodeName;\r
189             parentNodeKey = nodeName;\r
190             // check if the node already exists in parentNodeMap\r
191             parentNode = parentNodeMap.get(parentNodeKey);\r
192             if (null == dataNode) {\r
193               dataNode = parentNode;\r
194             }\r
195             continue;\r
196           } else if (nodeName.matches(INDEX_REGEX)) { // construct\r
197                                                       // tabular and\r
198                                                       // index nodes\r
199 \r
200             // get parent tabular node from parent MAP\r
201             parentNodeKey = parentNodeKey + "." + nodeName;\r
202             Element node = parentNodeMap.get(parentNodeKey);\r
203 \r
204             // create a tabular parent node if doesn't exit in MAP\r
205             if (null == node) {\r
206               node = doc.createElement(parentNodeName);\r
207               parentNodeMap.put(parentNodeKey, node);\r
208 \r
209               // update current tabular parent node.\r
210               if (null != parentNode)\r
211                 parentNode.appendChild(node);\r
212               else\r
213                 parentNode = node;\r
214 \r
215               // prepare and add index node to tabular parent node\r
216               Element indexNode = doc.createElement(INDEX_STR);\r
217               indexNode.setTextContent(nodeName);\r
218               node.appendChild(indexNode);\r
219             }\r
220             parentNode = node; // move parent to child\r
221             parentNodeName = nodeName;\r
222           } else if (parentNodeName.matches(INDEX_REGEX)) { // move to\r
223                                                             // next\r
224                                                             // node\r
225                                                             // if\r
226                                                             // tabular\r
227                                                             // attribute\r
228                                                             // is\r
229                                                             // found\r
230             parentNodeKey = parentNodeKey + "." + nodeName;\r
231             parentNodeName = nodeName;\r
232           } else {\r
233             // construct intermediate nodes\r
234             Element node = parentNodeMap.get(parentNodeKey);\r
235             if (null == node) {\r
236               if (null == dataNode) {\r
237                 node = doc.createElementNS(nameSpace, parentNodeName);\r
238                 dataNode = node;\r
239               } else {\r
240                 node = doc.createElement(parentNodeName);\r
241               }\r
242               parentNodeMap.put(parentNodeKey, node);\r
243               if (null != parentNode)\r
244                 parentNode.appendChild(node);\r
245             }\r
246             parentNodeKey = parentNodeKey + "." + nodeName;\r
247             parentNodeName = nodeName;\r
248             parentNode = node;\r
249           }\r
250         }\r
251         // construct leaf node\r
252         Element leafNode = doc.createElement(parentNodeName);\r
253         leafNode.setTextContent(paramValue);\r
254         parentNode.appendChild(leafNode);\r
255       }\r
256 \r
257       if (null != dataNode) {\r
258         final Element element = doc.createElement(NOTIFICATION_ELEMENT_NAME);\r
259         final Element eventTime = doc.createElement(EVENT_TIME);\r
260         eventTime\r
261             .setTextContent(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX").format(new Date()));\r
262         element.appendChild(element.getOwnerDocument().importNode(eventTime, true));\r
263 \r
264         if (notificationType != null) {\r
265           if (nameSpace == null && metaDataUtil.getMetaDataByTR69Name(notificationType, swVersion,\r
266               hwVersion) != null) {\r
267             nameSpace =\r
268                 metaDataUtil.getMetaDataByTR69Name(notificationType, swVersion, hwVersion).getURI();\r
269           }\r
270 \r
271           final Element evtTypeElement = doc.createElementNS(nameSpace, notificationType);\r
272           evtTypeElement.appendChild(dataNode);\r
273           element.appendChild(element.getOwnerDocument().importNode(evtTypeElement, true));\r
274         } else {\r
275           element.appendChild(element.getOwnerDocument().importNode(dataNode, true));\r
276         }\r
277 \r
278         result = convertDocumentToString(element);\r
279       }\r
280     } catch (ParserConfigurationException pce) {\r
281       LOG.error("Error occured while preparing the notification");\r
282     }\r
283 \r
284     return result;\r
285   }\r
286 \r
287   public static String convertDocumentToString(Element element) {\r
288     String strxml = null;\r
289     try {\r
290       TransformerFactory transformerFactory = TransformerFactory.newInstance();\r
291       Transformer transformer = transformerFactory.newTransformer();\r
292       DOMSource source = new DOMSource(element);\r
293       StreamResult result = new StreamResult(new StringWriter());\r
294       transformer.transform(source, result);\r
295       strxml = result.getWriter().toString();\r
296     } catch (Exception e) {\r
297       LOG.error("Error while converting Element to String" + e);\r
298     }\r
299     LOG.debug("Converted XML is : " + strxml);\r
300     return strxml;\r
301   }\r
302 \r
303 }\r