2 ecompProvider.sendProblemNotification(ownKeyName, notificationXml);
3 * ECOMP Messages are generated an send to destination
7 package org.opendaylight.mwtn.dcaeConnector.impl;
9 import java.io.IOException;
10 import java.net.HttpURLConnection;
11 import java.net.MalformedURLException;
13 import java.net.URLConnection;
14 import java.text.ParseException;
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;
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;
31 public class DcaeMessages {
33 private static final Logger LOG = LoggerFactory.getLogger(DcaeSenderImpl.class);
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";
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";
45 private static final String charset = "UTF-8";
47 private static final HostnameVerifier allHostsValid = new HostnameVerifier() {
48 public boolean verify(String hostname, SSLSession session) {
53 //Configurable parameters
54 private final DcaeSender dcaeSender;
55 private final int heartbeatIntervallSeconds;
56 private final String entityName;
57 private final DeviceManagerImpl deviceManager;
60 private int heartbeatsequence = 0;
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;
70 * Create a heartbeat message.
71 * @return Result string with answer from server
73 public String postHeartBeat() {
74 String epochTimeMicrosecondsString = getEpochTimeMicroseconds();
75 String body = assembleHeartbeatFromTemplate(null,
76 epochTimeMicrosecondsString,
78 NetconfTimeStamp.getTimeStampAsNetconfString()).toString();
79 return dcaeSender.sendDcaePost( body);
83 * ONF 1.2 Problem Notification
84 * @param mountPointName self-explaining
85 * @param notification Notification input
86 * @return String with answer
89 public String postNotification(String mountPointName, ProblemNotificationXml notification) {
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() );
97 String body = assembleEventNotificationFromTemplate(null,
99 mountPointName, objId, problemName, severity, notification.getTimeStamp() ).toString();
101 return dcaeSender.sendDcaePost( body);
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
113 static @Nullable HttpURLConnection openConnection( URL url, String basicAuth, boolean insertContentHeader, @Nullable SSLContext sc) throws MalformedURLException, IOException {
115 //Prepare the connection
116 HttpURLConnection newHttpConnection = null;
118 URLConnection newConnection = url.openConnection();
119 if (newConnection instanceof HttpURLConnection) {
120 LOG.debug("Setup connection to {} ", url.toString());
122 newHttpConnection = (HttpURLConnection)newConnection;
124 newHttpConnection.setDoOutput(true); // Triggers POST.
125 newHttpConnection.setRequestProperty("Accept-Charset", charset);
126 if (basicAuth != null) {
127 newHttpConnection.setRequestProperty("Authorization", basicAuth);
129 if (insertContentHeader) {
130 newHttpConnection.setRequestProperty("Content-Type", "application/json;charset=" + charset);
133 if (newHttpConnection instanceof HttpsURLConnection) {
134 LOG.debug("SSL connection setup with trust all.");
135 HttpsURLConnection newHttpsConnection = (HttpsURLConnection)newHttpConnection;
137 newHttpsConnection.setSSLSocketFactory(sc.getSocketFactory());
139 LOG.warn("No SSL Contect available");
141 newHttpsConnection.setHostnameVerifier(allHostsValid);
144 LOG.warn("URL not a HTTP protocol: {}", url);
147 return newHttpConnection;
151 * Private function for message creation and with templates
155 * Get actual microseconds
158 private String getEpochTimeMicroseconds() {
159 long microseconds = System.nanoTime() / 1000;
160 return String.valueOf(microseconds);
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
171 private StringBuffer assembleHeartbeatFromTemplate(
173 String epochTimeMicrosecondsString,
175 String eventTimeValueNetconfFormatString) {
178 sb = new StringBuffer();
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" +
197 " \"heartbeatFields\": {\n" +
198 " \"additionalFields\": [\n" +
200 " \"name\": \"eventTime\",\n" +
201 " \"value\": \""+eventTimeValueNetconfFormatString+"\"\n" +
204 " \"heartbeatFieldsVersion\": 1.0,\n" +
205 " \"heartbeatInterval\": "+heartbeatIntervallSeconds+"\n" +
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
223 * @return StringBuffer with result
226 private StringBuffer assembleEventNotificationFromTemplate(StringBuffer sb,
227 String epochTimeMicrosecondsString, String sequence,
228 String mountpointName, String objId, String problemName, String severity, String eventTimeValueNetconfFormatString
232 sb = new StringBuffer();
235 ONFCoreNetworkElementRepresentation optionalNe = deviceManager != null ? deviceManager.getNeByMountpoint(mountpointName) : null;
236 InventoryInformation neInventory = optionalNe != null ? optionalNe.getInventoryInformation() : InventoryInformation.DEFAULT;
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" +
255 " \"faultFields\": {\n" +
256 " \"alarmAdditionalInformation\": [\n" +
258 " \"name\": \"eventTime\",\n" +
259 " \"value\": \""+eventTimeValueNetconfFormatString+"\"\n" +
262 " \"name\": \"equipType\",\n" +
263 " \"value\": \""+neInventory.getType()+"\"\n" +
266 " \"name\": \"vendor\",\n" +
267 " \"value\": \""+neInventory.getVendor()+"\"\n" +
270 " \"name\": \"model\",\n" +
271 " \"value\": \""+neInventory.getModel()+"\"\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" +
290 * Convert internal type formats into the Ecomp format
293 private String convert(InternalSeverity severity ) {
304 return DCAE_CRITICAL;
311 * Time has to be converted into milliseconds
312 * @param timeAsString time as string
315 private String convert(String timeAsString) {
317 long microseconds = -1;
319 microseconds = NetconfTimeStamp.getTimeStampFromNetconfAsMilliseconds(timeAsString) * 1000;
320 } catch (IllegalArgumentException e) {
322 } catch (ParseException e) {
325 return String.valueOf(microseconds);