fc98d45ff1b92861c77694892dbfb06f02102b04
[ccsdk/apps.git] / sdnr / wireless-transport / code-Carbon-SR1 / apps / devicemanager / impl / src / main / java / org / opendaylight / mwtn / dcaeConnector / impl / DcaeMessages.java
1 /**
2         ecompProvider.sendProblemNotification(ownKeyName, notificationXml);
3  * ECOMP Messages are generated an send to destination
4  *
5  * @author herbert
6  */
7 package org.opendaylight.mwtn.dcaeConnector.impl;
8
9 import java.io.IOException;
10 import java.net.HttpURLConnection;
11 import java.net.MalformedURLException;
12 import java.net.URL;
13 import java.net.URLConnection;
14 import java.text.ParseException;
15
16 import javax.annotation.Nullable;
17 import javax.net.ssl.HostnameVerifier;
18 import javax.net.ssl.HttpsURLConnection;
19 import javax.net.ssl.SSLContext;
20 import javax.net.ssl.SSLSession;
21
22 import org.opendaylight.mwtn.base.internalTypes.InternalSeverity;
23 import org.opendaylight.mwtn.base.internalTypes.InventoryInformation;
24 import org.opendaylight.mwtn.base.netconf.NetconfTimeStamp;
25 import org.opendaylight.mwtn.base.netconf.ONFCoreNetworkElementRepresentation;
26 import org.opendaylight.mwtn.devicemanager.impl.DeviceManagerImpl;
27 import org.opendaylight.mwtn.devicemanager.impl.xml.ProblemNotificationXml;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 public class DcaeMessages {
32
33         private static final Logger LOG = LoggerFactory.getLogger(DcaeSenderImpl.class);
34
35     private static final String DCAE_NORMAL =  "NORMAL";
36     private static final String DCAE_MINOR =  "MINOR";
37     private static final String DCAE_WARNING =  "WARNING";
38     private static final String DCAE_CRITICAL =  "CRITICAL";
39     private static final String DCAE_MAJOR =  "MAJOR";
40
41     private static final String eventNamePrefix = "fault_Microwave_Radio_Alarms";
42     private static final String eventType = "Microwave_Radio_Alarms";
43     private static final String eventSourceType = "Microwave_Radio";
44
45     private static final String charset = "UTF-8";
46
47         private static final HostnameVerifier allHostsValid = new HostnameVerifier() {
48                 public boolean verify(String hostname, SSLSession session) {
49                         return true;
50                 }
51         };
52
53     //Configurable parameters
54     private final DcaeSender dcaeSender;
55     private final int heartbeatIntervallSeconds;
56     private final String entityName;
57     private final DeviceManagerImpl deviceManager;
58
59     //Variables
60     private int heartbeatsequence = 0;
61
62     public DcaeMessages(DcaeSender ecompSender, String entityName, Integer heartbeatIntervallSeconds, DeviceManagerImpl deviceManager) {
63         this.dcaeSender = ecompSender;
64         this.entityName = entityName;
65         this.deviceManager = deviceManager;
66         this.heartbeatIntervallSeconds = heartbeatIntervallSeconds;
67     }
68
69     /**
70      * Create a heartbeat message.
71      * @return Result string with answer from server
72      */
73     public String postHeartBeat() {
74         String epochTimeMicrosecondsString = getEpochTimeMicroseconds();
75         String body = assembleHeartbeatFromTemplate(null,
76                         epochTimeMicrosecondsString,
77                         heartbeatsequence++,
78                         NetconfTimeStamp.getTimeStampAsNetconfString()).toString();
79         return dcaeSender.sendDcaePost( body);
80     }
81
82     /**
83      * ONF 1.2 Problem Notification
84      * @param mountPointName self-explaining
85      * @param notification Notification input
86      * @return String with answer
87      */
88
89     public String postNotification(String mountPointName, ProblemNotificationXml notification) {
90
91         String problemName = notification.getProblem();
92         String sequence = notification.getCounter();
93         String objId = notification.getObjectId();
94         String severity = convert( notification.getSeverity());
95         String timeStamp = convert( notification.getTimeStamp() );
96
97         String body = assembleEventNotificationFromTemplate(null,
98                 timeStamp, sequence,
99                 mountPointName, objId, problemName, severity, notification.getTimeStamp() ).toString();
100
101         return dcaeSender.sendDcaePost( body);
102     }
103
104     /**
105      * Setup a connection to URL with authorisation header
106      * @param url e.g. "https://plan.fritz.box:9092/ux/#" or "
107      * @param basicAuth authorisation header like "Basic SGVyYmVydDpIZXJiZXJ0"
108      * @param insertContentHeader
109      * @return Null in case of error or the URLConnection
110      * @throws IOException
111      * @throws MalformedURLException
112      */
113     static @Nullable HttpURLConnection openConnection( URL url, String basicAuth, boolean insertContentHeader, @Nullable SSLContext sc) throws MalformedURLException, IOException {
114
115         //Prepare the connection
116         HttpURLConnection newHttpConnection = null;
117         {
118                 URLConnection newConnection = url.openConnection();
119                 if (newConnection instanceof HttpURLConnection) {
120                 LOG.debug("Setup connection to {} ", url.toString());
121
122                         newHttpConnection = (HttpURLConnection)newConnection;
123
124                 newHttpConnection.setDoOutput(true); // Triggers POST.
125                 newHttpConnection.setRequestProperty("Accept-Charset", charset);
126                 if (basicAuth != null) {
127                         newHttpConnection.setRequestProperty("Authorization", basicAuth);
128                 }
129                 if (insertContentHeader) {
130                         newHttpConnection.setRequestProperty("Content-Type", "application/json;charset=" + charset);
131                 }
132
133                 if (newHttpConnection instanceof HttpsURLConnection) {
134                         LOG.debug("SSL connection setup with trust all.");
135                         HttpsURLConnection newHttpsConnection = (HttpsURLConnection)newHttpConnection;
136                         if (sc != null) {
137                                 newHttpsConnection.setSSLSocketFactory(sc.getSocketFactory());
138                         } else {
139                                 LOG.warn("No SSL Contect available");
140                         }
141                         newHttpsConnection.setHostnameVerifier(allHostsValid);
142                 }
143                 } else {
144                         LOG.warn("URL not a HTTP protocol: {}", url);
145                 }
146         }
147         return newHttpConnection;
148     }
149
150     /* -----------------
151      * Private function for message creation and with templates
152      */
153
154     /**
155      * Get actual microseconds
156      * @return String
157      */
158     private String getEpochTimeMicroseconds() {
159         long microseconds = System.nanoTime() / 1000;
160         return String.valueOf(microseconds);
161     }
162
163     /**
164      * Assemble heartbeat message
165      * @param sb StringBuffer to be used or null to allocate
166      * @param epochTimeMicrosecondsString Text with time stamp
167      * @param sequence integer sequence number
168      * @param eventTimeValueNetconfFormatString like this: 2018-05-14T05:32:17.292Z
169      * @return StringBuffer with result
170      */
171     private StringBuffer assembleHeartbeatFromTemplate(
172                      StringBuffer sb,
173                      String epochTimeMicrosecondsString,
174                      int sequence,
175                      String eventTimeValueNetconfFormatString) {
176
177         if (sb == null) {
178           sb = new StringBuffer();
179         }
180         sb.append("{\n" +
181                 "    \"event\": {\n" +
182                 "        \"commonEventHeader\": {\n" +
183                 "            \"domain\": \"heartbeat\",\n" +
184                 "            \"eventId\": \"testpattern-ab305d54-85b4-a31b-7db2-fb6b9e546015\",\n" +
185                 "            \"eventName\": \"heartbeat_Controller\",\n" +
186                 "            \"eventType\": \"Controller\",\n" +
187                 "            \"priority\": \"Low\",\n" +
188                 "            \"reportingEntityId\": \"\",\n" +
189                 "            \"reportingEntityName\": \""+entityName+"\",\n" +
190                 "            \"sequence\": "+String.valueOf(sequence)+",\n" +
191                 "            \"sourceId\": \"\",\n" +
192                 "            \"sourceName\": \""+entityName+"\",\n" +
193                 "            \"startEpochMicrosec\": "+epochTimeMicrosecondsString+",\n" +
194                 "            \"lastEpochMicrosec\": "+epochTimeMicrosecondsString+",\n" +
195                 "            \"version\": 3.0\n" +
196                 "        },\n" +
197                 "        \"heartbeatFields\": {\n" +
198                 "            \"additionalFields\": [\n" +
199                 "                 {\n" +
200                 "                   \"name\": \"eventTime\",\n" +
201                 "                   \"value\": \""+eventTimeValueNetconfFormatString+"\"\n" +
202                 "                 }\n" +
203                 "            ],\n" +
204                 "            \"heartbeatFieldsVersion\": 1.0,\n" +
205                 "            \"heartbeatInterval\": "+heartbeatIntervallSeconds+"\n" +
206                 "        }\n" +
207                 "    }\n" +
208                 "}\n"
209         );
210
211         return sb;
212     }
213
214     /**
215      * Assemble notification message
216      * @param sb StringBuffer to be used or null to allocate
217      * @param epochTimeMicrosecondsString Text with time stamp
218      * @param sequence integer sequence number
219      * @param mountpointName
220      * @param objId
221      * @param problemName
222      * @param severity
223      * @return StringBuffer with result
224      */
225
226     private StringBuffer assembleEventNotificationFromTemplate(StringBuffer sb,
227             String epochTimeMicrosecondsString, String sequence,
228             String mountpointName, String objId, String problemName, String severity, String eventTimeValueNetconfFormatString
229             ) {
230
231         if (sb == null) {
232             sb = new StringBuffer();
233         }
234
235         ONFCoreNetworkElementRepresentation optionalNe = deviceManager != null ? deviceManager.getNeByMountpoint(mountpointName) : null;
236         InventoryInformation neInventory = optionalNe != null ? optionalNe.getInventoryInformation() : InventoryInformation.DEFAULT;
237
238         sb.append("{\n" +
239                 "    \"event\": {\n" +
240                 "        \"commonEventHeader\": {\n" +
241                 "            \"domain\": \"fault\",\n" +
242                 "            \"eventId\": \""+mountpointName+"_"+objId+"_"+problemName+"\",\n" +
243                 "            \"eventName\": \""+eventNamePrefix+"_"+problemName+"\",\n" +
244                 "            \"eventType\": \""+eventType+"\",\n" +
245                 "            \"sequence\": "+sequence+",\n" +
246                 "            \"priority\": \"High\",\n" +
247                 "            \"reportingEntityId\": \"\",\n" +
248                 "            \"reportingEntityName\": \""+entityName+"\",\n" +
249                 "            \"sourceId\": \"\",\n" +
250                 "            \"sourceName\": \""+mountpointName+"\",\n" +
251                 "            \"startEpochMicrosec\": "+epochTimeMicrosecondsString+",\n" +
252                 "            \"lastEpochMicrosec\": "+epochTimeMicrosecondsString+",\n" +
253                 "            \"version\": 3.0\n" +
254                 "        },\n" +
255                 "        \"faultFields\": {\n" +
256                 "            \"alarmAdditionalInformation\": [\n" +
257                 "                 {\n" +
258                 "                   \"name\": \"eventTime\",\n" +
259                 "                   \"value\": \""+eventTimeValueNetconfFormatString+"\"\n" +
260                 "                 },\n" +
261                 "                 {\n" +
262                 "                   \"name\": \"equipType\",\n" +
263                 "                   \"value\": \""+neInventory.getType()+"\"\n" +
264                 "                 },\n" +
265                 "                 {\n" +
266                 "                   \"name\": \"vendor\",\n" +
267                 "                   \"value\": \""+neInventory.getVendor()+"\"\n" +
268                 "                 },\n" +
269                 "                 {\n" +
270                 "                   \"name\": \"model\",\n" +
271                 "                   \"value\": \""+neInventory.getModel()+"\"\n" +
272                 "                 }\n" +
273                 "            ],\n" +
274                 "            \"faultFieldsVersion\":2.0,\n" +
275                 "            \"eventSourceType\": \""+eventSourceType+"\",\n" +
276                 "            \"alarmCondition\": \""+problemName+"\",\n" +
277                 "            \"alarmInterfaceA\": \""+objId+"\",\n" +
278                 "            \"specificProblem\": \""+problemName+"\",\n" +
279                 "            \"eventSeverity\": \""+severity+"\",\n" +
280                 "            \"vfStatus\": \"Active\"\n" +
281                 "        }\n" +
282                 "    }\n" +
283                 "}\n"
284                 );
285
286         return sb;
287     }
288
289     /* -----------------
290      * Convert internal type formats into the Ecomp format
291      */
292
293     private String convert(InternalSeverity severity ) {
294          switch( severity ) {
295             case NonAlarmed:
296                 break;
297             case Warning:
298                 return DCAE_WARNING;
299             case Minor:
300                 return DCAE_MINOR;
301             case Major:
302                 return DCAE_MAJOR;
303             case Critical:
304                 return DCAE_CRITICAL;
305         }
306         return DCAE_NORMAL;
307     }
308
309
310     /**
311      * Time has to be converted into milliseconds
312      * @param timeAsString time as string
313      * @return
314      */
315     private String convert(String timeAsString) {
316
317         long microseconds = -1;
318         try {
319             microseconds = NetconfTimeStamp.getTimeStampFromNetconfAsMilliseconds(timeAsString) * 1000;
320         } catch (IllegalArgumentException e) {
321             e.printStackTrace();
322         } catch (ParseException e) {
323             e.printStackTrace();
324         }
325         return String.valueOf(microseconds);
326     }
327
328
329 }