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.netconf.notification;
\r
21 import java.io.IOException;
\r
22 import java.io.StringWriter;
\r
23 import java.text.SimpleDateFormat;
\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
30 import javax.xml.XMLConstants;
\r
31 import javax.xml.parsers.DocumentBuilder;
\r
32 import javax.xml.parsers.DocumentBuilderFactory;
\r
33 import javax.xml.parsers.ParserConfigurationException;
\r
34 import javax.xml.transform.Transformer;
\r
35 import javax.xml.transform.TransformerFactory;
\r
36 import javax.xml.transform.dom.DOMSource;
\r
37 import javax.xml.transform.stream.StreamResult;
\r
39 import org.commscope.tr069adapter.acs.common.DeviceInform;
\r
40 import org.commscope.tr069adapter.acs.common.ParameterDTO;
\r
41 import org.commscope.tr069adapter.netconf.rpc.CreateSubscription;
\r
42 import org.opendaylight.netconf.api.NetconfMessage;
\r
43 import org.opendaylight.netconf.api.xml.XmlNetconfConstants;
\r
44 import org.opendaylight.netconf.api.xml.XmlUtil;
\r
45 import org.slf4j.Logger;
\r
46 import org.slf4j.LoggerFactory;
\r
47 import org.springframework.stereotype.Component;
\r
48 import org.w3c.dom.Document;
\r
49 import org.w3c.dom.Element;
\r
50 import org.xml.sax.SAXException;
\r
53 public class NetConfSessionUtil {
\r
55 private static final Logger LOG = LoggerFactory.getLogger(NetConfSessionUtil.class);
\r
57 private static final String INDEX_STR = "index";
\r
58 private static final String INDEX_REGEX = "[0-9]{1,}";
\r
59 private static final String NS_URI = "urn:onf:otcc:wireless:yang:tr069-notification";
\r
61 public void sendNetConfNotification(DeviceInform notification) {
\r
62 NetconfMessage netconfMessage = convertToNetConfMessage(notification);
\r
63 LOG.debug("Notification converted to NetConf format {}", netconfMessage);
\r
64 CreateSubscription.sendNotification(netconfMessage,
\r
65 notification.getDeviceDetails().getDeviceId());
\r
68 private NetconfMessage convertToNetConfMessage(DeviceInform notification) {
\r
70 String netConfXmlMsg = getNetconfResponseXML(notification);
\r
71 if (netConfXmlMsg == null)
\r
72 throw new IllegalArgumentException("There are no parameters found in the response");
\r
73 return new NetconfMessage(XmlUtil.readXmlToDocument(netConfXmlMsg));
\r
74 } catch (SAXException | IOException e) {
\r
75 throw new IllegalArgumentException("Cannot parse notifications", e);
\r
79 private static String getNetconfResponseXML(DeviceInform notification) {
\r
80 if (notification == null || notification.getParameters().isEmpty()) {
\r
81 LOG.debug("There are no parameters found in the response.");
\r
85 List<ParameterDTO> parameters = notification.getParameters();
\r
87 String result = null;
\r
89 DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
\r
90 docFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
\r
91 docFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
\r
92 DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
\r
93 Document doc = docBuilder.newDocument();
\r
95 Map<String, Element> parentNodeMap = new HashMap<>();
\r
96 Element dataNode = null; // root of all nodes
\r
98 for (ParameterDTO paramDto : parameters) {
\r
99 String paramName = paramDto.getParamName();
\r
100 String paramValue = paramDto.getParamValue();
\r
101 StringTokenizer tokenizer = new StringTokenizer(paramName, ".");
\r
102 String parentNodeName = null;
\r
103 StringBuilder parentNodeKey = null;
\r
104 Element parentNode = null;
\r
105 while (tokenizer.hasMoreElements()) {
\r
106 String nodeName = (String) tokenizer.nextElement();
\r
107 if (null == parentNodeName) { // construct first node or
\r
109 parentNodeName = nodeName;
\r
110 parentNodeKey = new StringBuilder(nodeName);
\r
111 // check if the node already exists in parentNodeMap
\r
112 parentNode = parentNodeMap.get(parentNodeKey.toString());
\r
113 if (null == dataNode) {
\r
114 dataNode = parentNode;
\r
116 } else if (nodeName.matches(INDEX_REGEX)) { // construct
\r
120 // get parent tabular node from parent MAP
\r
121 parentNodeKey = parentNodeKey.append(".").append(nodeName);
\r
122 Element node = parentNodeMap.get(parentNodeKey.toString());
\r
124 // create a tabular parent node if doesn't exit in MAP
\r
125 if (null == node) {
\r
126 node = doc.createElement(parentNodeName);
\r
127 parentNodeMap.put(parentNodeKey.toString(), node);
\r
129 // update current tabular parent node.
\r
130 if (null != parentNode)
\r
131 parentNode.appendChild(node);
\r
133 // prepare and add index node to tabular parent node
\r
134 Element indexNode = doc.createElement(INDEX_STR);
\r
135 indexNode.setTextContent(nodeName);
\r
136 node.appendChild(indexNode);
\r
138 parentNode = node; // move parent to child
\r
139 parentNodeName = nodeName;
\r
140 } else if (parentNodeName.matches(INDEX_REGEX)) { // move to
\r
148 parentNodeKey = parentNodeKey.append(".").append(nodeName);
\r
149 parentNodeName = nodeName;
\r
151 // construct intermediate nodes
\r
152 Element node = parentNodeMap.get(parentNodeKey.toString());
\r
153 if (null == node) {
\r
154 if (null == dataNode) {
\r
155 node = doc.createElementNS(NS_URI, parentNodeName);
\r
158 node = doc.createElement(parentNodeName);
\r
160 parentNodeMap.put(parentNodeKey.toString(), node);
\r
161 if (null != parentNode)
\r
162 parentNode.appendChild(node);
\r
164 parentNodeKey = parentNodeKey.append(".").append(nodeName);
\r
165 parentNodeName = nodeName;
\r
169 // construct leaf node
\r
170 Element leafNode = doc.createElement(parentNodeName);
\r
171 leafNode.setTextContent(paramValue);
\r
172 if (null != parentNode)
\r
173 parentNode.appendChild(leafNode);
\r
176 if (null != dataNode) {
\r
177 final Element element = doc.createElement(XmlNetconfConstants.NOTIFICATION_ELEMENT_NAME);
\r
178 final Element eventTime = doc.createElement(XmlNetconfConstants.EVENT_TIME);
\r
180 .setTextContent(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX").format(new Date()));
\r
182 final Element evtTypeElement =
\r
183 doc.createElementNS(NS_URI, notification.getInformTypeList().get(0).toString());
\r
184 evtTypeElement.appendChild(dataNode);
\r
185 element.appendChild(element.getOwnerDocument().importNode(eventTime, true));
\r
186 element.appendChild(element.getOwnerDocument().importNode(evtTypeElement, true));
\r
187 result = convertDocumentToString(element);
\r
189 } catch (ParserConfigurationException pce) {
\r
190 LOG.error("Error while getNetconfResponseXML {}", pce.toString());
\r
196 public static String convertDocumentToString(Element element) {
\r
197 String strxml = null;
\r
199 TransformerFactory transformerFactory = TransformerFactory.newInstance();
\r
200 transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
\r
201 transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
\r
202 Transformer transformer = transformerFactory.newTransformer();
\r
203 DOMSource source = new DOMSource(element);
\r
204 StreamResult result = new StreamResult(new StringWriter());
\r
205 transformer.transform(source, result);
\r
206 strxml = result.getWriter().toString();
\r
207 } catch (Exception e) {
\r
208 LOG.error("Error while converting Element to String {}", e.toString());
\r
210 LOG.debug("Converted XML is : {}", strxml);
\r