Committed by
Gerrit Code Review
[ONOS-4287] Persistent and distributed alarm store
Change-Id: I2fb0f5d84e563a53f036be012a8190d7df5869dc
Showing
15 changed files
with
723 additions
and
296 deletions
| ... | @@ -69,5 +69,12 @@ | ... | @@ -69,5 +69,12 @@ |
| 69 | <classifier>tests</classifier> | 69 | <classifier>tests</classifier> |
| 70 | <scope>test</scope> | 70 | <scope>test</scope> |
| 71 | </dependency> | 71 | </dependency> |
| 72 | + <dependency> | ||
| 73 | + <groupId>org.onosproject</groupId> | ||
| 74 | + <artifactId>onos-core-common</artifactId> | ||
| 75 | + <version>${project.version}</version> | ||
| 76 | + <classifier>tests</classifier> | ||
| 77 | + <scope>test</scope> | ||
| 78 | + </dependency> | ||
| 72 | </dependencies> | 79 | </dependencies> |
| 73 | </project> | 80 | </project> | ... | ... |
apps/faultmanagement/fmmgr/src/main/java/org/onosproject/faultmanagement/api/AlarmStore.java
0 → 100644
| 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.faultmanagement.api; | ||
| 18 | + | ||
| 19 | +import org.onosproject.incubator.net.faultmanagement.alarm.Alarm; | ||
| 20 | +import org.onosproject.incubator.net.faultmanagement.alarm.AlarmEvent; | ||
| 21 | +import org.onosproject.incubator.net.faultmanagement.alarm.AlarmId; | ||
| 22 | +import org.onosproject.net.DeviceId; | ||
| 23 | +import org.onosproject.store.Store; | ||
| 24 | + | ||
| 25 | +import java.util.Collection; | ||
| 26 | + | ||
| 27 | +/** | ||
| 28 | + * Manages inventory of alarms; not intended for direct use. | ||
| 29 | + */ | ||
| 30 | +public interface AlarmStore extends Store<AlarmEvent, AlarmStoreDelegate> { | ||
| 31 | + | ||
| 32 | + /** | ||
| 33 | + * Retrieves and alarm based on it's id. | ||
| 34 | + * | ||
| 35 | + * @param alarmId alarm identifier | ||
| 36 | + * @return alarm | ||
| 37 | + */ | ||
| 38 | + Alarm getAlarm(AlarmId alarmId); | ||
| 39 | + | ||
| 40 | + /** | ||
| 41 | + * Retrieves all alarms present in the system. | ||
| 42 | + * | ||
| 43 | + * @return alarms | ||
| 44 | + */ | ||
| 45 | + Collection<Alarm> getAlarms(); | ||
| 46 | + | ||
| 47 | + /** | ||
| 48 | + * Retrieves alarms for a device. | ||
| 49 | + * | ||
| 50 | + * @param deviceId device identifier | ||
| 51 | + * @return alarms | ||
| 52 | + */ | ||
| 53 | + Collection<Alarm> getAlarms(DeviceId deviceId); | ||
| 54 | + | ||
| 55 | + /** | ||
| 56 | + * Stores an alarm. | ||
| 57 | + * | ||
| 58 | + * @param alarm alarm | ||
| 59 | + */ | ||
| 60 | + void setAlarm(Alarm alarm); | ||
| 61 | + | ||
| 62 | + /** | ||
| 63 | + * Removes an alarm. | ||
| 64 | + * | ||
| 65 | + * @param alarmId alarm | ||
| 66 | + */ | ||
| 67 | + void removeAlarm(AlarmId alarmId); | ||
| 68 | +} |
apps/faultmanagement/fmmgr/src/main/java/org/onosproject/faultmanagement/api/AlarmStoreDelegate.java
0 → 100644
| 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.faultmanagement.api; | ||
| 18 | + | ||
| 19 | +import org.onosproject.incubator.net.faultmanagement.alarm.AlarmEvent; | ||
| 20 | +import org.onosproject.store.StoreDelegate; | ||
| 21 | + | ||
| 22 | +/** | ||
| 23 | + * Infrastructure alarm store delegate abstraction. | ||
| 24 | + */ | ||
| 25 | +public interface AlarmStoreDelegate extends StoreDelegate<AlarmEvent> { | ||
| 26 | +} |
apps/faultmanagement/fmmgr/src/main/java/org/onosproject/faultmanagement/api/package-info.java
0 → 100644
| 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 | +/** | ||
| 18 | + * Infrastructure alarm store & related services API definitions. | ||
| 19 | + */ | ||
| 20 | +package org.onosproject.faultmanagement.api; |
| ... | @@ -21,11 +21,17 @@ import org.apache.felix.scr.annotations.Activate; | ... | @@ -21,11 +21,17 @@ import org.apache.felix.scr.annotations.Activate; |
| 21 | import org.apache.felix.scr.annotations.Component; | 21 | import org.apache.felix.scr.annotations.Component; |
| 22 | import org.apache.felix.scr.annotations.Deactivate; | 22 | import org.apache.felix.scr.annotations.Deactivate; |
| 23 | import org.apache.felix.scr.annotations.Modified; | 23 | import org.apache.felix.scr.annotations.Modified; |
| 24 | +import org.apache.felix.scr.annotations.Reference; | ||
| 25 | +import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
| 24 | import org.apache.felix.scr.annotations.Service; | 26 | import org.apache.felix.scr.annotations.Service; |
| 25 | import org.onlab.util.ItemNotFoundException; | 27 | import org.onlab.util.ItemNotFoundException; |
| 28 | +import org.onosproject.faultmanagement.api.AlarmStore; | ||
| 29 | +import org.onosproject.faultmanagement.api.AlarmStoreDelegate; | ||
| 26 | import org.onosproject.incubator.net.faultmanagement.alarm.Alarm; | 30 | import org.onosproject.incubator.net.faultmanagement.alarm.Alarm; |
| 27 | import org.onosproject.incubator.net.faultmanagement.alarm.AlarmEntityId; | 31 | import org.onosproject.incubator.net.faultmanagement.alarm.AlarmEntityId; |
| 32 | +import org.onosproject.incubator.net.faultmanagement.alarm.AlarmEvent; | ||
| 28 | import org.onosproject.incubator.net.faultmanagement.alarm.AlarmId; | 33 | import org.onosproject.incubator.net.faultmanagement.alarm.AlarmId; |
| 34 | +import org.onosproject.incubator.net.faultmanagement.alarm.AlarmListener; | ||
| 29 | import org.onosproject.incubator.net.faultmanagement.alarm.AlarmProvider; | 35 | import org.onosproject.incubator.net.faultmanagement.alarm.AlarmProvider; |
| 30 | import org.onosproject.incubator.net.faultmanagement.alarm.AlarmProviderRegistry; | 36 | import org.onosproject.incubator.net.faultmanagement.alarm.AlarmProviderRegistry; |
| 31 | import org.onosproject.incubator.net.faultmanagement.alarm.AlarmProviderService; | 37 | import org.onosproject.incubator.net.faultmanagement.alarm.AlarmProviderService; |
| ... | @@ -33,15 +39,13 @@ import org.onosproject.incubator.net.faultmanagement.alarm.AlarmService; | ... | @@ -33,15 +39,13 @@ import org.onosproject.incubator.net.faultmanagement.alarm.AlarmService; |
| 33 | import org.onosproject.incubator.net.faultmanagement.alarm.DefaultAlarm; | 39 | import org.onosproject.incubator.net.faultmanagement.alarm.DefaultAlarm; |
| 34 | import org.onosproject.net.ConnectPoint; | 40 | import org.onosproject.net.ConnectPoint; |
| 35 | import org.onosproject.net.DeviceId; | 41 | import org.onosproject.net.DeviceId; |
| 36 | -import org.onosproject.net.provider.AbstractProviderRegistry; | 42 | +import org.onosproject.net.provider.AbstractListenerProviderRegistry; |
| 37 | import org.onosproject.net.provider.AbstractProviderService; | 43 | import org.onosproject.net.provider.AbstractProviderService; |
| 38 | -import org.osgi.service.component.ComponentContext; | ||
| 39 | import org.slf4j.Logger; | 44 | import org.slf4j.Logger; |
| 40 | 45 | ||
| 41 | import java.util.Collection; | 46 | import java.util.Collection; |
| 42 | import java.util.Map; | 47 | import java.util.Map; |
| 43 | import java.util.Set; | 48 | import java.util.Set; |
| 44 | -import java.util.concurrent.ConcurrentHashMap; | ||
| 45 | import java.util.concurrent.atomic.AtomicLong; | 49 | import java.util.concurrent.atomic.AtomicLong; |
| 46 | import java.util.stream.Collectors; | 50 | import java.util.stream.Collectors; |
| 47 | 51 | ||
| ... | @@ -54,63 +58,67 @@ import static org.slf4j.LoggerFactory.getLogger; | ... | @@ -54,63 +58,67 @@ import static org.slf4j.LoggerFactory.getLogger; |
| 54 | */ | 58 | */ |
| 55 | @Component(immediate = true) | 59 | @Component(immediate = true) |
| 56 | @Service | 60 | @Service |
| 57 | -public class AlarmsManager | 61 | +public class AlarmManager |
| 58 | - extends AbstractProviderRegistry<AlarmProvider, AlarmProviderService> | 62 | + extends AbstractListenerProviderRegistry<AlarmEvent, AlarmListener, AlarmProvider, AlarmProviderService> |
| 59 | implements AlarmService, AlarmProviderRegistry { | 63 | implements AlarmService, AlarmProviderRegistry { |
| 60 | 64 | ||
| 61 | private final Logger log = getLogger(getClass()); | 65 | private final Logger log = getLogger(getClass()); |
| 62 | 66 | ||
| 63 | - private final AtomicLong alarmIdGenerator = new AtomicLong(0); | ||
| 64 | 67 | ||
| 65 | - // TODO Later should must be persisted to disk or database | 68 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| 66 | - protected final Map<AlarmId, Alarm> alarms = new ConcurrentHashMap<>(); | 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); | ||
| 67 | 75 | ||
| 68 | private static final String NOT_SUPPORTED_YET = "Not supported yet."; | 76 | private static final String NOT_SUPPORTED_YET = "Not supported yet."; |
| 69 | 77 | ||
| 70 | @Activate | 78 | @Activate |
| 71 | - public void activate(ComponentContext context) { | 79 | + public void activate() { |
| 80 | + store.setDelegate(delegate); | ||
| 81 | + eventDispatcher.addSink(AlarmEvent.class, listenerRegistry); | ||
| 72 | log.info("Started"); | 82 | log.info("Started"); |
| 73 | } | 83 | } |
| 74 | 84 | ||
| 75 | @Deactivate | 85 | @Deactivate |
| 76 | - public void deactivate(ComponentContext context) { | 86 | + public void deactivate() { |
| 77 | - alarms.clear(); | 87 | + store.unsetDelegate(delegate); |
| 88 | + eventDispatcher.removeSink(AlarmEvent.class); | ||
| 78 | log.info("Stopped"); | 89 | log.info("Stopped"); |
| 79 | } | 90 | } |
| 80 | 91 | ||
| 81 | @Modified | 92 | @Modified |
| 82 | - public boolean modified(ComponentContext context) { | 93 | + public boolean modified() { |
| 83 | log.info("Modified"); | 94 | log.info("Modified"); |
| 84 | return true; | 95 | return true; |
| 85 | } | 96 | } |
| 86 | 97 | ||
| 87 | - private AlarmId generateAlarmId() { | ||
| 88 | - return AlarmId.alarmId(alarmIdGenerator.incrementAndGet()); | ||
| 89 | - } | ||
| 90 | - | ||
| 91 | @Override | 98 | @Override |
| 92 | public Alarm updateBookkeepingFields(AlarmId id, boolean isAcknowledged, String assignedUser) { | 99 | public Alarm updateBookkeepingFields(AlarmId id, boolean isAcknowledged, String assignedUser) { |
| 93 | 100 | ||
| 94 | - Alarm found = alarms.get(id); | 101 | + Alarm found = store.getAlarm(id); |
| 95 | if (found == null) { | 102 | if (found == null) { |
| 96 | throw new ItemNotFoundException("Alarm with id " + id + " found"); | 103 | throw new ItemNotFoundException("Alarm with id " + id + " found"); |
| 97 | } | 104 | } |
| 98 | 105 | ||
| 99 | - Alarm updated = new DefaultAlarm.Builder(found). | 106 | + Alarm updated = new DefaultAlarm.Builder(found) |
| 100 | - withAcknowledged(isAcknowledged). | 107 | + .withId(found.id()) |
| 101 | - withAssignedUser(assignedUser).build(); | 108 | + .withAcknowledged(isAcknowledged) |
| 102 | - alarms.put(id, updated); | 109 | + .withAssignedUser(assignedUser).build(); |
| 110 | + store.setAlarm(updated); | ||
| 103 | return updated; | 111 | return updated; |
| 104 | } | 112 | } |
| 105 | 113 | ||
| 106 | public Alarm clear(AlarmId id) { | 114 | public Alarm clear(AlarmId id) { |
| 107 | - Alarm found = alarms.get(id); | 115 | + Alarm found = store.getAlarm(id); |
| 108 | if (found == null) { | 116 | if (found == null) { |
| 109 | - log.warn("id {} cant be cleared as it is already gone.", id); | 117 | + log.warn("Alarm {} is not present", id); |
| 110 | return null; | 118 | return null; |
| 111 | } | 119 | } |
| 112 | - Alarm updated = new DefaultAlarm.Builder(found).clear().build(); | 120 | + Alarm updated = new DefaultAlarm.Builder(found).withId(id).clear().build(); |
| 113 | - alarms.put(id, updated); | 121 | + store.setAlarm(updated); |
| 114 | return updated; | 122 | return updated; |
| 115 | } | 123 | } |
| 116 | 124 | ||
| ... | @@ -128,47 +136,44 @@ public class AlarmsManager | ... | @@ -128,47 +136,44 @@ public class AlarmsManager |
| 128 | 136 | ||
| 129 | @Override | 137 | @Override |
| 130 | public Alarm getAlarm(AlarmId alarmId) { | 138 | public Alarm getAlarm(AlarmId alarmId) { |
| 131 | - return nullIsNotFound(alarms.get(checkNotNull(alarmId, "Alarm Id cannot be null")), | 139 | + return nullIsNotFound(store.getAlarm(checkNotNull(alarmId, "Alarm Id cannot be null")), |
| 132 | "Alarm is not found"); | 140 | "Alarm is not found"); |
| 133 | } | 141 | } |
| 134 | 142 | ||
| 135 | @Override | 143 | @Override |
| 136 | public Set<Alarm> getAlarms() { | 144 | public Set<Alarm> getAlarms() { |
| 137 | - return ImmutableSet.copyOf(alarms.values()); | 145 | + return ImmutableSet.copyOf(store.getAlarms()); |
| 138 | } | 146 | } |
| 139 | 147 | ||
| 140 | @Override | 148 | @Override |
| 141 | public Set<Alarm> getActiveAlarms() { | 149 | public Set<Alarm> getActiveAlarms() { |
| 142 | - return alarms.values().stream().filter( | 150 | + return ImmutableSet.copyOf(store.getAlarms().stream().filter( |
| 143 | a -> !a.severity().equals(Alarm.SeverityLevel.CLEARED)). | 151 | a -> !a.severity().equals(Alarm.SeverityLevel.CLEARED)). |
| 144 | - collect(Collectors.toSet()); | 152 | + collect(Collectors.toSet())); |
| 145 | } | 153 | } |
| 146 | 154 | ||
| 147 | @Override | 155 | @Override |
| 148 | public Set<Alarm> getAlarms(Alarm.SeverityLevel severity) { | 156 | public Set<Alarm> getAlarms(Alarm.SeverityLevel severity) { |
| 149 | - return alarms.values().stream().filter( | 157 | + return ImmutableSet.copyOf(store.getAlarms().stream().filter( |
| 150 | a -> a.severity().equals(severity)). | 158 | a -> a.severity().equals(severity)). |
| 151 | - collect(Collectors.toSet()); | 159 | + collect(Collectors.toSet())); |
| 152 | } | 160 | } |
| 153 | 161 | ||
| 154 | @Override | 162 | @Override |
| 155 | public Set<Alarm> getAlarms(DeviceId deviceId) { | 163 | public Set<Alarm> getAlarms(DeviceId deviceId) { |
| 156 | - return alarms.values().stream().filter( | 164 | + return ImmutableSet.copyOf(store.getAlarms(deviceId)); |
| 157 | - a -> deviceId.equals(a.deviceId())). | ||
| 158 | - collect(Collectors.toSet()); | ||
| 159 | } | 165 | } |
| 160 | 166 | ||
| 161 | private Set<Alarm> getActiveAlarms(DeviceId deviceId) { | 167 | private Set<Alarm> getActiveAlarms(DeviceId deviceId) { |
| 162 | - return getActiveAlarms().stream().filter( | 168 | + return ImmutableSet.copyOf(getActiveAlarms().stream().filter( |
| 163 | a -> deviceId.equals(a.deviceId())). | 169 | a -> deviceId.equals(a.deviceId())). |
| 164 | - collect(Collectors.toSet()); | 170 | + collect(Collectors.toSet())); |
| 165 | } | 171 | } |
| 166 | 172 | ||
| 167 | @Override | 173 | @Override |
| 168 | public Set<Alarm> getAlarms(DeviceId deviceId, AlarmEntityId source) { | 174 | public Set<Alarm> getAlarms(DeviceId deviceId, AlarmEntityId source) { |
| 169 | - return getAlarms(deviceId).stream().filter( | 175 | + return ImmutableSet.copyOf(getAlarms(deviceId).stream().filter( |
| 170 | - a -> source.equals(a.source()) | 176 | + a -> source.equals(a.source())).collect(Collectors.toSet())); |
| 171 | - ).collect(Collectors.toSet()); | ||
| 172 | } | 177 | } |
| 173 | 178 | ||
| 174 | @Override | 179 | @Override |
| ... | @@ -189,35 +194,37 @@ public class AlarmsManager | ... | @@ -189,35 +194,37 @@ public class AlarmsManager |
| 189 | // Synchronised to prevent duplicate NE alarms being raised | 194 | // Synchronised to prevent duplicate NE alarms being raised |
| 190 | protected synchronized void updateAlarms(DeviceId deviceId, Set<Alarm> discoveredSet) { | 195 | protected synchronized void updateAlarms(DeviceId deviceId, Set<Alarm> discoveredSet) { |
| 191 | Set<Alarm> storedSet = getActiveAlarms(deviceId); | 196 | Set<Alarm> storedSet = getActiveAlarms(deviceId); |
| 192 | - log.trace("currentNeAlarms={}. discoveredAlarms={}", storedSet, discoveredSet); | 197 | + log.debug("CurrentNeAlarms={}. DiscoveredAlarms={}", storedSet, discoveredSet); |
| 193 | 198 | ||
| 194 | if (CollectionUtils.isEqualCollection(storedSet, discoveredSet)) { | 199 | if (CollectionUtils.isEqualCollection(storedSet, discoveredSet)) { |
| 195 | - log.debug("Alarm lists are equivalent so no update for {}.", deviceId); | 200 | + log.debug("No update for {}.", deviceId); |
| 196 | return; | 201 | return; |
| 197 | } | 202 | } |
| 198 | - | 203 | + //TODO implement distinction between UPDATED and CLEARED ALARMS |
| 199 | storedSet.stream().filter( | 204 | storedSet.stream().filter( |
| 200 | (stored) -> (!discoveredSet.contains(stored))).forEach((stored) -> { | 205 | (stored) -> (!discoveredSet.contains(stored))).forEach((stored) -> { |
| 201 | - log.debug("Alarm will be cleared as it is not on the element. Cleared alarm: {}.", stored); | 206 | + log.debug("Alarm will be Cleared as it is not on the device. Cleared alarm: {}.", stored); |
| 202 | clear(stored.id()); | 207 | clear(stored.id()); |
| 203 | }); | 208 | }); |
| 204 | 209 | ||
| 205 | discoveredSet.stream().filter( | 210 | discoveredSet.stream().filter( |
| 206 | (discovered) -> (!storedSet.contains(discovered))).forEach((discovered) -> { | 211 | (discovered) -> (!storedSet.contains(discovered))).forEach((discovered) -> { |
| 207 | - log.info("New alarm raised as it is missing. New alarm: {}.", discovered); | 212 | + log.info("New alarm raised {}", discovered); |
| 208 | AlarmId id = generateAlarmId(); | 213 | AlarmId id = generateAlarmId(); |
| 209 | - alarms.put(id, new DefaultAlarm.Builder(discovered).withId(id).build()); | 214 | + store.setAlarm(new DefaultAlarm.Builder(discovered).withId(id).build()); |
| 210 | }); | 215 | }); |
| 211 | } | 216 | } |
| 212 | 217 | ||
| 213 | - private class InternalAlarmProviderService | 218 | + //TODO improve implementation of AlarmId |
| 214 | - extends AbstractProviderService<AlarmProvider> | 219 | + private AlarmId generateAlarmId() { |
| 220 | + return AlarmId.alarmId(alarmIdGenerator.incrementAndGet()); | ||
| 221 | + } | ||
| 222 | + | ||
| 223 | + private class InternalAlarmProviderService extends AbstractProviderService<AlarmProvider> | ||
| 215 | implements AlarmProviderService { | 224 | implements AlarmProviderService { |
| 216 | 225 | ||
| 217 | InternalAlarmProviderService(AlarmProvider provider) { | 226 | InternalAlarmProviderService(AlarmProvider provider) { |
| 218 | super(provider); | 227 | super(provider); |
| 219 | - | ||
| 220 | - | ||
| 221 | } | 228 | } |
| 222 | 229 | ||
| 223 | @Override | 230 | @Override | ... | ... |
| 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.faultmanagement.impl; | ||
| 18 | + | ||
| 19 | +import com.google.common.collect.ImmutableSet; | ||
| 20 | +import org.apache.felix.scr.annotations.Activate; | ||
| 21 | +import org.apache.felix.scr.annotations.Component; | ||
| 22 | +import org.apache.felix.scr.annotations.Deactivate; | ||
| 23 | +import org.apache.felix.scr.annotations.Modified; | ||
| 24 | +import org.apache.felix.scr.annotations.Reference; | ||
| 25 | +import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
| 26 | +import org.apache.felix.scr.annotations.Service; | ||
| 27 | +import org.onosproject.faultmanagement.api.AlarmStore; | ||
| 28 | +import org.onosproject.faultmanagement.api.AlarmStoreDelegate; | ||
| 29 | +import org.onosproject.incubator.net.faultmanagement.alarm.Alarm; | ||
| 30 | +import org.onosproject.incubator.net.faultmanagement.alarm.AlarmEntityId; | ||
| 31 | +import org.onosproject.incubator.net.faultmanagement.alarm.AlarmEvent; | ||
| 32 | +import org.onosproject.incubator.net.faultmanagement.alarm.AlarmId; | ||
| 33 | +import org.onosproject.incubator.net.faultmanagement.alarm.DefaultAlarm; | ||
| 34 | +import org.onosproject.net.DeviceId; | ||
| 35 | +import org.onosproject.store.AbstractStore; | ||
| 36 | +import org.onosproject.store.serializers.KryoNamespaces; | ||
| 37 | +import org.onosproject.store.service.ConsistentMap; | ||
| 38 | +import org.onosproject.store.service.MapEvent; | ||
| 39 | +import org.onosproject.store.service.MapEventListener; | ||
| 40 | +import org.onosproject.store.service.Serializer; | ||
| 41 | +import org.onosproject.store.service.StorageService; | ||
| 42 | +import org.slf4j.Logger; | ||
| 43 | + | ||
| 44 | +import java.util.Collection; | ||
| 45 | +import java.util.Map; | ||
| 46 | +import java.util.stream.Collectors; | ||
| 47 | + | ||
| 48 | +import static org.slf4j.LoggerFactory.getLogger; | ||
| 49 | + | ||
| 50 | +/** | ||
| 51 | + * Manages information of alarms using gossip protocol to distribute | ||
| 52 | + * information. | ||
| 53 | + */ | ||
| 54 | +@Component(immediate = true) | ||
| 55 | +@Service | ||
| 56 | +public class DistributedAlarmStore | ||
| 57 | + extends AbstractStore<AlarmEvent, AlarmStoreDelegate> | ||
| 58 | + implements AlarmStore { | ||
| 59 | + | ||
| 60 | + private final Logger log = getLogger(getClass()); | ||
| 61 | + private ConsistentMap<AlarmId, Alarm> alarms; | ||
| 62 | + private Map<AlarmId, Alarm> alarmsMap; | ||
| 63 | + | ||
| 64 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 65 | + protected StorageService storageService; | ||
| 66 | + | ||
| 67 | + private final MapEventListener<AlarmId, Alarm> listener = new InternalListener(); | ||
| 68 | + | ||
| 69 | + @Activate | ||
| 70 | + public void activate() { | ||
| 71 | + log.info("Started"); | ||
| 72 | + alarms = storageService.<AlarmId, Alarm>consistentMapBuilder() | ||
| 73 | + .withName("onos-alarm-table") | ||
| 74 | + .withSerializer(Serializer.using(KryoNamespaces.API, | ||
| 75 | + Alarm.class, | ||
| 76 | + DefaultAlarm.class, | ||
| 77 | + AlarmId.class, | ||
| 78 | + AlarmEvent.Type.class, | ||
| 79 | + Alarm.SeverityLevel.class, | ||
| 80 | + AlarmEntityId.class)) | ||
| 81 | + .build(); | ||
| 82 | + alarms.addListener(listener); | ||
| 83 | + alarmsMap = alarms.asJavaMap(); | ||
| 84 | + } | ||
| 85 | + | ||
| 86 | + @Deactivate | ||
| 87 | + public void deactivate() { | ||
| 88 | + alarms.removeListener(listener); | ||
| 89 | + log.info("Stopped"); | ||
| 90 | + } | ||
| 91 | + | ||
| 92 | + @Modified | ||
| 93 | + public boolean modified() { | ||
| 94 | + log.info("Modified"); | ||
| 95 | + return true; | ||
| 96 | + } | ||
| 97 | + | ||
| 98 | + @Override | ||
| 99 | + public Alarm getAlarm(AlarmId alarmId) { | ||
| 100 | + return alarmsMap.get(alarmId); | ||
| 101 | + } | ||
| 102 | + | ||
| 103 | + @Override | ||
| 104 | + public Collection<Alarm> getAlarms() { | ||
| 105 | + return ImmutableSet.copyOf(alarmsMap.values()); | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | + @Override | ||
| 109 | + public Collection<Alarm> getAlarms(DeviceId deviceId) { | ||
| 110 | + //FIXME: this is expensive, need refactoring when core maps provide different indexes. | ||
| 111 | + return ImmutableSet.copyOf(alarmsMap.values().stream() | ||
| 112 | + .filter(alarm -> alarm.deviceId().equals(deviceId)) | ||
| 113 | + .collect(Collectors.toSet())); | ||
| 114 | + } | ||
| 115 | + | ||
| 116 | + @Override | ||
| 117 | + public void setAlarm(Alarm alarm) { | ||
| 118 | + alarms.put(alarm.id(), alarm); | ||
| 119 | + } | ||
| 120 | + | ||
| 121 | + @Override | ||
| 122 | + public void removeAlarm(AlarmId alarmId) { | ||
| 123 | + alarms.remove(alarmId); | ||
| 124 | + } | ||
| 125 | + | ||
| 126 | + //Event listener to notify delegates about Map events. | ||
| 127 | + private class InternalListener implements MapEventListener<AlarmId, Alarm> { | ||
| 128 | + | ||
| 129 | + @Override | ||
| 130 | + public void event(MapEvent<AlarmId, Alarm> mapEvent) { | ||
| 131 | + final AlarmEvent.Type type; | ||
| 132 | + final Alarm alarm; | ||
| 133 | + switch (mapEvent.type()) { | ||
| 134 | + case INSERT: | ||
| 135 | + type = AlarmEvent.Type.CREATED; | ||
| 136 | + alarm = mapEvent.newValue().value(); | ||
| 137 | + break; | ||
| 138 | + case UPDATE: | ||
| 139 | + type = AlarmEvent.Type.CREATED; | ||
| 140 | + alarm = mapEvent.newValue().value(); | ||
| 141 | + break; | ||
| 142 | + case REMOVE: | ||
| 143 | + type = AlarmEvent.Type.REMOVED; | ||
| 144 | + alarm = mapEvent.oldValue().value(); | ||
| 145 | + break; | ||
| 146 | + default: | ||
| 147 | + throw new IllegalArgumentException("Wrong event type " + mapEvent.type()); | ||
| 148 | + } | ||
| 149 | + notifyDelegate(new AlarmEvent(type, alarm)); | ||
| 150 | + } | ||
| 151 | + } | ||
| 152 | +} |
| ... | @@ -15,6 +15,6 @@ | ... | @@ -15,6 +15,6 @@ |
| 15 | */ | 15 | */ |
| 16 | 16 | ||
| 17 | /** | 17 | /** |
| 18 | - * Fault Management application implementation. | 18 | + * Infrastructure alarm model & related services implementation. |
| 19 | */ | 19 | */ |
| 20 | package org.onosproject.faultmanagement.impl; | 20 | package org.onosproject.faultmanagement.impl; | ... | ... |
apps/faultmanagement/fmmgr/src/test/java/org/onosproject/faultmanagement/impl/AlarmManagerTest.java
0 → 100644
| 1 | +/* | ||
| 2 | + * Copyright 2015-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 | +package org.onosproject.faultmanagement.impl; | ||
| 17 | + | ||
| 18 | +import com.google.common.collect.ImmutableSet; | ||
| 19 | +import com.google.common.collect.Lists; | ||
| 20 | +import org.junit.Before; | ||
| 21 | +import org.junit.Rule; | ||
| 22 | +import org.junit.Test; | ||
| 23 | +import org.junit.rules.ExpectedException; | ||
| 24 | +import org.onlab.junit.TestTools; | ||
| 25 | +import org.onlab.junit.TestUtils; | ||
| 26 | +import org.onlab.util.ItemNotFoundException; | ||
| 27 | +import org.onosproject.common.event.impl.TestEventDispatcher; | ||
| 28 | +import org.onosproject.event.Event; | ||
| 29 | +import org.onosproject.incubator.net.faultmanagement.alarm.Alarm; | ||
| 30 | +import org.onosproject.incubator.net.faultmanagement.alarm.AlarmEntityId; | ||
| 31 | +import org.onosproject.incubator.net.faultmanagement.alarm.AlarmEvent; | ||
| 32 | +import org.onosproject.incubator.net.faultmanagement.alarm.AlarmId; | ||
| 33 | +import org.onosproject.incubator.net.faultmanagement.alarm.AlarmListener; | ||
| 34 | +import org.onosproject.incubator.net.faultmanagement.alarm.DefaultAlarm; | ||
| 35 | +import org.onosproject.net.DeviceId; | ||
| 36 | +import org.onosproject.net.NetTestTools; | ||
| 37 | +import org.onosproject.store.service.TestStorageService; | ||
| 38 | + | ||
| 39 | +import java.util.Collections; | ||
| 40 | +import java.util.HashMap; | ||
| 41 | +import java.util.List; | ||
| 42 | +import java.util.Map; | ||
| 43 | + | ||
| 44 | +import static junit.framework.TestCase.assertFalse; | ||
| 45 | +import static org.junit.Assert.assertEquals; | ||
| 46 | +import static org.junit.Assert.assertTrue; | ||
| 47 | +import static org.onosproject.incubator.net.faultmanagement.alarm.Alarm.SeverityLevel.CLEARED; | ||
| 48 | +import static org.onosproject.incubator.net.faultmanagement.alarm.Alarm.SeverityLevel.CRITICAL; | ||
| 49 | + | ||
| 50 | +/** | ||
| 51 | + * Alarm manager test suite. | ||
| 52 | + */ | ||
| 53 | +public class AlarmManagerTest { | ||
| 54 | + | ||
| 55 | + private static final DeviceId DEVICE_ID = DeviceId.deviceId("foo:bar"); | ||
| 56 | + private static final DefaultAlarm ALARM_A = new DefaultAlarm.Builder( | ||
| 57 | + DEVICE_ID, "aaa", Alarm.SeverityLevel.CRITICAL, 0).build(); | ||
| 58 | + | ||
| 59 | + private static final DefaultAlarm ALARM_A_WITHSRC = new DefaultAlarm.Builder( | ||
| 60 | + ALARM_A).forSource(AlarmEntityId.alarmEntityId("port:foo")).build(); | ||
| 61 | + | ||
| 62 | + private static final DefaultAlarm ALARM_B = new DefaultAlarm.Builder( | ||
| 63 | + DEVICE_ID, "bbb", Alarm.SeverityLevel.CRITICAL, 0).build(); | ||
| 64 | + | ||
| 65 | + private AlarmManager manager; | ||
| 66 | + private DistributedAlarmStore alarmStore; | ||
| 67 | + protected TestListener listener = new TestListener(); | ||
| 68 | + | ||
| 69 | + @Rule | ||
| 70 | + public final ExpectedException exception = ExpectedException.none(); | ||
| 71 | + | ||
| 72 | + @Before | ||
| 73 | + public void setUp() throws Exception { | ||
| 74 | + alarmStore = new DistributedAlarmStore(); | ||
| 75 | + TestUtils.setField(alarmStore, "storageService", new TestStorageService()); | ||
| 76 | + alarmStore.activate(); | ||
| 77 | + manager = new AlarmManager(); | ||
| 78 | + manager.addListener(listener); | ||
| 79 | + NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher()); | ||
| 80 | + manager.store = alarmStore; | ||
| 81 | + manager.activate(); | ||
| 82 | + } | ||
| 83 | + | ||
| 84 | + @Test | ||
| 85 | + public void deactivate() throws Exception { | ||
| 86 | + manager.updateAlarms(DEVICE_ID, ImmutableSet.of(ALARM_B, ALARM_A)); | ||
| 87 | + verifyGettingSetsOfAlarms(manager, 2, 2); | ||
| 88 | + alarmStore.deactivate(); | ||
| 89 | + manager.removeListener(listener); | ||
| 90 | + manager.deactivate(); | ||
| 91 | + NetTestTools.injectEventDispatcher(manager, null); | ||
| 92 | + assertFalse("Store should not have delegate", alarmStore.hasDelegate()); | ||
| 93 | + } | ||
| 94 | + | ||
| 95 | + @Test | ||
| 96 | + public void testGettersWhenNoAlarms() { | ||
| 97 | + | ||
| 98 | + assertTrue("No alarms should be present", manager.getAlarms().isEmpty()); | ||
| 99 | + assertTrue("No active alarms should be present", manager.getActiveAlarms().isEmpty()); | ||
| 100 | + assertTrue("The map should be empty per unknown device", | ||
| 101 | + manager.getAlarmCounts(DeviceId.NONE).keySet().isEmpty()); | ||
| 102 | + assertTrue("The counts should be empty", manager.getAlarmCounts().keySet().isEmpty()); | ||
| 103 | + | ||
| 104 | + assertEquals("Incorrect number of alarms for unknown device", | ||
| 105 | + 0, manager.getAlarms(DeviceId.NONE).size()); | ||
| 106 | + assertEquals("Incorrect number of major alarms for unknown device", | ||
| 107 | + 0, manager.getAlarms(Alarm.SeverityLevel.MAJOR).size()); | ||
| 108 | + | ||
| 109 | + exception.expect(NullPointerException.class); | ||
| 110 | + manager.getAlarm(null); | ||
| 111 | + | ||
| 112 | + exception.expect(ItemNotFoundException.class); | ||
| 113 | + manager.getAlarm(AlarmId.alarmId(1)); | ||
| 114 | + } | ||
| 115 | + | ||
| 116 | + @Test | ||
| 117 | + public void testAlarmUpdates() throws InterruptedException { | ||
| 118 | + | ||
| 119 | + assertTrue("No alarms should be present", manager.getAlarms().isEmpty()); | ||
| 120 | + manager.updateAlarms(DEVICE_ID, ImmutableSet.of()); | ||
| 121 | + assertTrue("No alarms should be present", manager.getAlarms().isEmpty()); | ||
| 122 | + Map<Alarm.SeverityLevel, Long> zeroAlarms = new CountsMapBuilder().create(); | ||
| 123 | + assertEquals("No alarms count should be present", zeroAlarms, manager.getAlarmCounts()); | ||
| 124 | + assertEquals("No alarms count should be present", zeroAlarms, manager.getAlarmCounts(DEVICE_ID)); | ||
| 125 | + | ||
| 126 | + manager.updateAlarms(DEVICE_ID, ImmutableSet.of(ALARM_B, ALARM_A)); | ||
| 127 | + verifyGettingSetsOfAlarms(manager, 2, 2); | ||
| 128 | + validateEvents(AlarmEvent.Type.CREATED, AlarmEvent.Type.CREATED); | ||
| 129 | + Map<Alarm.SeverityLevel, Long> critical2 = new CountsMapBuilder().with(CRITICAL, 2L).create(); | ||
| 130 | + assertEquals("A critical should be present", critical2, manager.getAlarmCounts()); | ||
| 131 | + assertEquals("A critical should be present", critical2, manager.getAlarmCounts(DEVICE_ID)); | ||
| 132 | + | ||
| 133 | + manager.updateAlarms(DEVICE_ID, ImmutableSet.of(ALARM_A)); | ||
| 134 | + verifyGettingSetsOfAlarms(manager, 2, 1); | ||
| 135 | + validateEvents(AlarmEvent.Type.CREATED); | ||
| 136 | + Map<Alarm.SeverityLevel, Long> critical1cleared1 = | ||
| 137 | + new CountsMapBuilder().with(CRITICAL, 1L).with(CLEARED, 1L).create(); | ||
| 138 | + assertEquals("A critical should be present and cleared", critical1cleared1, | ||
| 139 | + manager.getAlarmCounts()); | ||
| 140 | + assertEquals("A critical should be present and cleared", critical1cleared1, | ||
| 141 | + manager.getAlarmCounts(DEVICE_ID)); | ||
| 142 | + | ||
| 143 | + // No change map when same alarms sent | ||
| 144 | + manager.updateAlarms(DEVICE_ID, ImmutableSet.of(ALARM_A)); | ||
| 145 | + verifyGettingSetsOfAlarms(manager, 2, 1); | ||
| 146 | + validateEvents(); | ||
| 147 | + assertEquals("Map should not be changed for same alarm", critical1cleared1, | ||
| 148 | + manager.getAlarmCounts()); | ||
| 149 | + assertEquals("Map should not be changed for same alarm", critical1cleared1, | ||
| 150 | + manager.getAlarmCounts(DEVICE_ID)); | ||
| 151 | + | ||
| 152 | + manager.updateAlarms(DEVICE_ID, ImmutableSet.of(ALARM_A, ALARM_A_WITHSRC)); | ||
| 153 | + verifyGettingSetsOfAlarms(manager, 3, 2); | ||
| 154 | + validateEvents(AlarmEvent.Type.CREATED); | ||
| 155 | + Map<Alarm.SeverityLevel, Long> critical2cleared1 = | ||
| 156 | + new CountsMapBuilder().with(CRITICAL, 2L).with(CLEARED, 1L).create(); | ||
| 157 | + assertEquals("A critical should be present", critical2cleared1, manager.getAlarmCounts()); | ||
| 158 | + assertEquals("A critical should be present", critical2cleared1, manager.getAlarmCounts(DEVICE_ID)); | ||
| 159 | + | ||
| 160 | + manager.updateAlarms(DEVICE_ID, ImmutableSet.of()); | ||
| 161 | + verifyGettingSetsOfAlarms(manager, 3, 0); | ||
| 162 | + validateEvents(AlarmEvent.Type.CREATED, AlarmEvent.Type.CREATED); | ||
| 163 | + assertEquals(new CountsMapBuilder().with(CLEARED, 3L).create(), manager.getAlarmCounts(DEVICE_ID)); | ||
| 164 | + | ||
| 165 | + assertEquals("The counts should be empty for unknown devices", zeroAlarms, | ||
| 166 | + manager.getAlarmCounts(DeviceId.NONE)); | ||
| 167 | + assertEquals("The counts should be empty for unknown devices", zeroAlarms, | ||
| 168 | + manager.getAlarmCounts(DeviceId.deviceId("junk:junk"))); | ||
| 169 | + | ||
| 170 | + } | ||
| 171 | + | ||
| 172 | + private void verifyGettingSetsOfAlarms(AlarmManager am, int expectedTotal, int expectedActive) { | ||
| 173 | + assertEquals("Incorrect total alarms", expectedTotal, am.getAlarms().size()); | ||
| 174 | + assertEquals("Incorrect active alarms count", expectedActive, am.getActiveAlarms().size()); | ||
| 175 | + } | ||
| 176 | + | ||
| 177 | + /** | ||
| 178 | + * Method to validate that actual versus expected device key events were | ||
| 179 | + * received correctly. | ||
| 180 | + * | ||
| 181 | + * @param types expected device key events. | ||
| 182 | + */ | ||
| 183 | + private void validateEvents(Enum... types) { | ||
| 184 | + TestTools.assertAfter(100, () -> { | ||
| 185 | + int i = 0; | ||
| 186 | + assertEquals("wrong events received", types.length, listener.events.size()); | ||
| 187 | + for (Event event : listener.events) { | ||
| 188 | + assertEquals("incorrect event type", types[i], event.type()); | ||
| 189 | + i++; | ||
| 190 | + } | ||
| 191 | + listener.events.clear(); | ||
| 192 | + }); | ||
| 193 | + } | ||
| 194 | + | ||
| 195 | + private static class CountsMapBuilder { | ||
| 196 | + | ||
| 197 | + private final Map<Alarm.SeverityLevel, Long> map = new HashMap<>(); | ||
| 198 | + | ||
| 199 | + public CountsMapBuilder with(Alarm.SeverityLevel sev, Long count) { | ||
| 200 | + map.put(sev, count); | ||
| 201 | + return this; | ||
| 202 | + } | ||
| 203 | + | ||
| 204 | + public Map<Alarm.SeverityLevel, Long> create() { | ||
| 205 | + return Collections.unmodifiableMap(map); | ||
| 206 | + } | ||
| 207 | + } | ||
| 208 | + | ||
| 209 | + | ||
| 210 | + /** | ||
| 211 | + * Test listener class to receive alarm events. | ||
| 212 | + */ | ||
| 213 | + private static class TestListener implements AlarmListener { | ||
| 214 | + | ||
| 215 | + protected List<AlarmEvent> events = Lists.newArrayList(); | ||
| 216 | + | ||
| 217 | + @Override | ||
| 218 | + public void event(AlarmEvent event) { | ||
| 219 | + events.add(event); | ||
| 220 | + } | ||
| 221 | + | ||
| 222 | + } | ||
| 223 | +} |
| 1 | -/* | ||
| 2 | - * Copyright 2015-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 | -package org.onosproject.faultmanagement.impl; | ||
| 17 | - | ||
| 18 | -import com.google.common.collect.ImmutableSet; | ||
| 19 | -import org.junit.Before; | ||
| 20 | -import org.junit.Rule; | ||
| 21 | -import org.junit.Test; | ||
| 22 | -import org.junit.rules.ExpectedException; | ||
| 23 | -import org.onlab.util.ItemNotFoundException; | ||
| 24 | -import org.onosproject.incubator.net.faultmanagement.alarm.Alarm; | ||
| 25 | -import org.onosproject.incubator.net.faultmanagement.alarm.AlarmEntityId; | ||
| 26 | -import org.onosproject.incubator.net.faultmanagement.alarm.AlarmId; | ||
| 27 | -import org.onosproject.incubator.net.faultmanagement.alarm.DefaultAlarm; | ||
| 28 | -import org.onosproject.net.DeviceId; | ||
| 29 | - | ||
| 30 | -import java.util.Collections; | ||
| 31 | -import java.util.HashMap; | ||
| 32 | -import java.util.Map; | ||
| 33 | - | ||
| 34 | -import static org.junit.Assert.assertEquals; | ||
| 35 | -import static org.junit.Assert.assertTrue; | ||
| 36 | -import static org.onosproject.incubator.net.faultmanagement.alarm.Alarm.SeverityLevel.CLEARED; | ||
| 37 | -import static org.onosproject.incubator.net.faultmanagement.alarm.Alarm.SeverityLevel.CRITICAL; | ||
| 38 | - | ||
| 39 | -/** | ||
| 40 | - * Alarm manager test suite. | ||
| 41 | - */ | ||
| 42 | -public class AlarmsManagerTest { | ||
| 43 | - | ||
| 44 | - private static final DeviceId DEVICE_ID = DeviceId.deviceId("foo:bar"); | ||
| 45 | - private static final DefaultAlarm ALARM_A = new DefaultAlarm.Builder( | ||
| 46 | - DEVICE_ID, "aaa", Alarm.SeverityLevel.CRITICAL, 0).build(); | ||
| 47 | - | ||
| 48 | - private static final DefaultAlarm ALARM_A_WITHSRC = new DefaultAlarm.Builder( | ||
| 49 | - ALARM_A).forSource(AlarmEntityId.alarmEntityId("port:foo")).build(); | ||
| 50 | - | ||
| 51 | - private static final DefaultAlarm ALARM_B = new DefaultAlarm.Builder( | ||
| 52 | - DEVICE_ID, "bbb", Alarm.SeverityLevel.CRITICAL, 0).build(); | ||
| 53 | - | ||
| 54 | - private AlarmsManager am; | ||
| 55 | - | ||
| 56 | - @Rule | ||
| 57 | - public final ExpectedException exception = ExpectedException.none(); | ||
| 58 | - | ||
| 59 | - @Before | ||
| 60 | - public void setUp() throws Exception { | ||
| 61 | - am = new AlarmsManager(); | ||
| 62 | - } | ||
| 63 | - | ||
| 64 | - @Test | ||
| 65 | - public void deactivate() throws Exception { | ||
| 66 | - am.updateAlarms(DEVICE_ID, ImmutableSet.of(ALARM_B, ALARM_A)); | ||
| 67 | - verifyGettingSetsOfAlarms(am, 2, 2); | ||
| 68 | - am.deactivate(null); | ||
| 69 | - assertEquals("Alarms should be purged", 0, am.alarms.size()); | ||
| 70 | - } | ||
| 71 | - | ||
| 72 | - @Test | ||
| 73 | - public void testGettersWhenNoAlarms() { | ||
| 74 | - | ||
| 75 | - assertTrue("No alarms should be present", am.getAlarms().isEmpty()); | ||
| 76 | - assertTrue("No active alarms should be present", am.getActiveAlarms().isEmpty()); | ||
| 77 | - assertTrue("The map should be empty per unknown device", | ||
| 78 | - am.getAlarmCounts(DeviceId.NONE).keySet().isEmpty()); | ||
| 79 | - assertTrue("The counts should be empty", am.getAlarmCounts().keySet().isEmpty()); | ||
| 80 | - | ||
| 81 | - assertEquals("Incorrect number of alarms for unknown device", | ||
| 82 | - 0, am.getAlarms(DeviceId.NONE).size()); | ||
| 83 | - assertEquals("Incorrect number of major alarms for unknown device", | ||
| 84 | - 0, am.getAlarms(Alarm.SeverityLevel.MAJOR).size()); | ||
| 85 | - | ||
| 86 | - exception.expect(NullPointerException.class); | ||
| 87 | - am.getAlarm(null); | ||
| 88 | - | ||
| 89 | - exception.expect(ItemNotFoundException.class); | ||
| 90 | - am.getAlarm(AlarmId.alarmId(1)); | ||
| 91 | - } | ||
| 92 | - | ||
| 93 | - @Test | ||
| 94 | - public void testAlarmUpdates() { | ||
| 95 | - | ||
| 96 | - assertTrue("No alarms should be present", am.getAlarms().isEmpty()); | ||
| 97 | - am.updateAlarms(DEVICE_ID, ImmutableSet.of()); | ||
| 98 | - assertTrue("No alarms should be present", am.getAlarms().isEmpty()); | ||
| 99 | - Map<Alarm.SeverityLevel, Long> zeroAlarms = new CountsMapBuilder().create(); | ||
| 100 | - assertEquals("No alarms count should be present", zeroAlarms, am.getAlarmCounts()); | ||
| 101 | - assertEquals("No alarms count should be present", zeroAlarms, am.getAlarmCounts(DEVICE_ID)); | ||
| 102 | - | ||
| 103 | - am.updateAlarms(DEVICE_ID, ImmutableSet.of(ALARM_B, ALARM_A)); | ||
| 104 | - verifyGettingSetsOfAlarms(am, 2, 2); | ||
| 105 | - Map<Alarm.SeverityLevel, Long> critical2 = new CountsMapBuilder().with(CRITICAL, 2L).create(); | ||
| 106 | - assertEquals("A critical should be present", critical2, am.getAlarmCounts()); | ||
| 107 | - assertEquals("A critical should be present", critical2, am.getAlarmCounts(DEVICE_ID)); | ||
| 108 | - | ||
| 109 | - am.updateAlarms(DEVICE_ID, ImmutableSet.of(ALARM_A)); | ||
| 110 | - verifyGettingSetsOfAlarms(am, 2, 1); | ||
| 111 | - Map<Alarm.SeverityLevel, Long> critical1cleared1 = | ||
| 112 | - new CountsMapBuilder().with(CRITICAL, 1L).with(CLEARED, 1L).create(); | ||
| 113 | - assertEquals("A critical should be present and cleared", critical1cleared1, | ||
| 114 | - am.getAlarmCounts()); | ||
| 115 | - assertEquals("A critical should be present and cleared", critical1cleared1, | ||
| 116 | - am.getAlarmCounts(DEVICE_ID)); | ||
| 117 | - | ||
| 118 | - // No change map when same alarms sent | ||
| 119 | - am.updateAlarms(DEVICE_ID, ImmutableSet.of(ALARM_A)); | ||
| 120 | - verifyGettingSetsOfAlarms(am, 2, 1); | ||
| 121 | - assertEquals("Map should not be changed for same alarm", critical1cleared1, | ||
| 122 | - am.getAlarmCounts()); | ||
| 123 | - assertEquals("Map should not be changed for same alarm", critical1cleared1, | ||
| 124 | - am.getAlarmCounts(DEVICE_ID)); | ||
| 125 | - | ||
| 126 | - am.updateAlarms(DEVICE_ID, ImmutableSet.of(ALARM_A, ALARM_A_WITHSRC)); | ||
| 127 | - verifyGettingSetsOfAlarms(am, 3, 2); | ||
| 128 | - Map<Alarm.SeverityLevel, Long> critical2cleared1 = | ||
| 129 | - new CountsMapBuilder().with(CRITICAL, 2L).with(CLEARED, 1L).create(); | ||
| 130 | - assertEquals("A critical should be present", critical2cleared1, am.getAlarmCounts()); | ||
| 131 | - assertEquals("A critical should be present", critical2cleared1, am.getAlarmCounts(DEVICE_ID)); | ||
| 132 | - | ||
| 133 | - am.updateAlarms(DEVICE_ID, ImmutableSet.of()); | ||
| 134 | - verifyGettingSetsOfAlarms(am, 3, 0); | ||
| 135 | - assertEquals(new CountsMapBuilder().with(CLEARED, 3L).create(), am.getAlarmCounts(DEVICE_ID)); | ||
| 136 | - | ||
| 137 | - assertEquals("The counts should be empty for unknown devices", zeroAlarms, | ||
| 138 | - am.getAlarmCounts(DeviceId.NONE)); | ||
| 139 | - assertEquals("The counts should be empty for unknown devices", zeroAlarms, | ||
| 140 | - am.getAlarmCounts(DeviceId.deviceId("junk:junk"))); | ||
| 141 | - | ||
| 142 | - } | ||
| 143 | - | ||
| 144 | - private void verifyGettingSetsOfAlarms(AlarmsManager am, int expectedTotal, int expectedActive) { | ||
| 145 | - assertEquals("Incorrect total alarms", expectedTotal, am.getAlarms().size()); | ||
| 146 | - assertEquals("Incorrect active alarms count", expectedActive, am.getActiveAlarms().size()); | ||
| 147 | - } | ||
| 148 | - | ||
| 149 | - private static class CountsMapBuilder { | ||
| 150 | - | ||
| 151 | - private final Map<Alarm.SeverityLevel, Long> map = new HashMap<>(); | ||
| 152 | - | ||
| 153 | - public CountsMapBuilder with(Alarm.SeverityLevel sev, Long count) { | ||
| 154 | - map.put(sev, count); | ||
| 155 | - return this; | ||
| 156 | - } | ||
| 157 | - | ||
| 158 | - public Map<Alarm.SeverityLevel, Long> create() { | ||
| 159 | - return Collections.unmodifiableMap(map); | ||
| 160 | - } | ||
| 161 | - } | ||
| 162 | - | ||
| 163 | -} |
| 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.faultmanagement.impl; | ||
| 18 | + | ||
| 19 | +import org.junit.After; | ||
| 20 | +import org.junit.Before; | ||
| 21 | +import org.junit.Test; | ||
| 22 | +import org.onosproject.incubator.net.faultmanagement.alarm.Alarm; | ||
| 23 | +import org.onosproject.incubator.net.faultmanagement.alarm.DefaultAlarm; | ||
| 24 | +import org.onosproject.net.DeviceId; | ||
| 25 | +import org.onosproject.store.service.TestStorageService; | ||
| 26 | + | ||
| 27 | +import static org.junit.Assert.assertFalse; | ||
| 28 | +import static org.junit.Assert.assertTrue; | ||
| 29 | + | ||
| 30 | +/** | ||
| 31 | + * Distributed Alarm store test suite. | ||
| 32 | + */ | ||
| 33 | +public class DistributedAlarmStoreTest { | ||
| 34 | + private DistributedAlarmStore alarmStore; | ||
| 35 | + private static final DeviceId DEVICE_ID = DeviceId.deviceId("foo:bar"); | ||
| 36 | + private static final DefaultAlarm ALARM_A = new DefaultAlarm.Builder( | ||
| 37 | + DEVICE_ID, "aaa", Alarm.SeverityLevel.CRITICAL, 0).build(); | ||
| 38 | + | ||
| 39 | + /** | ||
| 40 | + * Sets up the device key store and the storage service test harness. | ||
| 41 | + */ | ||
| 42 | + @Before | ||
| 43 | + public void setUp() { | ||
| 44 | + alarmStore = new DistributedAlarmStore(); | ||
| 45 | + alarmStore.storageService = new TestStorageService(); | ||
| 46 | + alarmStore.setDelegate(event -> { | ||
| 47 | + }); | ||
| 48 | + alarmStore.activate(); | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + /** | ||
| 52 | + * Tears down the device key store. | ||
| 53 | + */ | ||
| 54 | + @After | ||
| 55 | + public void tearDown() { | ||
| 56 | + alarmStore.deactivate(); | ||
| 57 | + } | ||
| 58 | + | ||
| 59 | + /** | ||
| 60 | + * Tests adding, removing and getting. | ||
| 61 | + */ | ||
| 62 | + @Test | ||
| 63 | + public void basics() { | ||
| 64 | + alarmStore.setAlarm(ALARM_A); | ||
| 65 | + assertTrue("There should be one alarm in the set.", | ||
| 66 | + alarmStore.getAlarms().contains(ALARM_A)); | ||
| 67 | + assertTrue("The same alarm should be returned.", | ||
| 68 | + alarmStore.getAlarms(DEVICE_ID).contains(ALARM_A)); | ||
| 69 | + assertTrue("The alarm should be the same", | ||
| 70 | + alarmStore.getAlarm(ALARM_A.id()).equals(ALARM_A)); | ||
| 71 | + alarmStore.removeAlarm(ALARM_A.id()); | ||
| 72 | + assertFalse("There should be no alarm in the set.", | ||
| 73 | + alarmStore.getAlarms().contains(ALARM_A)); | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | +} |
| ... | @@ -15,50 +15,13 @@ | ... | @@ -15,50 +15,13 @@ |
| 15 | */ | 15 | */ |
| 16 | package org.onosproject.incubator.net.faultmanagement.alarm; | 16 | package org.onosproject.incubator.net.faultmanagement.alarm; |
| 17 | 17 | ||
| 18 | -import java.util.Set; | ||
| 19 | import org.onosproject.event.AbstractEvent; | 18 | import org.onosproject.event.AbstractEvent; |
| 20 | -import org.onosproject.net.DeviceId; | ||
| 21 | 19 | ||
| 22 | /** | 20 | /** |
| 23 | - * Entity that represents Alarm events. Note: although the event will itself have a time, consumers may be more | 21 | + * Entity that represents Alarm events. Note: although the event will itself have a time, |
| 24 | - * interested in the times embedded in the alarms themselves. | 22 | + * consumers may be more interested in the times embedded in the alarms themselves. |
| 25 | - * | ||
| 26 | */ | 23 | */ |
| 27 | -public class AlarmEvent extends AbstractEvent<AlarmEvent.Type, Set<Alarm>> { | 24 | +public class AlarmEvent extends AbstractEvent<AlarmEvent.Type, Alarm> { |
| 28 | - | ||
| 29 | - private final DeviceId deviceRefreshed; | ||
| 30 | - | ||
| 31 | - /** | ||
| 32 | - * Creates an event due to one or more notification. | ||
| 33 | - * | ||
| 34 | - * @param alarms the set one or more of alarms. | ||
| 35 | - */ | ||
| 36 | - public AlarmEvent(Set<Alarm> alarms) { | ||
| 37 | - super(Type.NOTIFICATION, alarms); | ||
| 38 | - deviceRefreshed = null; | ||
| 39 | - } | ||
| 40 | - | ||
| 41 | - /** | ||
| 42 | - * Creates an event due to alarm discovery for a device. | ||
| 43 | - * | ||
| 44 | - * @param alarms the set of alarms. | ||
| 45 | - * @param deviceRefreshed if of refreshed device, populated after a de-discovery | ||
| 46 | - */ | ||
| 47 | - public AlarmEvent(Set<Alarm> alarms, | ||
| 48 | - DeviceId deviceRefreshed) { | ||
| 49 | - super(Type.DEVICE_DISCOVERY, alarms); | ||
| 50 | - this.deviceRefreshed = deviceRefreshed; | ||
| 51 | - | ||
| 52 | - } | ||
| 53 | - | ||
| 54 | - /** | ||
| 55 | - * Gets which device was refreshed. | ||
| 56 | - * | ||
| 57 | - * @return the refreshed device, or null if event related to a asynchronous notification(s) | ||
| 58 | - */ | ||
| 59 | - public DeviceId getDeviceRefreshed() { | ||
| 60 | - return deviceRefreshed; | ||
| 61 | - } | ||
| 62 | 25 | ||
| 63 | /** | 26 | /** |
| 64 | * Type of alarm event. | 27 | * Type of alarm event. |
| ... | @@ -66,13 +29,22 @@ public class AlarmEvent extends AbstractEvent<AlarmEvent.Type, Set<Alarm>> { | ... | @@ -66,13 +29,22 @@ public class AlarmEvent extends AbstractEvent<AlarmEvent.Type, Set<Alarm>> { |
| 66 | public enum Type { | 29 | public enum Type { |
| 67 | 30 | ||
| 68 | /** | 31 | /** |
| 69 | - * Individual alarm(s) updated. | 32 | + * Individual alarm updated. |
| 70 | */ | 33 | */ |
| 71 | - NOTIFICATION, | 34 | + CREATED, |
| 72 | /** | 35 | /** |
| 73 | * Alarm set updated for a given device. | 36 | * Alarm set updated for a given device. |
| 74 | */ | 37 | */ |
| 75 | - DEVICE_DISCOVERY, | 38 | + REMOVED, |
| 39 | + } | ||
| 40 | + | ||
| 41 | + /** | ||
| 42 | + * Creates an event due to one alarm. | ||
| 43 | + * | ||
| 44 | + * @param alarm the alarm related to the event. | ||
| 45 | + */ | ||
| 46 | + public AlarmEvent(AlarmEvent.Type type, Alarm alarm) { | ||
| 47 | + super(type, alarm); | ||
| 76 | } | 48 | } |
| 77 | 49 | ||
| 78 | } | 50 | } | ... | ... |
incubator/api/src/main/java/org/onosproject/incubator/net/faultmanagement/alarm/AlarmListener.java
0 → 100644
| 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.event.EventListener; | ||
| 20 | + | ||
| 21 | +/** | ||
| 22 | + * Entity capable of receiving alarm related events. | ||
| 23 | + */ | ||
| 24 | +public interface AlarmListener extends EventListener<AlarmEvent> { | ||
| 25 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| ... | @@ -16,7 +16,6 @@ | ... | @@ -16,7 +16,6 @@ |
| 16 | package org.onosproject.incubator.net.faultmanagement.alarm; | 16 | package org.onosproject.incubator.net.faultmanagement.alarm; |
| 17 | 17 | ||
| 18 | 18 | ||
| 19 | -import com.google.common.annotations.Beta; | ||
| 20 | import org.onosproject.net.DeviceId; | 19 | import org.onosproject.net.DeviceId; |
| 21 | import org.onosproject.net.provider.ProviderService; | 20 | import org.onosproject.net.provider.ProviderService; |
| 22 | 21 | ||
| ... | @@ -25,7 +24,7 @@ import java.util.Collection; | ... | @@ -25,7 +24,7 @@ import java.util.Collection; |
| 25 | /** | 24 | /** |
| 26 | * The interface Alarm provider service. | 25 | * The interface Alarm provider service. |
| 27 | */ | 26 | */ |
| 28 | -@Beta | 27 | + |
| 29 | public interface AlarmProviderService extends ProviderService<AlarmProvider> { | 28 | public interface AlarmProviderService extends ProviderService<AlarmProvider> { |
| 30 | 29 | ||
| 31 | /** | 30 | /** | ... | ... |
| ... | @@ -15,28 +15,26 @@ | ... | @@ -15,28 +15,26 @@ |
| 15 | */ | 15 | */ |
| 16 | package org.onosproject.incubator.net.faultmanagement.alarm; | 16 | package org.onosproject.incubator.net.faultmanagement.alarm; |
| 17 | 17 | ||
| 18 | -import com.google.common.annotations.Beta; | 18 | +import org.onosproject.event.ListenerService; |
| 19 | -import java.util.Map; | ||
| 20 | - | ||
| 21 | -import java.util.Set; | ||
| 22 | import org.onosproject.net.ConnectPoint; | 19 | import org.onosproject.net.ConnectPoint; |
| 23 | import org.onosproject.net.DeviceId; | 20 | import org.onosproject.net.DeviceId; |
| 24 | 21 | ||
| 22 | +import java.util.Map; | ||
| 23 | +import java.util.Set; | ||
| 24 | + | ||
| 25 | /** | 25 | /** |
| 26 | * Service for interacting with the alarm handling of devices. Unless stated otherwise, getter methods | 26 | * Service for interacting with the alarm handling of devices. Unless stated otherwise, getter methods |
| 27 | * return active AND recently-cleared alarms. | 27 | * return active AND recently-cleared alarms. |
| 28 | */ | 28 | */ |
| 29 | -@Beta | 29 | +public interface AlarmService extends ListenerService<AlarmEvent, AlarmListener> { |
| 30 | -public interface AlarmService { | ||
| 31 | 30 | ||
| 32 | /** | 31 | /** |
| 33 | * Update book-keeping (ie administrative) fields for the alarm matching the specified identifier. | 32 | * Update book-keeping (ie administrative) fields for the alarm matching the specified identifier. |
| 34 | * | 33 | * |
| 35 | - * @param id alarm identifier | 34 | + * @param id alarm identifier |
| 36 | * @param isAcknowledged new acknowledged state | 35 | * @param isAcknowledged new acknowledged state |
| 37 | - * @param assignedUser new assigned user, null clear | 36 | + * @param assignedUser new assigned user, null clear |
| 38 | * @return updated alarm (including any recent device-derived changes) | 37 | * @return updated alarm (including any recent device-derived changes) |
| 39 | - * | ||
| 40 | */ | 38 | */ |
| 41 | Alarm updateBookkeepingFields(AlarmId id, boolean isAcknowledged, String assignedUser); | 39 | Alarm updateBookkeepingFields(AlarmId id, boolean isAcknowledged, String assignedUser); |
| 42 | 40 | ||
| ... | @@ -98,7 +96,7 @@ public interface AlarmService { | ... | @@ -98,7 +96,7 @@ public interface AlarmService { |
| 98 | * Returns the alarm for a given device and source. | 96 | * Returns the alarm for a given device and source. |
| 99 | * | 97 | * |
| 100 | * @param deviceId the device | 98 | * @param deviceId the device |
| 101 | - * @param source the source within the device | 99 | + * @param source the source within the device |
| 102 | * @return set of alarms; empty set if no alarms | 100 | * @return set of alarms; empty set if no alarms |
| 103 | */ | 101 | */ |
| 104 | Set<Alarm> getAlarms(DeviceId deviceId, AlarmEntityId source); | 102 | Set<Alarm> getAlarms(DeviceId deviceId, AlarmEntityId source); |
| ... | @@ -116,7 +114,7 @@ public interface AlarmService { | ... | @@ -116,7 +114,7 @@ public interface AlarmService { |
| 116 | * Returns the alarm affecting a given flow. | 114 | * Returns the alarm affecting a given flow. |
| 117 | * | 115 | * |
| 118 | * @param deviceId the device | 116 | * @param deviceId the device |
| 119 | - * @param flowId the flow | 117 | + * @param flowId the flow |
| 120 | * @return set of alarms; empty set if no alarms | 118 | * @return set of alarms; empty set if no alarms |
| 121 | */ | 119 | */ |
| 122 | Set<Alarm> getAlarmsForFlow(DeviceId deviceId, long flowId); | 120 | Set<Alarm> getAlarmsForFlow(DeviceId deviceId, long flowId); | ... | ... |
| ... | @@ -25,6 +25,7 @@ import static com.google.common.base.Preconditions.checkNotNull; | ... | @@ -25,6 +25,7 @@ import static com.google.common.base.Preconditions.checkNotNull; |
| 25 | /** | 25 | /** |
| 26 | * Default implementation of an alarm. | 26 | * Default implementation of an alarm. |
| 27 | */ | 27 | */ |
| 28 | +//TODO simpler creation and updating. | ||
| 28 | public final class DefaultAlarm implements Alarm { | 29 | public final class DefaultAlarm implements Alarm { |
| 29 | 30 | ||
| 30 | private final AlarmId id; | 31 | private final AlarmId id; |
| ... | @@ -41,34 +42,50 @@ public final class DefaultAlarm implements Alarm { | ... | @@ -41,34 +42,50 @@ public final class DefaultAlarm implements Alarm { |
| 41 | private final boolean isManuallyClearable; | 42 | private final boolean isManuallyClearable; |
| 42 | private final String assignedUser; | 43 | private final String assignedUser; |
| 43 | 44 | ||
| 45 | + //Only for Kryo | ||
| 46 | + DefaultAlarm() { | ||
| 47 | + id = null; | ||
| 48 | + deviceId = null; | ||
| 49 | + description = null; | ||
| 50 | + source = null; | ||
| 51 | + timeRaised = -1; | ||
| 52 | + timeUpdated = -1; | ||
| 53 | + timeCleared = null; | ||
| 54 | + severity = null; | ||
| 55 | + isServiceAffecting = false; | ||
| 56 | + isAcknowledged = false; | ||
| 57 | + isManuallyClearable = false; | ||
| 58 | + assignedUser = null; | ||
| 59 | + } | ||
| 60 | + | ||
| 44 | /** | 61 | /** |
| 45 | * Instantiates a new Default alarm. | 62 | * Instantiates a new Default alarm. |
| 46 | * | 63 | * |
| 47 | - * @param id the id | 64 | + * @param id the id |
| 48 | - * @param deviceId the device id | 65 | + * @param deviceId the device id |
| 49 | - * @param description the description | 66 | + * @param description the description |
| 50 | - * @param source the source, null indicates none. | 67 | + * @param source the source, null indicates none. |
| 51 | - * @param timeRaised the time raised. | 68 | + * @param timeRaised the time raised. |
| 52 | - * @param timeUpdated the time last updated. | 69 | + * @param timeUpdated the time last updated. |
| 53 | - * @param timeCleared the time cleared, null indicates uncleared. | 70 | + * @param timeCleared the time cleared, null indicates uncleared. |
| 54 | - * @param severity the severity | 71 | + * @param severity the severity |
| 55 | - * @param isServiceAffecting the service affecting | 72 | + * @param isServiceAffecting the service affecting |
| 56 | - * @param isAcknowledged the acknowledged | 73 | + * @param isAcknowledged the acknowledged |
| 57 | * @param isManuallyClearable the manually clearable | 74 | * @param isManuallyClearable the manually clearable |
| 58 | - * @param assignedUser the assigned user, `null` indicates none. | 75 | + * @param assignedUser the assigned user, `null` indicates none. |
| 59 | */ | 76 | */ |
| 60 | private DefaultAlarm(final AlarmId id, | 77 | private DefaultAlarm(final AlarmId id, |
| 61 | - final DeviceId deviceId, | 78 | + final DeviceId deviceId, |
| 62 | - final String description, | 79 | + final String description, |
| 63 | - final AlarmEntityId source, | 80 | + final AlarmEntityId source, |
| 64 | - final long timeRaised, | 81 | + final long timeRaised, |
| 65 | - final long timeUpdated, | 82 | + final long timeUpdated, |
| 66 | - final Long timeCleared, | 83 | + final Long timeCleared, |
| 67 | - final SeverityLevel severity, | 84 | + final SeverityLevel severity, |
| 68 | - final boolean isServiceAffecting, | 85 | + final boolean isServiceAffecting, |
| 69 | - final boolean isAcknowledged, | 86 | + final boolean isAcknowledged, |
| 70 | - final boolean isManuallyClearable, | 87 | + final boolean isManuallyClearable, |
| 71 | - final String assignedUser) { | 88 | + final String assignedUser) { |
| 72 | this.id = id; | 89 | this.id = id; |
| 73 | this.deviceId = deviceId; | 90 | this.deviceId = deviceId; |
| 74 | this.description = description; | 91 | this.description = description; |
| ... | @@ -147,9 +164,9 @@ public final class DefaultAlarm implements Alarm { | ... | @@ -147,9 +164,9 @@ public final class DefaultAlarm implements Alarm { |
| 147 | public int hashCode() { | 164 | public int hashCode() { |
| 148 | // id or timeRaised or timeUpdated may differ | 165 | // id or timeRaised or timeUpdated may differ |
| 149 | return Objects.hash(deviceId, description, | 166 | return Objects.hash(deviceId, description, |
| 150 | - source, timeCleared, severity, | 167 | + source, timeCleared, severity, |
| 151 | - isServiceAffecting, isAcknowledged, | 168 | + isServiceAffecting, isAcknowledged, |
| 152 | - isManuallyClearable, assignedUser); | 169 | + isManuallyClearable, assignedUser); |
| 153 | } | 170 | } |
| 154 | 171 | ||
| 155 | @Override | 172 | @Override |
| ... | @@ -244,7 +261,7 @@ public final class DefaultAlarm implements Alarm { | ... | @@ -244,7 +261,7 @@ public final class DefaultAlarm implements Alarm { |
| 244 | } | 261 | } |
| 245 | 262 | ||
| 246 | public Builder(final DeviceId deviceId, | 263 | public Builder(final DeviceId deviceId, |
| 247 | - final String description, final SeverityLevel severity, final long timeRaised) { | 264 | + final String description, final SeverityLevel severity, final long timeRaised) { |
| 248 | super(); | 265 | super(); |
| 249 | this.id = AlarmId.NONE; | 266 | this.id = AlarmId.NONE; |
| 250 | this.deviceId = deviceId; | 267 | this.deviceId = deviceId; |
| ... | @@ -310,7 +327,7 @@ public final class DefaultAlarm implements Alarm { | ... | @@ -310,7 +327,7 @@ public final class DefaultAlarm implements Alarm { |
| 310 | checkNotNull(severity, "Must specify a severity"); | 327 | checkNotNull(severity, "Must specify a severity"); |
| 311 | 328 | ||
| 312 | return new DefaultAlarm(id, deviceId, description, source, timeRaised, timeUpdated, timeCleared, | 329 | return new DefaultAlarm(id, deviceId, description, source, timeRaised, timeUpdated, timeCleared, |
| 313 | - severity, isServiceAffecting, isAcknowledged, isManuallyClearable, assignedUser); | 330 | + severity, isServiceAffecting, isAcknowledged, isManuallyClearable, assignedUser); |
| 314 | } | 331 | } |
| 315 | } | 332 | } |
| 316 | } | 333 | } | ... | ... |
-
Please register or login to post a comment