[Goldeneye][ONOS-4038] Support configurable heartbeat on DistributedClusterStore
- Add readComponentConfiguration method for @Modified
- Apply updated Tools
- Add unit test code
- Add checkNotNull about NodeId

Change-Id: If8b7d4c00f2c72d29c0abb6407530d76bc3f6d80
diff --git a/core/store/dist/src/main/java/org/onosproject/store/cluster/impl/PhiAccrualFailureDetector.java b/core/store/dist/src/main/java/org/onosproject/store/cluster/impl/PhiAccrualFailureDetector.java
index cdb138b..22911f6 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/cluster/impl/PhiAccrualFailureDetector.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/cluster/impl/PhiAccrualFailureDetector.java
@@ -33,15 +33,20 @@
 public class PhiAccrualFailureDetector {
     private final Map<NodeId, History> states = Maps.newConcurrentMap();
 
-    // TODO: make these configurable.
-    private static final int WINDOW_SIZE = 250;
-    private static final int MIN_SAMPLES = 25;
-    private static final double PHI_FACTOR = 1.0 / Math.log(10.0);
+    // Default value
+    private static final int DEFAULT_WINDOW_SIZE = 250;
+    private static final int DEFAULT_MIN_SAMPLES = 25;
+    private static final double DEFAULT_PHI_FACTOR = 1.0 / Math.log(10.0);
 
     // If a node does not have any heartbeats, this is the phi
     // value to report. Indicates the node is inactive (from the
     // detectors perspective.
-    private static final double BOOTSTRAP_PHI_VALUE = 100.0;
+    private static final double DEFAULT_BOOTSTRAP_PHI_VALUE = 100.0;
+
+
+    private int minSamples = DEFAULT_MIN_SAMPLES;
+    private double phiFactor = DEFAULT_PHI_FACTOR;
+    private double bootstrapPhiValue = DEFAULT_BOOTSTRAP_PHI_VALUE;
 
     /**
      * Report a new heart beat for the specified node id.
@@ -70,6 +75,8 @@
         }
     }
 
+
+
     /**
      * Compute phi for the specified node id.
      * @param nodeId node id
@@ -78,13 +85,13 @@
     public double phi(NodeId nodeId) {
         checkNotNull(nodeId, "NodeId must not be null");
         if (!states.containsKey(nodeId)) {
-            return BOOTSTRAP_PHI_VALUE;
+            return bootstrapPhiValue;
         }
         History nodeState = states.get(nodeId);
         synchronized (nodeState) {
             long latestHeartbeat = nodeState.latestHeartbeatTime();
             DescriptiveStatistics samples = nodeState.samples();
-            if (latestHeartbeat == -1 || samples.getN() < MIN_SAMPLES) {
+            if (latestHeartbeat == -1 || samples.getN() < minSamples) {
                 return 0.0;
             }
             return computePhi(samples, latestHeartbeat, System.currentTimeMillis());
@@ -95,13 +102,27 @@
         long size = samples.getN();
         long t = tNow - tLast;
         return (size > 0)
-               ? PHI_FACTOR * t / samples.getMean()
-               : BOOTSTRAP_PHI_VALUE;
+                ? phiFactor * t / samples.getMean()
+                : bootstrapPhiValue;
     }
 
+
+    private void setMinSamples(int samples) {
+        minSamples = samples;
+    }
+
+    private void setPhiFactor(double factor) {
+        phiFactor = factor;
+    }
+
+    private void setBootstrapPhiValue(double phiValue) {
+        bootstrapPhiValue = phiValue;
+    }
+
+
     private static class History {
         DescriptiveStatistics samples =
-                new DescriptiveStatistics(WINDOW_SIZE);
+                new DescriptiveStatistics(DEFAULT_WINDOW_SIZE);
         long lastHeartbeatTime = -1;
 
         public DescriptiveStatistics samples() {