85d8d34a23c3738abfeda22257fd079635483954
[oam/tr069-adapter.git] / netconf-server / src / main / java / org / commscope / tr069adapter / netconf / notification / NetConfSessionUtil.java
1 /*
2  * ============LICENSE_START========================================================================
3  * ONAP : tr-069-adapter
4  * =================================================================================================
5  * Copyright (C) 2020 CommScope Inc Intellectual Property.
6  * =================================================================================================
7  * This tr-069-adapter software file is distributed by CommScope Inc under the Apache License,
8  * Version 2.0 (the "License"); you may not use this file except in compliance with the License. You
9  * may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
14  * either express or implied. See the License for the specific language governing permissions and
15  * limitations under the License.
16  * ===============LICENSE_END=======================================================================
17  */
18
19 package org.commscope.tr069adapter.netconf.notification;\r
20 \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
29 \r
30 import javax.xml.parsers.DocumentBuilder;\r
31 import javax.xml.parsers.DocumentBuilderFactory;\r
32 import javax.xml.parsers.ParserConfigurationException;\r
33 import javax.xml.transform.Transformer;\r
34 import javax.xml.transform.TransformerFactory;\r
35 import javax.xml.transform.dom.DOMSource;\r
36 import javax.xml.transform.stream.StreamResult;\r
37 \r
38 import org.commscope.tr069adapter.acs.common.ParameterDTO;\r
39 import org.commscope.tr069adapter.mapper.model.NetConfNotificationDTO;\r
40 import org.commscope.tr069adapter.netconf.rpc.CreateSubscription;\r
41 import org.opendaylight.netconf.api.NetconfMessage;\r
42 import org.opendaylight.netconf.api.xml.XmlNetconfConstants;\r
43 import org.opendaylight.netconf.api.xml.XmlUtil;\r
44 import org.slf4j.Logger;\r
45 import org.slf4j.LoggerFactory;\r
46 import org.springframework.stereotype.Component;\r
47 import org.w3c.dom.Document;\r
48 import org.w3c.dom.Element;\r
49 import org.xml.sax.SAXException;\r
50 \r
51 @Component\r
52 public class NetConfSessionUtil {\r
53 \r
54   private static final Logger LOG = LoggerFactory.getLogger(NetConfSessionUtil.class);\r
55 \r
56   private static final String INDEX_STR = "index";\r
57   private static final String INDEX_REGEX = "[0-9]{1,}";\r
58   private static final String NS_URI = "urn:onf:otcc:wireless:yang:tr069-notification";\r
59 \r
60   public void sendNetConfNotification(NetConfNotificationDTO netConNotifDTO) {\r
61     NetconfMessage netconfMessage = convertToNetConfMessage(netConNotifDTO);\r
62     LOG.debug("Notification converted to NetConf format" + netconfMessage);\r
63     CreateSubscription.sendNotification(netconfMessage, netConNotifDTO.getDeviceID());\r
64   }\r
65 \r
66   private NetconfMessage convertToNetConfMessage(NetConfNotificationDTO netConNotifDTO) {\r
67     try {\r
68       String nameSpace = "";\r
69       if (netConNotifDTO.getUri() != null) {\r
70         nameSpace = netConNotifDTO.getUri();\r
71       } else {\r
72         nameSpace = NS_URI;\r
73       }\r
74       return new NetconfMessage(\r
75           XmlUtil.readXmlToDocument(getNetconfResponseXML(netConNotifDTO, nameSpace)));\r
76     } catch (SAXException | IOException e) {\r
77       throw new IllegalArgumentException("Cannot parse notifications", e);\r
78     }\r
79   }\r
80 \r
81   private static String getNetconfResponseXML(NetConfNotificationDTO netConNotifDTO,\r
82       String nameSpace) {\r
83     if (netConNotifDTO == null || netConNotifDTO.getParameters().isEmpty()) {\r
84       LOG.debug("There are no parameters found in the response.");\r
85       return null;\r
86     }\r
87 \r
88     List<ParameterDTO> parameters = netConNotifDTO.getParameters();\r
89 \r
90     String result = null;\r
91     try {\r
92       DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();\r
93       DocumentBuilder docBuilder = docFactory.newDocumentBuilder();\r
94       Document doc = docBuilder.newDocument();\r
95 \r
96       Map<String, Element> parentNodeMap = new HashMap<>();\r
97       Element dataNode = null; // root of all nodes\r
98 \r
99       for (ParameterDTO paramDto : parameters) {\r
100         String paramName = paramDto.getParamName();\r
101         String paramValue = paramDto.getParamValue();\r
102         StringTokenizer tokenizer = new StringTokenizer(paramName, ".");\r
103         String parentNodeName = null;\r
104         String parentNodeKey = null;\r
105         Element parentNode = null;\r
106         while (tokenizer.hasMoreElements()) {\r
107           String nodeName = (String) tokenizer.nextElement();\r
108           if (null == parentNodeName) { // construct first node or\r
109                                         // Device node\r
110             parentNodeName = nodeName;\r
111             parentNodeKey = nodeName;\r
112             // check if the node already exists in parentNodeMap\r
113             parentNode = parentNodeMap.get(parentNodeKey);\r
114             if (null == dataNode) {\r
115               dataNode = parentNode;\r
116             }\r
117             continue;\r
118           } else if (nodeName.matches(INDEX_REGEX)) { // construct\r
119                                                       // tabular and\r
120                                                       // index nodes\r
121 \r
122             // get parent tabular node from parent MAP\r
123             parentNodeKey = parentNodeKey + "." + nodeName;\r
124             Element node = parentNodeMap.get(parentNodeKey);\r
125 \r
126             // create a tabular parent node if doesn't exit in MAP\r
127             if (null == node) {\r
128               node = doc.createElement(parentNodeName);\r
129               parentNodeMap.put(parentNodeKey, node);\r
130 \r
131               // update current tabular parent node.\r
132               if (null != parentNode)\r
133                 parentNode.appendChild(node);\r
134               else\r
135                 parentNode = node;\r
136 \r
137               // prepare and add index node to tabular parent node\r
138               Element indexNode = doc.createElement(INDEX_STR);\r
139               indexNode.setTextContent(nodeName);\r
140               node.appendChild(indexNode);\r
141             }\r
142             parentNode = node; // move parent to child\r
143             parentNodeName = nodeName;\r
144           } else if (parentNodeName.matches(INDEX_REGEX)) { // move to\r
145                                                             // next\r
146                                                             // node\r
147                                                             // if\r
148                                                             // tabular\r
149                                                             // attribute\r
150                                                             // is\r
151                                                             // found\r
152             parentNodeKey = parentNodeKey + "." + nodeName;\r
153             parentNodeName = nodeName;\r
154           } else {\r
155             // construct intermediate nodes\r
156             Element node = parentNodeMap.get(parentNodeKey);\r
157             if (null == node) {\r
158               if (null == dataNode) {\r
159                 node = doc.createElementNS(nameSpace, parentNodeName);\r
160                 dataNode = node;\r
161               } else {\r
162                 node = doc.createElement(parentNodeName);\r
163               }\r
164               parentNodeMap.put(parentNodeKey, node);\r
165               if (null != parentNode)\r
166                 parentNode.appendChild(node);\r
167             }\r
168             parentNodeKey = parentNodeKey + "." + nodeName;\r
169             parentNodeName = nodeName;\r
170             parentNode = node;\r
171           }\r
172         }\r
173         // construct leaf node\r
174         Element leafNode = doc.createElement(parentNodeName);\r
175         leafNode.setTextContent(paramValue);\r
176         parentNode.appendChild(leafNode);\r
177       }\r
178 \r
179       if (null != dataNode) {\r
180         final Element element = doc.createElement(XmlNetconfConstants.NOTIFICATION_ELEMENT_NAME);\r
181         final Element eventTime = doc.createElement(XmlNetconfConstants.EVENT_TIME);\r
182         eventTime\r
183             .setTextContent(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX").format(new Date()));\r
184         element.appendChild(element.getOwnerDocument().importNode(eventTime, true));\r
185 \r
186         if (netConNotifDTO.getNotificationType() != null) {\r
187           final Element evtTypeElement =\r
188               doc.createElementNS(nameSpace, netConNotifDTO.getNotificationType());\r
189           evtTypeElement.appendChild(dataNode);\r
190           element.appendChild(element.getOwnerDocument().importNode(evtTypeElement, true));\r
191         } else {\r
192           element.appendChild(element.getOwnerDocument().importNode(dataNode, true));\r
193         }\r
194 \r
195         result = convertDocumentToString(element);\r
196       }\r
197     } catch (ParserConfigurationException pce) {\r
198       pce.printStackTrace();\r
199     }\r
200 \r
201     return result;\r
202   }\r
203 \r
204   public static String convertDocumentToString(Element element) {\r
205     String strxml = null;\r
206     try {\r
207       TransformerFactory transformerFactory = TransformerFactory.newInstance();\r
208       Transformer transformer = transformerFactory.newTransformer();\r
209       DOMSource source = new DOMSource(element);\r
210       StreamResult result = new StreamResult(new StringWriter());\r
211       transformer.transform(source, result);\r
212       strxml = result.getWriter().toString();\r
213     } catch (Exception e) {\r
214       LOG.error("Error while converting Element to String" + e);\r
215     }\r
216     LOG.debug("Converted XML is : " + strxml);\r
217     return strxml;\r
218   }\r
219 \r
220 }\r