[ONOS-7136] Removing Alarms when a device is from ONOS
Change-Id: I0556ca45741f38aacc6aca1d0173941a7e50acae
diff --git a/apps/faultmanagement/fmmgr/src/main/java/org/onosproject/faultmanagement/impl/AlarmManager.java b/apps/faultmanagement/fmmgr/src/main/java/org/onosproject/faultmanagement/impl/AlarmManager.java
index 2996101..f12bacb 100644
--- a/apps/faultmanagement/fmmgr/src/main/java/org/onosproject/faultmanagement/impl/AlarmManager.java
+++ b/apps/faultmanagement/fmmgr/src/main/java/org/onosproject/faultmanagement/impl/AlarmManager.java
@@ -36,8 +36,12 @@
import org.onosproject.incubator.net.faultmanagement.alarm.AlarmProviderService;
import org.onosproject.incubator.net.faultmanagement.alarm.AlarmService;
import org.onosproject.incubator.net.faultmanagement.alarm.DefaultAlarm;
+import org.onosproject.mastership.MastershipService;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DeviceId;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceService;
import org.onosproject.net.provider.AbstractListenerProviderRegistry;
import org.onosproject.net.provider.AbstractProviderService;
import org.slf4j.Logger;
@@ -63,12 +67,19 @@
private final Logger log = getLogger(getClass());
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected DeviceService deviceService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected MastershipService mastershipService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected AlarmStore store;
protected AlarmStoreDelegate delegate = this::post;
+ private InternalDeviceListener deviceListener = new InternalDeviceListener();
+
//TODO improve implementation of AlarmId
private final AtomicLong alarmIdGenerator = new AtomicLong(0);
@@ -78,11 +89,13 @@
public void activate() {
store.setDelegate(delegate);
eventDispatcher.addSink(AlarmEvent.class, listenerRegistry);
+ deviceService.addListener(deviceListener);
log.info("Started");
}
@Deactivate
public void deactivate() {
+ deviceService.removeListener(deviceListener);
store.unsetDelegate(delegate);
eventDispatcher.removeSink(AlarmEvent.class);
log.info("Stopped");
@@ -215,4 +228,27 @@
alarms.forEach(alarm -> store.createOrUpdateAlarm(alarm));
}
}
+
+ /**
+ * Internal listener for device events.
+ */
+ private class InternalDeviceListener implements DeviceListener {
+
+ @Override
+ public boolean isRelevant(DeviceEvent event) {
+ return event.type().equals(DeviceEvent.Type.DEVICE_REMOVED);
+ }
+
+ @Override
+ public void event(DeviceEvent event) {
+ if (mastershipService.isLocalMaster(event.subject().id())) {
+ log.info("Device {} removed from ONOS, removing all related alarms", event.subject().id());
+ //TODO this can be improved when core supports multiple keys map and gets implemented in AlarmStore
+ store.getAlarms(event.subject().id()).forEach(alarm -> store.removeAlarm(alarm.id()));
+ } else {
+ log.info("This Node is not Master for device {}", event.subject().id());
+ }
+ }
+
+ }
}
diff --git a/apps/faultmanagement/fmmgr/src/test/java/org/onosproject/faultmanagement/impl/AlarmManagerTest.java b/apps/faultmanagement/fmmgr/src/test/java/org/onosproject/faultmanagement/impl/AlarmManagerTest.java
index 6a3c376..d226c6b 100644
--- a/apps/faultmanagement/fmmgr/src/test/java/org/onosproject/faultmanagement/impl/AlarmManagerTest.java
+++ b/apps/faultmanagement/fmmgr/src/test/java/org/onosproject/faultmanagement/impl/AlarmManagerTest.java
@@ -35,9 +35,17 @@
import org.onosproject.incubator.net.faultmanagement.alarm.AlarmProviderRegistry;
import org.onosproject.incubator.net.faultmanagement.alarm.AlarmProviderService;
import org.onosproject.incubator.net.faultmanagement.alarm.DefaultAlarm;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.mastership.MastershipServiceAdapter;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.MastershipRole;
import org.onosproject.net.NetTestTools;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceServiceAdapter;
import org.onosproject.net.provider.AbstractProvider;
import org.onosproject.store.service.TestStorageService;
@@ -59,6 +67,7 @@
public class AlarmManagerTest {
private static final DeviceId DEVICE_ID = DeviceId.deviceId("foo:bar");
+
private static final String UNIQUE_ID_1 = "unique_id_1";
private static final String UNIQUE_ID_2 = "unique_id_2";
private static final AlarmId A_ID = AlarmId.alarmId(DEVICE_ID, UNIQUE_ID_1);
@@ -82,6 +91,10 @@
private TestProvider provider;
protected AlarmProviderRegistry registry;
protected TestListener listener = new TestListener();
+ private final MastershipService mastershipService = new MockMastershipService();
+ protected final MockDeviceService deviceService = new MockDeviceService();
+
+ private final Device device = new MockDevice(DEVICE_ID);
@Rule
public final ExpectedException exception = ExpectedException.none();
@@ -95,6 +108,8 @@
registry = manager;
manager.addListener(listener);
NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
+ manager.deviceService = deviceService;
+ manager.mastershipService = mastershipService;
manager.store = alarmStore;
manager.activate();
provider = new TestProvider();
@@ -191,6 +206,21 @@
}
+ @Test
+ public void testRemoveWhenDeviceRemoved() {
+ providerService.updateAlarmList(DEVICE_ID, ImmutableSet.of(ALARM_B, ALARM_A));
+ verifyGettingSetsOfAlarms(manager, 2, 2);
+ validateEvents(AlarmEvent.Type.CREATED, AlarmEvent.Type.CREATED);
+ Map<Alarm.SeverityLevel, Long> critical2 = new CountsMapBuilder().with(CRITICAL, 2L).create();
+ assertEquals("A critical should be present", critical2, manager.getAlarmCounts());
+ assertEquals("A critical should be present", critical2, manager.getAlarmCounts(DEVICE_ID));
+ deviceService.deviceListener.event(new DeviceEvent(DeviceEvent.Type.DEVICE_REMOVED, device));
+ Map<Alarm.SeverityLevel, Long> zeroAlarms = new CountsMapBuilder().create();
+ assertEquals("The counts should be empty for removed device", zeroAlarms,
+ manager.getAlarmCounts(DEVICE_ID));
+
+ }
+
private void verifyGettingSetsOfAlarms(AlarmManager am, int expectedTotal, int expectedActive) {
assertEquals("Incorrect total alarms", expectedTotal, am.getAlarms().size());
assertEquals("Incorrect active alarms count", expectedActive, am.getActiveAlarms().size());
@@ -229,6 +259,21 @@
}
+ private class MockDeviceService extends DeviceServiceAdapter {
+ DeviceListener deviceListener = null;
+
+ @Override
+ public void addListener(DeviceListener listener) {
+ this.deviceListener = listener;
+ }
+
+ @Override
+ public void removeListener(DeviceListener listener) {
+ this.deviceListener = null;
+ }
+ }
+
+
private class TestProvider extends AbstractProvider implements AlarmProvider {
private DeviceId deviceReceived;
private MastershipRole roleReceived;
@@ -242,6 +287,14 @@
}
}
+ private class MockMastershipService extends MastershipServiceAdapter {
+ int test = 0;
+ @Override
+ public boolean isLocalMaster(DeviceId deviceId) {
+ return true;
+ }
+ }
+
/**
* Test listener class to receive alarm events.
*/
@@ -255,4 +308,13 @@
}
}
+
+ private class MockDevice extends DefaultDevice {
+
+ MockDevice(DeviceId id) {
+ super(null, id, null, null, null, null, null,
+ null, DefaultAnnotations.EMPTY);
+ }
+
+ }
}