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