ONOS-4380 Refactor AlarmId and Alarm construction and update
Change-Id: I0117afda723ba27aadb1db306f7ce15b666f102d
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/faultmanagement/alarm/Alarm.java b/incubator/api/src/main/java/org/onosproject/incubator/net/faultmanagement/alarm/Alarm.java
index 301e8d3..1a7ec9f 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/faultmanagement/alarm/Alarm.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/faultmanagement/alarm/Alarm.java
@@ -121,6 +121,17 @@
boolean acknowledged();
/**
+ * Returns a flag to indicate if this alarm has been cleared. All
+ * alarms are not cleared until and unless an ONOS user or app takes action to
+ * indicate so.
+ *
+ * @return whether alarm is currently cleared (true indicates it is)
+ */
+ default boolean cleared() {
+ return false;
+ }
+
+ /**
* Returns a flag to indicate if this alarm is manually-cleared by a user action within ONOS. Some stateless events
* e.g. backup-failure or upgrade-failure, may be mapped by ONOS to alarms, and these may be deemed manually-
* clearable. The more typical case is that an alarm represents a persistent fault on or related to a device and
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/faultmanagement/alarm/AlarmEvent.java b/incubator/api/src/main/java/org/onosproject/incubator/net/faultmanagement/alarm/AlarmEvent.java
index 9481b01..167d7f6 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/faultmanagement/alarm/AlarmEvent.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/faultmanagement/alarm/AlarmEvent.java
@@ -33,6 +33,10 @@
*/
CREATED,
/**
+ * Individual alarm updated.
+ */
+ UPDATED,
+ /**
* Alarm set updated for a given device.
*/
REMOVED,
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/faultmanagement/alarm/AlarmId.java b/incubator/api/src/main/java/org/onosproject/incubator/net/faultmanagement/alarm/AlarmId.java
index db26a7e..bc84e8a 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/faultmanagement/alarm/AlarmId.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/faultmanagement/alarm/AlarmId.java
@@ -17,48 +17,64 @@
import com.google.common.annotations.Beta;
import org.onlab.util.Identifier;
+import org.onosproject.net.DeviceId;
import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
/**
* Alarm identifier suitable as an external key.
* <p>
* This class is immutable.</p>
*/
@Beta
-public final class AlarmId extends Identifier<Long> {
-
- public static final AlarmId NONE = new AlarmId();
+public final class AlarmId extends Identifier<String> {
/**
* Instantiates a new Alarm id.
*
- * @param id the id
+ * @param id the device id
+ * @param uniqueIdentifier the unique identifier of the Alarm on that device
*/
- private AlarmId(long id) {
- super(id);
- checkArgument(id != 0L, "id must be non-zero");
- }
-
- private AlarmId() {
- super(0L);
+ private AlarmId(DeviceId id, String uniqueIdentifier) {
+ super(id.toString() + ":" + uniqueIdentifier);
+ checkNotNull(id, "device id must not be null");
+ checkNotNull(uniqueIdentifier, "unique identifier must not be null");
+ checkArgument(!uniqueIdentifier.isEmpty(), "unique identifier must not be empty");
}
/**
- * Creates an alarm identifier from the specified long representation.
+ * Instantiates a new Alarm id, primarly meant for lookup.
*
- * @param value long value
- * @return intent identifier
+ * @param globallyUniqueIdentifier the globally unique identifier of the Alarm,
+ * device Id + local unique identifier on the device
*/
- public static AlarmId alarmId(long value) {
- return new AlarmId(value);
+ private AlarmId(String globallyUniqueIdentifier) {
+ super(globallyUniqueIdentifier);
+ checkArgument(!globallyUniqueIdentifier.isEmpty(), "unique identifier must not be empty");
}
/**
- * Returns the backing integer index.
+ * Creates an alarm identifier from the specified device id and
+ * unique identifier provided representation.
*
- * @return backing integer index
+ * @param id device id
+ * @param uniqueIdentifier per device unique identifier of the alarm
+ * @return alarm identifier
*/
- public long fingerprint() {
- return identifier;
+ public static AlarmId alarmId(DeviceId id, String uniqueIdentifier) {
+ return new AlarmId(id, uniqueIdentifier);
}
+
+ /**
+ * Creates an alarm identifier from the specified globally unique identifier.
+ *
+ * @param globallyUniqueIdentifier the globally unique identifier of the Alarm,
+ * device Id + local unique identifier on the device
+ * @return alarm identifier
+ */
+ public static AlarmId alarmId(String globallyUniqueIdentifier) {
+ return new AlarmId(globallyUniqueIdentifier);
+ }
+
}
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/faultmanagement/alarm/AlarmService.java b/incubator/api/src/main/java/org/onosproject/incubator/net/faultmanagement/alarm/AlarmService.java
index 4cee1ca..cba84f4 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/faultmanagement/alarm/AlarmService.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/faultmanagement/alarm/AlarmService.java
@@ -36,10 +36,30 @@
* @param isAcknowledged new acknowledged state
* @param assignedUser new assigned user, null clear
* @return updated alarm (including any recent device-derived changes)
+ * @deprecated 1.10.0 Kingfisher
*/
+ @Deprecated
Alarm updateBookkeepingFields(AlarmId id, boolean isAcknowledged, String assignedUser);
/**
+ * Update book-keeping (ie administrative) fields for the alarm matching the specified identifier.
+ *
+ * @param id alarm identifier
+ * @param clear ture if the alarm has to be cleared
+ * @param isAcknowledged new acknowledged state
+ * @param assignedUser new assigned user, null clear
+ * @return updated alarm (including any recent device-derived changes)
+ */
+ Alarm updateBookkeepingFields(AlarmId id, boolean clear, boolean isAcknowledged, String assignedUser);
+
+ /**
+ * Remove an alarm from ONOS.
+ *
+ * @param id alarm
+ */
+ void remove(AlarmId id);
+
+ /**
* Returns summary of alarms on a given device.
*
* @param deviceId the device
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/faultmanagement/alarm/DefaultAlarm.java b/incubator/api/src/main/java/org/onosproject/incubator/net/faultmanagement/alarm/DefaultAlarm.java
index 162b3df..15d6292 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/faultmanagement/alarm/DefaultAlarm.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/faultmanagement/alarm/DefaultAlarm.java
@@ -25,7 +25,6 @@
/**
* Default implementation of an alarm.
*/
-//TODO simpler creation and updating.
public final class DefaultAlarm implements Alarm {
private final AlarmId id;
@@ -34,14 +33,16 @@
private final String description;
private final AlarmEntityId source;
private final long timeRaised;
- private final long timeUpdated;
- private final Long timeCleared;
- private final SeverityLevel severity;
private final boolean isServiceAffecting;
private final boolean isAcknowledged;
private final boolean isManuallyClearable;
private final String assignedUser;
+ private final SeverityLevel severity;
+ private final long timeUpdated;
+ private final Long timeCleared;
+
+
//Only for Kryo
DefaultAlarm() {
id = null;
@@ -151,6 +152,11 @@
}
@Override
+ public boolean cleared() {
+ return severity.equals(SeverityLevel.CLEARED);
+ }
+
+ @Override
public boolean manuallyClearable() {
return isManuallyClearable;
}
@@ -230,6 +236,9 @@
.toString();
}
+ /**
+ * Builder for the DefaultAlarm object.
+ */
public static class Builder {
// Manadatory fields when constructing alarm ...
@@ -248,8 +257,13 @@
private boolean isManuallyClearable = false;
private String assignedUser = null;
+ /**
+ * Constructs a Builder to create a Default Alarm based on another alarm.
+ *
+ * @param alarm the other alarm
+ */
public Builder(final Alarm alarm) {
- this(alarm.deviceId(), alarm.description(), alarm.severity(), alarm.timeRaised());
+ this(alarm.id(), alarm.deviceId(), alarm.description(), alarm.severity(), alarm.timeRaised());
this.source = alarm.source();
this.timeUpdated = alarm.timeUpdated();
this.timeCleared = alarm.timeCleared();
@@ -260,10 +274,41 @@
}
+ /**
+ * Constructs a Builder to create a Default Alarm.
+ *
+ * @param deviceId the device ID
+ * @param description the Alarm description
+ * @param severity the severity
+ * @param timeRaised when the alarm was raised
+ * @deprecated 1.10.0 - Kingfisher
+ */
+ @Deprecated
public Builder(final DeviceId deviceId,
final String description, final SeverityLevel severity, final long timeRaised) {
super();
- this.id = AlarmId.NONE;
+ this.deviceId = deviceId;
+ this.description = description;
+ this.severity = severity;
+ this.timeRaised = timeRaised;
+ // Unless specified time-updated is same as raised.
+ this.timeUpdated = timeRaised;
+ this.id = AlarmId.alarmId(deviceId, Long.toString(timeRaised));
+ }
+
+ /**
+ * Constructs a Builder to create a Default Alarm.
+ *
+ * @param id the AlarmId
+ * @param deviceId the device ID
+ * @param description the Alarm description
+ * @param severity the severity
+ * @param timeRaised when the alarm was raised
+ */
+ public Builder(final AlarmId id, final DeviceId deviceId,
+ final String description, final SeverityLevel severity, final long timeRaised) {
+ super();
+ this.id = id;
this.deviceId = deviceId;
this.description = description;
this.severity = severity;
@@ -272,52 +317,112 @@
this.timeUpdated = timeRaised;
}
+ /**
+ * Sets the new alarm source.
+ *
+ * @param source the source
+ * @return self for chaining
+ */
public Builder forSource(final AlarmEntityId source) {
this.source = source;
return this;
}
+ /**
+ * Sets the new alarm time updated.
+ *
+ * @param timeUpdated the time
+ * @return self for chaining
+ */
public Builder withTimeUpdated(final long timeUpdated) {
this.timeUpdated = timeUpdated;
return this;
}
+ /**
+ * Sets the new alarm time cleared.
+ *
+ * @param timeCleared the time
+ * @return self for chaining
+ */
public Builder withTimeCleared(final Long timeCleared) {
this.timeCleared = timeCleared;
return this;
}
+ /**
+ * Sets the new alarm Id.
+ *
+ * @param id the id
+ * @return self for chaining
+ * @deprecated 1.10.0- Kingfisher
+ */
+ @Deprecated
public Builder withId(final AlarmId id) {
this.id = id;
return this;
}
+ /**
+ * Clears the alarm that is being created.
+ *
+ * @return self for chaining
+ */
public Builder clear() {
this.severity = SeverityLevel.CLEARED;
final long now = System.currentTimeMillis();
return withTimeCleared(now).withTimeUpdated(now);
}
+ /**
+ * Sets the new alarm service affecting flag.
+ *
+ * @param isServiceAffecting the service affecting flag
+ * @return self for chaining
+ */
public Builder withServiceAffecting(final boolean isServiceAffecting) {
this.isServiceAffecting = isServiceAffecting;
return this;
}
+ /**
+ * Sets the new alarm acknowledged flag.
+ *
+ * @param isAcknowledged the acknowledged flag
+ * @return self for chaining
+ */
public Builder withAcknowledged(final boolean isAcknowledged) {
this.isAcknowledged = isAcknowledged;
return this;
}
+ /**
+ * Sets the new alarm the manually clearable flag.
+ *
+ * @param isManuallyClearable the manually clearable flag
+ * @return self for chaining
+ */
public Builder withManuallyClearable(final boolean isManuallyClearable) {
this.isManuallyClearable = isManuallyClearable;
return this;
}
+ /**
+ * Sets the new alarm assigned user.
+ *
+ * @param assignedUser the user
+ * @return self for chaining
+ */
public Builder withAssignedUser(final String assignedUser) {
this.assignedUser = assignedUser;
return this;
}
+ /**
+ * Builds the alarm.
+ *
+ * @return self for chaining
+ */
public DefaultAlarm build() {
checkNotNull(id, "Must specify an alarm id");
checkNotNull(deviceId, "Must specify a device");
diff --git a/incubator/api/src/test/java/org/onosproject/incubator/net/faultmanagement/alarm/AlarmIdTest.java b/incubator/api/src/test/java/org/onosproject/incubator/net/faultmanagement/alarm/AlarmIdTest.java
index bfb56d6..e9522c4 100644
--- a/incubator/api/src/test/java/org/onosproject/incubator/net/faultmanagement/alarm/AlarmIdTest.java
+++ b/incubator/api/src/test/java/org/onosproject/incubator/net/faultmanagement/alarm/AlarmIdTest.java
@@ -16,14 +16,13 @@
package org.onosproject.incubator.net.faultmanagement.alarm;
import com.google.common.testing.EqualsTester;
-import static org.hamcrest.Matchers.containsString;
import org.junit.Test;
+import org.onosproject.net.DeviceId;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
-import static org.junit.Assert.fail;
import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
/**
@@ -31,9 +30,16 @@
*/
public class AlarmIdTest {
- private static final long ID_A = 1L;
- private static final long ID_B = 2L;
- private static final long ID_Z = 987654321L;
+ private static final DeviceId DEVICE_ID = DeviceId.deviceId("foo:bar");
+ private static final String UNIQUE_ID_1 = "unique_id_1";
+ private static final AlarmId ID_A = AlarmId.alarmId(DEVICE_ID, UNIQUE_ID_1);
+
+ private static final String UNIQUE_ID_2 = "unique_id_2";
+
+ private static final String UNIQUE_ID_3 = "unique_id_3";
+ private static final AlarmId ID_Z = AlarmId.alarmId(DEVICE_ID, UNIQUE_ID_3);
+
+ private static final String ID_STRING = "foo:bar:unique_id_3";
/**
* Tests the immutability of {@link AlarmId}.
@@ -48,8 +54,8 @@
*/
@Test
public void testEquality() {
- final AlarmId id1 = AlarmId.alarmId(ID_A);
- final AlarmId id2 = AlarmId.alarmId(ID_A);
+ final AlarmId id1 = AlarmId.alarmId(DEVICE_ID, UNIQUE_ID_1);
+ final AlarmId id2 = AlarmId.alarmId(DEVICE_ID, UNIQUE_ID_1);
assertThat(id1, is(id2));
}
@@ -59,16 +65,16 @@
*/
@Test
public void testNonEquality() {
- final AlarmId id1 = AlarmId.alarmId(ID_A);
- final AlarmId id2 = AlarmId.alarmId(ID_B);
+ final AlarmId id1 = AlarmId.alarmId(DEVICE_ID, UNIQUE_ID_1);
+ final AlarmId id2 = AlarmId.alarmId(DEVICE_ID, UNIQUE_ID_2);
assertThat(id1, is(not(id2)));
}
@Test
public void valueOf() {
- final AlarmId id = AlarmId.alarmId(0xdeadbeefL);
- assertEquals("incorrect valueOf", id, AlarmId.alarmId(0xdeadbeefL));
+ final AlarmId id = AlarmId.alarmId(DEVICE_ID, UNIQUE_ID_1);
+ assertEquals("incorrect valueOf", id, ID_A);
}
/**
@@ -76,9 +82,9 @@
*/
@Test
public void testEquals() {
- final AlarmId id1 = AlarmId.alarmId(11111L);
- final AlarmId sameAsId1 = AlarmId.alarmId(11111L);
- final AlarmId id2 = AlarmId.alarmId(22222L);
+ final AlarmId id1 = AlarmId.alarmId(DEVICE_ID, UNIQUE_ID_1);
+ final AlarmId sameAsId1 = AlarmId.alarmId(DEVICE_ID, UNIQUE_ID_1);
+ final AlarmId id2 = AlarmId.alarmId(DEVICE_ID, UNIQUE_ID_2);
new EqualsTester()
.addEqualityGroup(id1, sameAsId1)
@@ -91,18 +97,11 @@
*/
@Test
public void testConstruction() {
- final AlarmId id1 = AlarmId.alarmId(ID_Z);
- assertEquals(id1.fingerprint(), ID_Z);
+ final AlarmId id1 = AlarmId.alarmId(DEVICE_ID, UNIQUE_ID_3);
+ assertEquals(id1.toString(), ID_Z.toString());
- // No default constructor so no need to test it !
- assertEquals(0L, AlarmId.NONE.fingerprint());
- try {
- final AlarmId bad = AlarmId.alarmId(0L);
- fail("0 is a Reserved value but we created " + bad);
- } catch (IllegalArgumentException ex) {
- assertThat(ex.getMessage(),
- containsString("id must be non-zero"));
- }
+ final AlarmId idString = AlarmId.alarmId(ID_STRING);
+ assertEquals(id1, idString);
}
}
diff --git a/incubator/api/src/test/java/org/onosproject/incubator/net/faultmanagement/alarm/DefaultAlarmTest.java b/incubator/api/src/test/java/org/onosproject/incubator/net/faultmanagement/alarm/DefaultAlarmTest.java
index 60bb330..7e4c3a9 100644
--- a/incubator/api/src/test/java/org/onosproject/incubator/net/faultmanagement/alarm/DefaultAlarmTest.java
+++ b/incubator/api/src/test/java/org/onosproject/incubator/net/faultmanagement/alarm/DefaultAlarmTest.java
@@ -15,17 +15,23 @@
*/
package org.onosproject.incubator.net.faultmanagement.alarm;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.notNullValue;
-import static org.hamcrest.Matchers.greaterThan;
import org.junit.Test;
-import static org.junit.Assert.*;
-import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
import org.onosproject.net.DeviceId;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
public class DefaultAlarmTest {
+ private static final AlarmEntityId ALARM_ENTITY_ID = AlarmEntityId.alarmEntityId("port:bar");
+ private static final DeviceId DEVICE_ID = DeviceId.deviceId("foo:bar");
+ private static final String UNIQUE_ID_1 = "unique_id_1";
+ private static final AlarmId ALARM_ID = AlarmId.alarmId(DEVICE_ID, UNIQUE_ID_1);
+ private static final String UNIQUE_ID_2 = "unique_id_1";
+ private static final AlarmId ALARM_ID_2 = AlarmId.alarmId(DEVICE_ID, UNIQUE_ID_2);
+
@Test
public void testImmutability() {
assertThatClassIsImmutable(DefaultAlarm.class);
@@ -44,11 +50,11 @@
@Test
public void testEquals() {
- final DefaultAlarm a = new DefaultAlarm.Builder(
+ final DefaultAlarm a = new DefaultAlarm.Builder(ALARM_ID_2,
DeviceId.NONE, "desc", Alarm.SeverityLevel.MINOR, 3).build();
- final DefaultAlarm b = new DefaultAlarm.Builder(
- DeviceId.NONE, "desc", Alarm.SeverityLevel.MINOR, a.timeRaised() + 1).
- withId(ALARM_ID).withTimeUpdated(a.timeUpdated() + 1).build();
+ final DefaultAlarm b = new DefaultAlarm.Builder(ALARM_ID,
+ DeviceId.NONE, "desc", Alarm.SeverityLevel.MINOR, a.timeRaised() + 1)
+ .withTimeUpdated(a.timeUpdated() + 1).build();
assertEquals("id or timeRaised or timeUpdated may differ", a, b);
assertNotEquals(a, new DefaultAlarm.Builder(a).withAcknowledged(!a.acknowledged()).build());
@@ -73,20 +79,17 @@
@Test
public void testId() {
final DefaultAlarm a = generate();
- assertThat(a.id(), is(AlarmId.NONE));
- final DefaultAlarm b = new DefaultAlarm.Builder(a).withId(ALARM_ID).build();
+ final DefaultAlarm b = new DefaultAlarm.Builder(a).build();
assertEquals("id ignored in equals", a, b);
- assertNotEquals(ALARM_ID, a.id());
+ assertEquals(ALARM_ID, a.id());
assertEquals(ALARM_ID, b.id());
assertEquals(ALARM_ENTITY_ID, b.source());
}
- private static final AlarmEntityId ALARM_ENTITY_ID = AlarmEntityId.alarmEntityId("port:bar");
- private static final AlarmId ALARM_ID = AlarmId.alarmId(888L);
private static DefaultAlarm generate() {
- return new DefaultAlarm.Builder(
+ return new DefaultAlarm.Builder(ALARM_ID,
DeviceId.NONE, "desc", Alarm.SeverityLevel.MINOR, 3).forSource(ALARM_ENTITY_ID).build();
}
}