helenyrwu
Committed by Gerrit Code Review

[ONOS-3775] Building alarms from NETCONF notifications

Change-Id: I80d960193ce957fa640fde0d1e7b4422d60c7fe4
1 +/*
2 + * Copyright 2016-present Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.incubator.net.faultmanagement.alarm;
18 +
19 +import org.onosproject.net.DeviceId;
20 +
21 +import java.io.InputStream;
22 +import java.util.Collection;
23 +
24 +/**
25 + * Abstraction of ability to translate device messages into alarms.
26 + */
27 +public interface AlarmTranslator {
28 +
29 + /**
30 + * Translates message from device into an alarm with appropriate
31 + * information.
32 + *
33 + * @param message message from device to translate to alarm
34 + * @return Alarm with information determined by given message
35 + */
36 + Collection<Alarm> translateToAlarm(DeviceId deviceId, InputStream message);
37 +}
...@@ -25,9 +25,7 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; ...@@ -25,9 +25,7 @@ import org.apache.felix.scr.annotations.ReferenceCardinality;
25 import org.onosproject.incubator.net.faultmanagement.alarm.Alarm; 25 import org.onosproject.incubator.net.faultmanagement.alarm.Alarm;
26 import org.onosproject.incubator.net.faultmanagement.alarm.AlarmProvider; 26 import org.onosproject.incubator.net.faultmanagement.alarm.AlarmProvider;
27 import org.onosproject.incubator.net.faultmanagement.alarm.AlarmProviderService; 27 import org.onosproject.incubator.net.faultmanagement.alarm.AlarmProviderService;
28 -import org.onosproject.incubator.net.faultmanagement.alarm.AlarmService;
29 import org.onosproject.incubator.net.faultmanagement.alarm.AlarmProviderRegistry; 28 import org.onosproject.incubator.net.faultmanagement.alarm.AlarmProviderRegistry;
30 -import org.onosproject.incubator.net.faultmanagement.alarm.DefaultAlarm;
31 import org.onosproject.net.DeviceId; 29 import org.onosproject.net.DeviceId;
32 import org.onosproject.net.provider.AbstractProvider; 30 import org.onosproject.net.provider.AbstractProvider;
33 import org.onosproject.net.provider.ProviderId; 31 import org.onosproject.net.provider.ProviderId;
...@@ -41,8 +39,10 @@ import org.onosproject.netconf.NetconfSession; ...@@ -41,8 +39,10 @@ import org.onosproject.netconf.NetconfSession;
41 import org.onosproject.netconf.ctl.NetconfDeviceOutputEventListenerImpl; 39 import org.onosproject.netconf.ctl.NetconfDeviceOutputEventListenerImpl;
42 import org.slf4j.Logger; 40 import org.slf4j.Logger;
43 41
42 +import java.io.ByteArrayInputStream;
43 +import java.io.InputStream;
44 +import java.nio.charset.StandardCharsets;
44 import java.util.Collection; 45 import java.util.Collection;
45 -import java.util.Collections;
46 import java.util.Map; 46 import java.util.Map;
47 47
48 import static org.slf4j.LoggerFactory.getLogger; 48 import static org.slf4j.LoggerFactory.getLogger;
...@@ -62,9 +62,6 @@ public class NetconfAlarmProvider extends AbstractProvider implements AlarmProvi ...@@ -62,9 +62,6 @@ public class NetconfAlarmProvider extends AbstractProvider implements AlarmProvi
62 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 62 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
63 protected NetconfController controller; 63 protected NetconfController controller;
64 64
65 - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
66 - protected AlarmService alarmService;
67 -
68 protected AlarmProviderService providerService; 65 protected AlarmProviderService providerService;
69 66
70 private Map<DeviceId, InternalNotificationListener> idNotificationListenerMap = Maps.newHashMap(); 67 private Map<DeviceId, InternalNotificationListener> idNotificationListenerMap = Maps.newHashMap();
...@@ -94,8 +91,8 @@ public class NetconfAlarmProvider extends AbstractProvider implements AlarmProvi ...@@ -94,8 +91,8 @@ public class NetconfAlarmProvider extends AbstractProvider implements AlarmProvi
94 providerRegistry.unregister(this); 91 providerRegistry.unregister(this);
95 idNotificationListenerMap.forEach((id, listener) -> { 92 idNotificationListenerMap.forEach((id, listener) -> {
96 controller.getNetconfDevice(id) 93 controller.getNetconfDevice(id)
97 - .getSession() 94 + .getSession()
98 - .removeDeviceOutputListener(listener); 95 + .removeDeviceOutputListener(listener);
99 }); 96 });
100 controller.removeDeviceListener(deviceListener); 97 controller.removeDeviceListener(deviceListener);
101 providerService = null; 98 providerService = null;
...@@ -123,10 +120,11 @@ public class NetconfAlarmProvider extends AbstractProvider implements AlarmProvi ...@@ -123,10 +120,11 @@ public class NetconfAlarmProvider extends AbstractProvider implements AlarmProvi
123 public void event(NetconfDeviceOutputEvent event) { 120 public void event(NetconfDeviceOutputEvent event) {
124 if (event.type() == NetconfDeviceOutputEvent.Type.DEVICE_NOTIFICATION) { 121 if (event.type() == NetconfDeviceOutputEvent.Type.DEVICE_NOTIFICATION) {
125 DeviceId deviceId = event.getDeviceInfo().getDeviceId(); 122 DeviceId deviceId = event.getDeviceInfo().getDeviceId();
126 - Alarm newAlarm = new DefaultAlarm.Builder(deviceId, event.getMessagePayload(), 123 + NetconfAlarmTranslator translator = new NetconfAlarmTranslator();
127 - Alarm.SeverityLevel.WARNING, 0).build(); 124 + String message = event.getMessagePayload();
128 - Collection<Alarm> alarms = Collections.singleton(newAlarm); 125 + InputStream in = new ByteArrayInputStream(message.getBytes(StandardCharsets.UTF_8));
129 - triggerProbe(deviceId, alarms); 126 + Collection<Alarm> newAlarms = translator.translateToAlarm(deviceId, in);
127 + triggerProbe(deviceId, newAlarms);
130 } 128 }
131 } 129 }
132 } 130 }
......
1 +/*
2 + * Copyright 2016-present Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.provider.netconf.alarm;
18 +
19 +import com.google.common.collect.ImmutableSet;
20 +import org.onosproject.incubator.net.faultmanagement.alarm.Alarm;
21 +import org.onosproject.incubator.net.faultmanagement.alarm.AlarmTranslator;
22 +import org.onosproject.incubator.net.faultmanagement.alarm.DefaultAlarm;
23 +import org.onosproject.net.DeviceId;
24 +import org.slf4j.Logger;
25 +import org.w3c.dom.Document;
26 +import org.w3c.dom.Node;
27 +import org.xml.sax.InputSource;
28 +
29 +import javax.xml.parsers.DocumentBuilder;
30 +import javax.xml.parsers.DocumentBuilderFactory;
31 +import javax.xml.parsers.ParserConfigurationException;
32 +import javax.xml.transform.OutputKeys;
33 +import javax.xml.transform.Transformer;
34 +import javax.xml.transform.TransformerException;
35 +import javax.xml.transform.TransformerFactory;
36 +import javax.xml.transform.dom.DOMSource;
37 +import javax.xml.transform.stream.StreamResult;
38 +import java.io.IOException;
39 +import java.io.InputStream;
40 +import java.io.StringWriter;
41 +import java.util.ArrayList;
42 +import java.util.Collection;
43 +
44 +import org.joda.time.format.ISODateTimeFormat;
45 +import org.xml.sax.SAXException;
46 +
47 +import static org.slf4j.LoggerFactory.getLogger;
48 +
49 +/**
50 + * Translates NETCONF notification messages to actions on alarms.
51 + */
52 +public class NetconfAlarmTranslator implements AlarmTranslator {
53 +
54 + private final Logger log = getLogger(getClass());
55 + private static final String EVENTTIME_TAGNAME = "eventTime";
56 +
57 + @Override
58 + public Collection<Alarm> translateToAlarm(DeviceId deviceId, InputStream message) {
59 + try {
60 + Collection<Alarm> alarms = new ArrayList<>();
61 + Document doc = createDocFromMessage(message);
62 +
63 + // parse date element value into long
64 + Node eventTime = doc.getElementsByTagName(EVENTTIME_TAGNAME).item(0);
65 + String date = eventTime.getTextContent();
66 + long timeStamp = parseDate(date);
67 +
68 + // event-specific tag names as alarm descriptions
69 + Node descriptionNode = eventTime.getNextSibling();
70 + while (descriptionNode != null) {
71 + if (descriptionNode.getNodeType() == Node.ELEMENT_NODE) {
72 + String description = nodeToString(descriptionNode);
73 + alarms.add(new DefaultAlarm.Builder(deviceId, description,
74 + Alarm.SeverityLevel.WARNING,
75 + timeStamp).build());
76 + descriptionNode = null;
77 + } else {
78 + descriptionNode = descriptionNode.getNextSibling();
79 + }
80 + }
81 + return alarms;
82 + } catch (SAXException | IOException | ParserConfigurationException |
83 + UnsupportedOperationException | IllegalArgumentException |
84 + TransformerException e) {
85 + log.error("Exception thrown translating {} from {}.", message, deviceId);
86 + return ImmutableSet.of();
87 + }
88 + }
89 +
90 + private Document createDocFromMessage(InputStream message)
91 + throws SAXException, IOException, ParserConfigurationException {
92 + DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance();
93 + DocumentBuilder builder = dbfactory.newDocumentBuilder();
94 + return builder.parse(new InputSource(message));
95 + }
96 +
97 + private long parseDate(String timeStr)
98 + throws UnsupportedOperationException, IllegalArgumentException {
99 + return ISODateTimeFormat.dateTimeNoMillis().parseMillis(timeStr);
100 + }
101 +
102 + private static String nodeToString(Node rootNode) throws TransformerException {
103 + TransformerFactory tf = TransformerFactory.newInstance();
104 + Transformer transformer = tf.newTransformer();
105 + transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
106 + StringWriter writer = new StringWriter();
107 + DOMSource source = new DOMSource(rootNode);
108 + transformer.transform(source, new StreamResult(writer));
109 + return writer.getBuffer().toString();
110 + }
111 +}