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
11 * http://www.apache.org/licenses/LICENSE-2.0
\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
19 package org.commscope.tr069adapter.mapper.netconf;
\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
52 public class NetConfNotificationSender {
\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
65 MapperConfigProperties config;
\r
68 MOMetaDataUtil metaDataUtil;
\r
71 RestTemplate restTemplate;
\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
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
86 convertTR069ToNetConfParams(parameters, deviceInform.getDeviceDetails().getSoftwareVersion(),
\r
87 deviceInform.getDeviceDetails().getHardwareVersion());
\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
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
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
111 String notificationXml = getNetconfResponseXML(parameters, null, nameSpace, null, null);
\r
112 NetConfNotificationDTO netConfDTO = new NetConfNotificationDTO(deviceId, notificationXml);
\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
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
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
138 removeList.add(param); // unknown parameter found.
\r
141 parameters.removeAll(removeList);
\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
157 private String getUri() {
\r
158 return config.getNbiNotificationUri();
\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
168 String result = null;
\r
170 DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
\r
171 DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
\r
172 Document doc = docBuilder.newDocument();
\r
174 Map<String, Element> parentNodeMap = new HashMap<>();
\r
175 Element dataNode = null; // root of all nodes
\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
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
196 } else if (nodeName.matches(INDEX_REGEX)) { // construct
\r
200 // get parent tabular node from parent MAP
\r
201 parentNodeKey = parentNodeKey + "." + nodeName;
\r
202 Element node = parentNodeMap.get(parentNodeKey);
\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
209 // update current tabular parent node.
\r
210 if (null != parentNode)
\r
211 parentNode.appendChild(node);
\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
220 parentNode = node; // move parent to child
\r
221 parentNodeName = nodeName;
\r
222 } else if (parentNodeName.matches(INDEX_REGEX)) { // move to
\r
230 parentNodeKey = parentNodeKey + "." + nodeName;
\r
231 parentNodeName = nodeName;
\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
240 node = doc.createElement(parentNodeName);
\r
242 parentNodeMap.put(parentNodeKey, node);
\r
243 if (null != parentNode)
\r
244 parentNode.appendChild(node);
\r
246 parentNodeKey = parentNodeKey + "." + nodeName;
\r
247 parentNodeName = nodeName;
\r
251 // construct leaf node
\r
252 Element leafNode = doc.createElement(parentNodeName);
\r
253 leafNode.setTextContent(paramValue);
\r
254 parentNode.appendChild(leafNode);
\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
261 .setTextContent(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX").format(new Date()));
\r
262 element.appendChild(element.getOwnerDocument().importNode(eventTime, true));
\r
264 if (notificationType != null) {
\r
265 if (nameSpace == null && metaDataUtil.getMetaDataByTR69Name(notificationType, swVersion,
\r
266 hwVersion) != null) {
\r
268 metaDataUtil.getMetaDataByTR69Name(notificationType, swVersion, hwVersion).getURI();
\r
271 final Element evtTypeElement = doc.createElementNS(nameSpace, notificationType);
\r
272 evtTypeElement.appendChild(dataNode);
\r
273 element.appendChild(element.getOwnerDocument().importNode(evtTypeElement, true));
\r
275 element.appendChild(element.getOwnerDocument().importNode(dataNode, true));
\r
278 result = convertDocumentToString(element);
\r
280 } catch (ParserConfigurationException pce) {
\r
281 LOG.error("Error occured while preparing the notification");
\r
287 public static String convertDocumentToString(Element element) {
\r
288 String strxml = null;
\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
299 LOG.debug("Converted XML is : " + strxml);
\r