blob: c7f724e4115c292b8455af8fea9e33264d2ea43e [file] [log] [blame]
kmcpeake4fe18c82015-11-17 20:07:39 +00001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-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 Campanellae72ac552016-04-11 10:04:52 -070024import org.apache.felix.scr.annotations.Service;
25import org.onlab.util.ItemNotFoundException;
kmcpeake4fe18c82015-11-17 20:07:39 +000026import org.onosproject.incubator.net.faultmanagement.alarm.Alarm;
27import org.onosproject.incubator.net.faultmanagement.alarm.AlarmEntityId;
kmcpeake4fe18c82015-11-17 20:07:39 +000028import org.onosproject.incubator.net.faultmanagement.alarm.AlarmId;
Andrea Campanellae72ac552016-04-11 10:04:52 -070029import org.onosproject.incubator.net.faultmanagement.alarm.AlarmProvider;
30import org.onosproject.incubator.net.faultmanagement.alarm.AlarmProviderRegistry;
31import org.onosproject.incubator.net.faultmanagement.alarm.AlarmProviderService;
kmcpeake4fe18c82015-11-17 20:07:39 +000032import org.onosproject.incubator.net.faultmanagement.alarm.AlarmService;
Andrea Campanellae72ac552016-04-11 10:04:52 -070033import org.onosproject.incubator.net.faultmanagement.alarm.DefaultAlarm;
kmcpeake4fe18c82015-11-17 20:07:39 +000034import org.onosproject.net.ConnectPoint;
35import org.onosproject.net.DeviceId;
Andrea Campanellae72ac552016-04-11 10:04:52 -070036import org.onosproject.net.provider.AbstractProviderRegistry;
37import org.onosproject.net.provider.AbstractProviderService;
kmcpeake4fe18c82015-11-17 20:07:39 +000038import org.osgi.service.component.ComponentContext;
Andrea Campanellae72ac552016-04-11 10:04:52 -070039import org.slf4j.Logger;
kmcpeakeb172d5f2015-12-10 11:30:43 +000040
Andrea Campanellae72ac552016-04-11 10:04:52 -070041import java.util.Collection;
42import java.util.Map;
43import java.util.Set;
44import java.util.concurrent.ConcurrentHashMap;
kmcpeakeb172d5f2015-12-10 11:30:43 +000045import java.util.concurrent.atomic.AtomicLong;
Andrea Campanellae72ac552016-04-11 10:04:52 -070046import java.util.stream.Collectors;
47
48import static com.google.common.base.Preconditions.checkNotNull;
49import static org.onlab.util.Tools.nullIsNotFound;
50import static org.slf4j.LoggerFactory.getLogger;
kmcpeake4fe18c82015-11-17 20:07:39 +000051
52/**
53 * Implementation of the Alarm service.
54 */
55@Component(immediate = true)
56@Service
Andrea Campanellae72ac552016-04-11 10:04:52 -070057public class AlarmsManager
58 extends AbstractProviderRegistry<AlarmProvider, AlarmProviderService>
59 implements AlarmService, AlarmProviderRegistry {
kmcpeakeb172d5f2015-12-10 11:30:43 +000060
kmcpeake4fe18c82015-11-17 20:07:39 +000061 private final Logger log = getLogger(getClass());
kmcpeake4fe18c82015-11-17 20:07:39 +000062
kmcpeake4fe18c82015-11-17 20:07:39 +000063 private final AtomicLong alarmIdGenerator = new AtomicLong(0);
64
Andrea Campanellae72ac552016-04-11 10:04:52 -070065 // TODO Later should must be persisted to disk or database
66 protected final Map<AlarmId, Alarm> alarms = new ConcurrentHashMap<>();
67
68 private static final String NOT_SUPPORTED_YET = "Not supported yet.";
69
70 @Activate
71 public void activate(ComponentContext context) {
72 log.info("Started");
73 }
74
75 @Deactivate
76 public void deactivate(ComponentContext context) {
77 alarms.clear();
78 log.info("Stopped");
79 }
80
81 @Modified
82 public boolean modified(ComponentContext context) {
83 log.info("Modified");
84 return true;
85 }
86
kmcpeakeb172d5f2015-12-10 11:30:43 +000087 private AlarmId generateAlarmId() {
88 return AlarmId.alarmId(alarmIdGenerator.incrementAndGet());
89 }
kmcpeake4fe18c82015-11-17 20:07:39 +000090
kmcpeakeb172d5f2015-12-10 11:30:43 +000091 @Override
92 public Alarm updateBookkeepingFields(AlarmId id, boolean isAcknowledged, String assignedUser) {
93
94 Alarm found = alarms.get(id);
kmcpeake4fe18c82015-11-17 20:07:39 +000095 if (found == null) {
kmcpeakeb172d5f2015-12-10 11:30:43 +000096 throw new ItemNotFoundException("Alarm with id " + id + " found");
kmcpeake4fe18c82015-11-17 20:07:39 +000097 }
kmcpeakeb172d5f2015-12-10 11:30:43 +000098
99 Alarm updated = new DefaultAlarm.Builder(found).
100 withAcknowledged(isAcknowledged).
101 withAssignedUser(assignedUser).build();
102 alarms.put(id, updated);
103 return updated;
104 }
105
106 public Alarm clear(AlarmId id) {
kmcpeakeb172d5f2015-12-10 11:30:43 +0000107 Alarm found = alarms.get(id);
108 if (found == null) {
109 log.warn("id {} cant be cleared as it is already gone.", id);
110 return null;
111 }
112 Alarm updated = new DefaultAlarm.Builder(found).clear().build();
113 alarms.put(id, updated);
kmcpeake4fe18c82015-11-17 20:07:39 +0000114 return updated;
115 }
116
117 @Override
kmcpeakeb172d5f2015-12-10 11:30:43 +0000118 public Map<Alarm.SeverityLevel, Long> getAlarmCounts(DeviceId deviceId) {
kmcpeakeb172d5f2015-12-10 11:30:43 +0000119 return getAlarms(deviceId).stream().collect(
120 Collectors.groupingBy(Alarm::severity, Collectors.counting()));
kmcpeake4fe18c82015-11-17 20:07:39 +0000121 }
kmcpeakeb172d5f2015-12-10 11:30:43 +0000122
123 @Override
124 public Map<Alarm.SeverityLevel, Long> getAlarmCounts() {
kmcpeakeb172d5f2015-12-10 11:30:43 +0000125 return getAlarms().stream().collect(
126 Collectors.groupingBy(Alarm::severity, Collectors.counting()));
127 }
128
kmcpeake4fe18c82015-11-17 20:07:39 +0000129 @Override
kmcpeakea5404812015-12-08 11:52:50 +0000130 public Alarm getAlarm(AlarmId alarmId) {
Andrea Campanellae72ac552016-04-11 10:04:52 -0700131 return nullIsNotFound(alarms.get(checkNotNull(alarmId, "Alarm Id cannot be null")),
132 "Alarm is not found");
kmcpeake4fe18c82015-11-17 20:07:39 +0000133 }
134
135 @Override
136 public Set<Alarm> getAlarms() {
Andrea Campanellae72ac552016-04-11 10:04:52 -0700137 return ImmutableSet.copyOf(alarms.values());
kmcpeake4fe18c82015-11-17 20:07:39 +0000138 }
139
140 @Override
141 public Set<Alarm> getActiveAlarms() {
kmcpeakeb172d5f2015-12-10 11:30:43 +0000142 return alarms.values().stream().filter(
143 a -> !a.severity().equals(Alarm.SeverityLevel.CLEARED)).
144 collect(Collectors.toSet());
kmcpeake4fe18c82015-11-17 20:07:39 +0000145 }
146
147 @Override
kmcpeakea5404812015-12-08 11:52:50 +0000148 public Set<Alarm> getAlarms(Alarm.SeverityLevel severity) {
kmcpeakeb172d5f2015-12-10 11:30:43 +0000149 return alarms.values().stream().filter(
150 a -> a.severity().equals(severity)).
151 collect(Collectors.toSet());
kmcpeake4fe18c82015-11-17 20:07:39 +0000152 }
153
154 @Override
kmcpeakea5404812015-12-08 11:52:50 +0000155 public Set<Alarm> getAlarms(DeviceId deviceId) {
kmcpeakeb172d5f2015-12-10 11:30:43 +0000156 return alarms.values().stream().filter(
157 a -> deviceId.equals(a.deviceId())).
158 collect(Collectors.toSet());
159 }
160
161 private Set<Alarm> getActiveAlarms(DeviceId deviceId) {
162 return getActiveAlarms().stream().filter(
163 a -> deviceId.equals(a.deviceId())).
164 collect(Collectors.toSet());
kmcpeake4fe18c82015-11-17 20:07:39 +0000165 }
166
167 @Override
kmcpeakea5404812015-12-08 11:52:50 +0000168 public Set<Alarm> getAlarms(DeviceId deviceId, AlarmEntityId source) {
kmcpeakeb172d5f2015-12-10 11:30:43 +0000169 return getAlarms(deviceId).stream().filter(
170 a -> source.equals(a.source())
171 ).collect(Collectors.toSet());
kmcpeake4fe18c82015-11-17 20:07:39 +0000172 }
173
174 @Override
kmcpeakea5404812015-12-08 11:52:50 +0000175 public Set<Alarm> getAlarmsForLink(ConnectPoint src, ConnectPoint dst) {
kmcpeake4fe18c82015-11-17 20:07:39 +0000176 throw new UnsupportedOperationException(NOT_SUPPORTED_YET);
177 }
178
179 @Override
kmcpeakea5404812015-12-08 11:52:50 +0000180 public Set<Alarm> getAlarmsForFlow(DeviceId deviceId, long flowId) {
kmcpeake4fe18c82015-11-17 20:07:39 +0000181 throw new UnsupportedOperationException(NOT_SUPPORTED_YET);
182 }
183
Andrea Campanellae72ac552016-04-11 10:04:52 -0700184 @Override
185 protected AlarmProviderService createProviderService(AlarmProvider provider) {
186 return new InternalAlarmProviderService(provider);
kmcpeake4fe18c82015-11-17 20:07:39 +0000187 }
188
kmcpeakeb172d5f2015-12-10 11:30:43 +0000189 // Synchronised to prevent duplicate NE alarms being raised
Andrea Campanellae72ac552016-04-11 10:04:52 -0700190 protected synchronized void updateAlarms(DeviceId deviceId, Set<Alarm> discoveredSet) {
kmcpeakeb172d5f2015-12-10 11:30:43 +0000191 Set<Alarm> storedSet = getActiveAlarms(deviceId);
192 log.trace("currentNeAlarms={}. discoveredAlarms={}", storedSet, discoveredSet);
193
194 if (CollectionUtils.isEqualCollection(storedSet, discoveredSet)) {
195 log.debug("Alarm lists are equivalent so no update for {}.", deviceId);
196 return;
kmcpeake4fe18c82015-11-17 20:07:39 +0000197 }
kmcpeakeb172d5f2015-12-10 11:30:43 +0000198
199 storedSet.stream().filter(
200 (stored) -> (!discoveredSet.contains(stored))).forEach((stored) -> {
Andrea Campanellae72ac552016-04-11 10:04:52 -0700201 log.debug("Alarm will be cleared as it is not on the element. Cleared alarm: {}.", stored);
202 clear(stored.id());
203 });
kmcpeakeb172d5f2015-12-10 11:30:43 +0000204
205 discoveredSet.stream().filter(
206 (discovered) -> (!storedSet.contains(discovered))).forEach((discovered) -> {
Andrea Campanellae72ac552016-04-11 10:04:52 -0700207 log.info("New alarm raised as it is missing. New alarm: {}.", discovered);
kmcpeakeb172d5f2015-12-10 11:30:43 +0000208 AlarmId id = generateAlarmId();
209 alarms.put(id, new DefaultAlarm.Builder(discovered).withId(id).build());
210 });
kmcpeake4fe18c82015-11-17 20:07:39 +0000211 }
212
Andrea Campanellae72ac552016-04-11 10:04:52 -0700213 private class InternalAlarmProviderService
214 extends AbstractProviderService<AlarmProvider>
215 implements AlarmProviderService {
216
217 InternalAlarmProviderService(AlarmProvider provider) {
218 super(provider);
219
220
221 }
222
223 @Override
224 public void updateAlarmList(DeviceId deviceId, Collection<Alarm> alarms) {
225 updateAlarms(deviceId, ImmutableSet.copyOf(alarms));
226 }
227 }
kmcpeake4fe18c82015-11-17 20:07:39 +0000228}