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