Introduced HostMoveTracker to suspend hosts that moves too frequently

Change-Id: I3037c626657790ce6817feddba7dbbfac203b188
diff --git a/core/api/src/main/java/org/onosproject/net/DefaultHost.java b/core/api/src/main/java/org/onosproject/net/DefaultHost.java
index ec0d9b5..8e6c195 100644
--- a/core/api/src/main/java/org/onosproject/net/DefaultHost.java
+++ b/core/api/src/main/java/org/onosproject/net/DefaultHost.java
@@ -41,6 +41,7 @@
     private final VlanId innerVlan;
     private final EthType tpid;
     private final boolean configured;
+    private final boolean suspended;
 
     // TODO consider moving this constructor to a builder pattern.
     /**
@@ -95,7 +96,7 @@
                        VlanId vlan, Set<HostLocation> locations, Set<IpAddress> ips,
                        boolean configured, Annotations... annotations) {
         this(providerId, id, mac, vlan, locations, ips, VlanId.NONE,
-             EthType.EtherType.UNKNOWN.ethType(), configured, annotations);
+                EthType.EtherType.UNKNOWN.ethType(), configured, annotations);
     }
 
     /**
@@ -123,6 +124,36 @@
         this.configured = configured;
         this.innerVlan = innerVlan;
         this.tpid = tpid;
+        this.suspended = false;
+    }
+
+    /**
+     * Creates an end-station host using the supplied information.
+     *
+     * @param providerId  provider identity
+     * @param id          host identifier
+     * @param mac         host MAC address
+     * @param vlan        host VLAN identifier
+     * @param locations   set of host locations
+     * @param ips         host IP addresses
+     * @param configured  true if configured via NetworkConfiguration
+     * @param innerVlan   host inner VLAN identifier
+     * @param tpid        outer TPID of a host
+     * @param suspended   true if the host is suspended due to policy violation.
+     * @param annotations optional key/value annotations
+     */
+    public DefaultHost(ProviderId providerId, HostId id, MacAddress mac,
+                       VlanId vlan, Set<HostLocation> locations, Set<IpAddress> ips, VlanId innerVlan,
+                       EthType tpid, boolean configured, boolean suspended, Annotations... annotations) {
+        super(providerId, id, annotations);
+        this.mac = mac;
+        this.vlan = vlan;
+        this.locations = new HashSet<>(locations);
+        this.ips = new HashSet<>(ips);
+        this.configured = configured;
+        this.innerVlan = innerVlan;
+        this.tpid = tpid;
+        this.suspended = suspended;
     }
 
     @Override
@@ -177,8 +208,14 @@
     }
 
     @Override
+    public boolean suspended() {
+        return this.suspended;
+    }
+
+
+    @Override
     public int hashCode() {
-        return Objects.hash(id, mac, vlan, locations);
+        return Objects.hash(id, mac, vlan, locations, suspended);
     }
 
     @Override
@@ -195,7 +232,8 @@
                     Objects.equals(this.ipAddresses(), other.ipAddresses()) &&
                     Objects.equals(this.innerVlan, other.innerVlan) &&
                     Objects.equals(this.tpid, other.tpid) &&
-                    Objects.equals(this.annotations(), other.annotations());
+                    Objects.equals(this.annotations(), other.annotations()) &&
+                    Objects.equals(this.suspended, other.suspended);
         }
         return false;
     }
@@ -212,6 +250,7 @@
                 .add("configured", configured())
                 .add("innerVlanId", innerVlan())
                 .add("outerTPID", tpid())
+                .add("suspended", suspended())
                 .toString();
     }
 
diff --git a/core/api/src/main/java/org/onosproject/net/Host.java b/core/api/src/main/java/org/onosproject/net/Host.java
index 1c2e50a..d4a922e 100644
--- a/core/api/src/main/java/org/onosproject/net/Host.java
+++ b/core/api/src/main/java/org/onosproject/net/Host.java
@@ -73,6 +73,7 @@
 
     /**
      * Returns true if configured by NetworkConfiguration.
+     *
      * @return configured/learnt dynamically
      */
     default boolean configured() {
@@ -98,4 +99,12 @@
     }
     // TODO: explore capturing list of recent locations to aid in mobility
 
+    /**
+     * Returns the state of host whether it is in suspended state(offending host due to frequent movement.).
+     *
+     * @return state true if suspended else false.
+     */
+    boolean suspended();
+
+
 }
diff --git a/core/api/src/main/java/org/onosproject/net/host/HostEvent.java b/core/api/src/main/java/org/onosproject/net/host/HostEvent.java
index 0ed491f..0fecf2b 100644
--- a/core/api/src/main/java/org/onosproject/net/host/HostEvent.java
+++ b/core/api/src/main/java/org/onosproject/net/host/HostEvent.java
@@ -48,7 +48,15 @@
         /**
          * Signifies that a host location has changed.
          */
-        HOST_MOVED
+        HOST_MOVED,
+        /**
+         * Signifies that a host is in offending state, eg: frequent  host movement.
+         */
+        HOST_SUSPENDED,
+        /**
+         * Signifies that host state in non offending state.
+         */
+        HOST_UNSUSPENDED
     }
 
     private Host prevSubject;
diff --git a/core/api/src/main/java/org/onosproject/net/host/HostStore.java b/core/api/src/main/java/org/onosproject/net/host/HostStore.java
index 0b6238b..6d6eb11 100644
--- a/core/api/src/main/java/org/onosproject/net/host/HostStore.java
+++ b/core/api/src/main/java/org/onosproject/net/host/HostStore.java
@@ -161,4 +161,21 @@
      * @param probeMac the source MAC address ONOS uses to probe the host
      */
     default void removePendingHostLocation(MacAddress probeMac) {}
+
+    /**
+     * Update the host to suspended state to true
+     * denotes host is in suspended state.
+     *
+     * @param id ID of the host
+     */
+    default void suspend(HostId id){}
+
+    /**
+     * Update the host suspended state to false
+     * denotes host is in unsuspended state.
+     *
+     * @param id ID of the host
+     */
+    default void unsuspend(HostId id){}
+
 }