blob: 80d3ed5b84f149542c05f9b06c0f08c6c68b3b92 [file] [log] [blame]
kmcpeake4fe18c82015-11-17 20:07:39 +00001/*
Brian O'Connor0a4e6742016-09-15 23:03:10 -07002 * Copyright 2016-present Open Networking Laboratory
kmcpeake4fe18c82015-11-17 20:07:39 +00003 *
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 */
16package org.onosproject.faultmanagement.impl;
17
Andrea Campanellae72ac552016-04-11 10:04:52 -070018import com.google.common.collect.ImmutableSet;
kmcpeakeb172d5f2015-12-10 11:30:43 +000019import org.apache.commons.collections.CollectionUtils;
kmcpeake4fe18c82015-11-17 20:07:39 +000020import org.apache.felix.scr.annotations.Activate;
21import org.apache.felix.scr.annotations.Component;
22import org.apache.felix.scr.annotations.Deactivate;
23import org.apache.felix.scr.annotations.Modified;
Andrea Campanella8e94b0c2016-04-12 13:58:07 -070024import org.apache.felix.scr.annotations.Reference;
25import org.apache.felix.scr.annotations.ReferenceCardinality;
Andrea Campanellae72ac552016-04-11 10:04:52 -070026import org.apache.felix.scr.annotations.Service;
27import org.onlab.util.ItemNotFoundException;
Andrea Campanella8e94b0c2016-04-12 13:58:07 -070028import org.onosproject.faultmanagement.api.AlarmStore;
29import org.onosproject.faultmanagement.api.AlarmStoreDelegate;
kmcpeake4fe18c82015-11-17 20:07:39 +000030import org.onosproject.incubator.net.faultmanagement.alarm.Alarm;
31import org.onosproject.incubator.net.faultmanagement.alarm.AlarmEntityId;
Andrea Campanella8e94b0c2016-04-12 13:58:07 -070032import org.onosproject.incubator.net.faultmanagement.alarm.AlarmEvent;
kmcpeake4fe18c82015-11-17 20:07:39 +000033import org.onosproject.incubator.net.faultmanagement.alarm.AlarmId;
Andrea Campanella8e94b0c2016-04-12 13:58:07 -070034import org.onosproject.incubator.net.faultmanagement.alarm.AlarmListener;
Andrea Campanellae72ac552016-04-11 10:04:52 -070035import org.onosproject.incubator.net.faultmanagement.alarm.AlarmProvider;
36import org.onosproject.incubator.net.faultmanagement.alarm.AlarmProviderRegistry;
37import org.onosproject.incubator.net.faultmanagement.alarm.AlarmProviderService;
kmcpeake4fe18c82015-11-17 20:07:39 +000038import org.onosproject.incubator.net.faultmanagement.alarm.AlarmService;
Andrea Campanellae72ac552016-04-11 10:04:52 -070039import org.onosproject.incubator.net.faultmanagement.alarm.DefaultAlarm;
kmcpeake4fe18c82015-11-17 20:07:39 +000040import org.onosproject.net.ConnectPoint;
41import org.onosproject.net.DeviceId;
Andrea Campanella8e94b0c2016-04-12 13:58:07 -070042import org.onosproject.net.provider.AbstractListenerProviderRegistry;
Andrea Campanellae72ac552016-04-11 10:04:52 -070043import org.onosproject.net.provider.AbstractProviderService;
Andrea Campanellae72ac552016-04-11 10:04:52 -070044import org.slf4j.Logger;
kmcpeakeb172d5f2015-12-10 11:30:43 +000045
Andrea Campanellae72ac552016-04-11 10:04:52 -070046import java.util.Collection;
47import java.util.Map;
48import java.util.Set;
kmcpeakeb172d5f2015-12-10 11:30:43 +000049import java.util.concurrent.atomic.AtomicLong;
Andrea Campanellae72ac552016-04-11 10:04:52 -070050import java.util.stream.Collectors;
51
52import static com.google.common.base.Preconditions.checkNotNull;
53import static org.onlab.util.Tools.nullIsNotFound;
54import static org.slf4j.LoggerFactory.getLogger;
kmcpeake4fe18c82015-11-17 20:07:39 +000055
56/**
57 * Implementation of the Alarm service.
58 */
59@Component(immediate = true)
60@Service
Andrea Campanella8e94b0c2016-04-12 13:58:07 -070061public class AlarmManager
62 extends AbstractListenerProviderRegistry<AlarmEvent, AlarmListener, AlarmProvider, AlarmProviderService>
Andrea Campanellae72ac552016-04-11 10:04:52 -070063 implements AlarmService, AlarmProviderRegistry {
kmcpeakeb172d5f2015-12-10 11:30:43 +000064
kmcpeake4fe18c82015-11-17 20:07:39 +000065 private final Logger log = getLogger(getClass());
kmcpeake4fe18c82015-11-17 20:07:39 +000066
kmcpeake4fe18c82015-11-17 20:07:39 +000067
Andrea Campanella8e94b0c2016-04-12 13:58:07 -070068 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
69 protected AlarmStore store;
70
71 protected AlarmStoreDelegate delegate = this::post;
72
73 //TODO improve implementation of AlarmId
74 private final AtomicLong alarmIdGenerator = new AtomicLong(0);
Andrea Campanellae72ac552016-04-11 10:04:52 -070075
76 private static final String NOT_SUPPORTED_YET = "Not supported yet.";
77
78 @Activate
Andrea Campanella8e94b0c2016-04-12 13:58:07 -070079 public void activate() {
80 store.setDelegate(delegate);
81 eventDispatcher.addSink(AlarmEvent.class, listenerRegistry);
Andrea Campanellae72ac552016-04-11 10:04:52 -070082 log.info("Started");
83 }
84
85 @Deactivate
Andrea Campanella8e94b0c2016-04-12 13:58:07 -070086 public void deactivate() {
87 store.unsetDelegate(delegate);
88 eventDispatcher.removeSink(AlarmEvent.class);
Andrea Campanellae72ac552016-04-11 10:04:52 -070089 log.info("Stopped");
90 }
91
92 @Modified
Andrea Campanella8e94b0c2016-04-12 13:58:07 -070093 public boolean modified() {
Andrea Campanellae72ac552016-04-11 10:04:52 -070094 log.info("Modified");
95 return true;
96 }
97
kmcpeakeb172d5f2015-12-10 11:30:43 +000098 @Override
99 public Alarm updateBookkeepingFields(AlarmId id, boolean isAcknowledged, String assignedUser) {
100
Andrea Campanella8e94b0c2016-04-12 13:58:07 -0700101 Alarm found = store.getAlarm(id);
kmcpeake4fe18c82015-11-17 20:07:39 +0000102 if (found == null) {
kmcpeakeb172d5f2015-12-10 11:30:43 +0000103 throw new ItemNotFoundException("Alarm with id " + id + " found");
kmcpeake4fe18c82015-11-17 20:07:39 +0000104 }
kmcpeakeb172d5f2015-12-10 11:30:43 +0000105
Andrea Campanella8e94b0c2016-04-12 13:58:07 -0700106 Alarm updated = new DefaultAlarm.Builder(found)
107 .withId(found.id())
108 .withAcknowledged(isAcknowledged)
109 .withAssignedUser(assignedUser).build();
110 store.setAlarm(updated);
kmcpeakeb172d5f2015-12-10 11:30:43 +0000111 return updated;
112 }
113
114 public Alarm clear(AlarmId id) {
Andrea Campanella8e94b0c2016-04-12 13:58:07 -0700115 Alarm found = store.getAlarm(id);
kmcpeakeb172d5f2015-12-10 11:30:43 +0000116 if (found == null) {
Andrea Campanella8e94b0c2016-04-12 13:58:07 -0700117 log.warn("Alarm {} is not present", id);
kmcpeakeb172d5f2015-12-10 11:30:43 +0000118 return null;
119 }
Andrea Campanella8e94b0c2016-04-12 13:58:07 -0700120 Alarm updated = new DefaultAlarm.Builder(found).withId(id).clear().build();
121 store.setAlarm(updated);
kmcpeake4fe18c82015-11-17 20:07:39 +0000122 return updated;
123 }
124
125 @Override
kmcpeakeb172d5f2015-12-10 11:30:43 +0000126 public Map<Alarm.SeverityLevel, Long> getAlarmCounts(DeviceId deviceId) {
kmcpeakeb172d5f2015-12-10 11:30:43 +0000127 return getAlarms(deviceId).stream().collect(
128 Collectors.groupingBy(Alarm::severity, Collectors.counting()));
kmcpeake4fe18c82015-11-17 20:07:39 +0000129 }
kmcpeakeb172d5f2015-12-10 11:30:43 +0000130
131 @Override
132 public Map<Alarm.SeverityLevel, Long> getAlarmCounts() {
kmcpeakeb172d5f2015-12-10 11:30:43 +0000133 return getAlarms().stream().collect(
134 Collectors.groupingBy(Alarm::severity, Collectors.counting()));
135 }
136
kmcpeake4fe18c82015-11-17 20:07:39 +0000137 @Override
kmcpeakea5404812015-12-08 11:52:50 +0000138 public Alarm getAlarm(AlarmId alarmId) {
Andrea Campanella8e94b0c2016-04-12 13:58:07 -0700139 return nullIsNotFound(store.getAlarm(checkNotNull(alarmId, "Alarm Id cannot be null")),
Andrea Campanellae72ac552016-04-11 10:04:52 -0700140 "Alarm is not found");
kmcpeake4fe18c82015-11-17 20:07:39 +0000141 }
142
143 @Override
144 public Set<Alarm> getAlarms() {
Andrea Campanella8e94b0c2016-04-12 13:58:07 -0700145 return ImmutableSet.copyOf(store.getAlarms());
kmcpeake4fe18c82015-11-17 20:07:39 +0000146 }
147
148 @Override
149 public Set<Alarm> getActiveAlarms() {
Andrea Campanella8e94b0c2016-04-12 13:58:07 -0700150 return ImmutableSet.copyOf(store.getAlarms().stream().filter(
kmcpeakeb172d5f2015-12-10 11:30:43 +0000151 a -> !a.severity().equals(Alarm.SeverityLevel.CLEARED)).
Andrea Campanella8e94b0c2016-04-12 13:58:07 -0700152 collect(Collectors.toSet()));
kmcpeake4fe18c82015-11-17 20:07:39 +0000153 }
154
155 @Override
kmcpeakea5404812015-12-08 11:52:50 +0000156 public Set<Alarm> getAlarms(Alarm.SeverityLevel severity) {
Andrea Campanella8e94b0c2016-04-12 13:58:07 -0700157 return ImmutableSet.copyOf(store.getAlarms().stream().filter(
kmcpeakeb172d5f2015-12-10 11:30:43 +0000158 a -> a.severity().equals(severity)).
Andrea Campanella8e94b0c2016-04-12 13:58:07 -0700159 collect(Collectors.toSet()));
kmcpeake4fe18c82015-11-17 20:07:39 +0000160 }
161
162 @Override
kmcpeakea5404812015-12-08 11:52:50 +0000163 public Set<Alarm> getAlarms(DeviceId deviceId) {
Andrea Campanella8e94b0c2016-04-12 13:58:07 -0700164 return ImmutableSet.copyOf(store.getAlarms(deviceId));
kmcpeakeb172d5f2015-12-10 11:30:43 +0000165 }
166
167 private Set<Alarm> getActiveAlarms(DeviceId deviceId) {
Andrea Campanella8e94b0c2016-04-12 13:58:07 -0700168 return ImmutableSet.copyOf(getActiveAlarms().stream().filter(
kmcpeakeb172d5f2015-12-10 11:30:43 +0000169 a -> deviceId.equals(a.deviceId())).
Andrea Campanella8e94b0c2016-04-12 13:58:07 -0700170 collect(Collectors.toSet()));
kmcpeake4fe18c82015-11-17 20:07:39 +0000171 }
172
173 @Override
kmcpeakea5404812015-12-08 11:52:50 +0000174 public Set<Alarm> getAlarms(DeviceId deviceId, AlarmEntityId source) {
Andrea Campanella8e94b0c2016-04-12 13:58:07 -0700175 return ImmutableSet.copyOf(getAlarms(deviceId).stream().filter(
176 a -> source.equals(a.source())).collect(Collectors.toSet()));
kmcpeake4fe18c82015-11-17 20:07:39 +0000177 }
178
179 @Override
kmcpeakea5404812015-12-08 11:52:50 +0000180 public Set<Alarm> getAlarmsForLink(ConnectPoint src, ConnectPoint dst) {
kmcpeake4fe18c82015-11-17 20:07:39 +0000181 throw new UnsupportedOperationException(NOT_SUPPORTED_YET);
182 }
183
184 @Override
kmcpeakea5404812015-12-08 11:52:50 +0000185 public Set<Alarm> getAlarmsForFlow(DeviceId deviceId, long flowId) {
kmcpeake4fe18c82015-11-17 20:07:39 +0000186 throw new UnsupportedOperationException(NOT_SUPPORTED_YET);
187 }
188
Andrea Campanellae72ac552016-04-11 10:04:52 -0700189 @Override
190 protected AlarmProviderService createProviderService(AlarmProvider provider) {
191 return new InternalAlarmProviderService(provider);
kmcpeake4fe18c82015-11-17 20:07:39 +0000192 }
193
kmcpeakeb172d5f2015-12-10 11:30:43 +0000194 // Synchronised to prevent duplicate NE alarms being raised
Andrea Campanellae72ac552016-04-11 10:04:52 -0700195 protected synchronized void updateAlarms(DeviceId deviceId, Set<Alarm> discoveredSet) {
kmcpeakeb172d5f2015-12-10 11:30:43 +0000196 Set<Alarm> storedSet = getActiveAlarms(deviceId);
Andrea Campanella8e94b0c2016-04-12 13:58:07 -0700197 log.debug("CurrentNeAlarms={}. DiscoveredAlarms={}", storedSet, discoveredSet);
kmcpeakeb172d5f2015-12-10 11:30:43 +0000198
199 if (CollectionUtils.isEqualCollection(storedSet, discoveredSet)) {
Andrea Campanella8e94b0c2016-04-12 13:58:07 -0700200 log.debug("No update for {}.", deviceId);
kmcpeakeb172d5f2015-12-10 11:30:43 +0000201 return;
kmcpeake4fe18c82015-11-17 20:07:39 +0000202 }
Andrea Campanella8e94b0c2016-04-12 13:58:07 -0700203 //TODO implement distinction between UPDATED and CLEARED ALARMS
kmcpeakeb172d5f2015-12-10 11:30:43 +0000204 storedSet.stream().filter(
205 (stored) -> (!discoveredSet.contains(stored))).forEach((stored) -> {
Andrea Campanella8e94b0c2016-04-12 13:58:07 -0700206 log.debug("Alarm will be Cleared as it is not on the device. Cleared alarm: {}.", stored);
Andrea Campanellae72ac552016-04-11 10:04:52 -0700207 clear(stored.id());
208 });
kmcpeakeb172d5f2015-12-10 11:30:43 +0000209
210 discoveredSet.stream().filter(
211 (discovered) -> (!storedSet.contains(discovered))).forEach((discovered) -> {
Andrea Campanella8e94b0c2016-04-12 13:58:07 -0700212 log.info("New alarm raised {}", discovered);
kmcpeakeb172d5f2015-12-10 11:30:43 +0000213 AlarmId id = generateAlarmId();
Andrea Campanella8e94b0c2016-04-12 13:58:07 -0700214 store.setAlarm(new DefaultAlarm.Builder(discovered).withId(id).build());
kmcpeakeb172d5f2015-12-10 11:30:43 +0000215 });
kmcpeake4fe18c82015-11-17 20:07:39 +0000216 }
217
Andrea Campanella8e94b0c2016-04-12 13:58:07 -0700218 //TODO improve implementation of AlarmId
219 private AlarmId generateAlarmId() {
220 return AlarmId.alarmId(alarmIdGenerator.incrementAndGet());
221 }
222
223 private class InternalAlarmProviderService extends AbstractProviderService<AlarmProvider>
Andrea Campanellae72ac552016-04-11 10:04:52 -0700224 implements AlarmProviderService {
225
226 InternalAlarmProviderService(AlarmProvider provider) {
227 super(provider);
Andrea Campanellae72ac552016-04-11 10:04:52 -0700228 }
229
230 @Override
231 public void updateAlarmList(DeviceId deviceId, Collection<Alarm> alarms) {
232 updateAlarms(deviceId, ImmutableSet.copyOf(alarms));
233 }
234 }
kmcpeake4fe18c82015-11-17 20:07:39 +0000235}