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");