resilient flows and application id

Change-Id: Ic9f192d4451ae962737ab2b45c644372535e7bdb
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/DefaultFlowRule.java b/core/api/src/main/java/org/onlab/onos/net/flow/DefaultFlowRule.java
index ad22160..65c4a16 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/DefaultFlowRule.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/DefaultFlowRule.java
@@ -5,6 +5,7 @@
 
 import java.util.Objects;
 
+import org.onlab.onos.ApplicationId;
 import org.onlab.onos.net.DeviceId;
 import org.slf4j.Logger;
 
@@ -24,6 +25,8 @@
 
     private final FlowId id;
 
+    private final ApplicationId appId;
+
     public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
             TrafficTreatment treatment, int priority, FlowRuleState state,
             long life, long packets, long bytes, long flowId) {
@@ -32,7 +35,7 @@
         this.selector = selector;
         this.treatment = treatment;
         this.state = state;
-
+        this.appId = ApplicationId.valueOf((int) (flowId >> 32));
         this.id = FlowId.valueOf(flowId);
 
         this.life = life;
@@ -42,18 +45,18 @@
     }
 
     public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
-            TrafficTreatment treatement, int priority) {
-        this(deviceId, selector, treatement, priority, FlowRuleState.CREATED);
+            TrafficTreatment treatement, int priority, ApplicationId appId) {
+        this(deviceId, selector, treatement, priority, FlowRuleState.CREATED, appId);
     }
 
     public DefaultFlowRule(FlowRule rule, FlowRuleState state) {
         this(rule.deviceId(), rule.selector(), rule.treatment(),
-                rule.priority(), state, rule.id());
+                rule.priority(), state, rule.id(), rule.appId());
     }
 
     private DefaultFlowRule(DeviceId deviceId,
             TrafficSelector selector, TrafficTreatment treatment,
-            int priority, FlowRuleState state) {
+            int priority, FlowRuleState state, ApplicationId appId) {
         this.deviceId = deviceId;
         this.priority = priority;
         this.selector = selector;
@@ -62,13 +65,15 @@
         this.life = 0;
         this.packets = 0;
         this.bytes = 0;
-        this.id = FlowId.valueOf(this.hashCode());
+        this.appId = appId;
+
+        this.id = FlowId.valueOf((((long) appId().id()) << 32) | (this.hash() & 0xffffffffL));
         this.created = System.currentTimeMillis();
     }
 
     private DefaultFlowRule(DeviceId deviceId,
             TrafficSelector selector, TrafficTreatment treatment,
-            int priority, FlowRuleState state, FlowId flowId) {
+            int priority, FlowRuleState state, FlowId flowId, ApplicationId appId) {
         this.deviceId = deviceId;
         this.priority = priority;
         this.selector = selector;
@@ -77,6 +82,7 @@
         this.life = 0;
         this.packets = 0;
         this.bytes = 0;
+        this.appId = appId;
         this.id = flowId;
         this.created = System.currentTimeMillis();
     }
@@ -88,6 +94,11 @@
     }
 
     @Override
+    public ApplicationId appId() {
+        return appId;
+    }
+
+    @Override
     public int priority() {
         return priority;
     }
@@ -136,7 +147,11 @@
      * @see java.lang.Object#equals(java.lang.Object)
      */
     public int hashCode() {
-        return Objects.hash(deviceId, selector, treatment);
+        return Objects.hash(deviceId, id);
+    }
+
+    public int hash() {
+        return Objects.hash(deviceId, selector, id);
     }
 
     @Override
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRule.java b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRule.java
index e72beed..487659b 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRule.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRule.java
@@ -1,5 +1,6 @@
 package org.onlab.onos.net.flow;
 
+import org.onlab.onos.ApplicationId;
 import org.onlab.onos.net.DeviceId;
 
 /**
@@ -53,6 +54,13 @@
     FlowId id();
 
     /**
+     * Returns the application id of this flow.
+     *
+     * @return an applicationId
+     */
+    ApplicationId appId();
+
+    /**
      * Returns the flow rule priority given in natural order; higher numbers
      * mean higher priorities.
      *
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleProvider.java b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleProvider.java
index 0277695..b2c3d30 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleProvider.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleProvider.java
@@ -1,5 +1,6 @@
 package org.onlab.onos.net.flow;
 
+import org.onlab.onos.ApplicationId;
 import org.onlab.onos.net.provider.Provider;
 
 /**
@@ -25,4 +26,10 @@
      */
     void removeFlowRule(FlowRule... flowRules);
 
+    /**
+     * Removes rules by their id.
+     * @param id the id to remove
+     */
+    void removeRulesById(ApplicationId id, FlowRule... flowRules);
+
 }
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleService.java b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleService.java
index 9db035a..c09a56d 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleService.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleService.java
@@ -1,5 +1,6 @@
 package org.onlab.onos.net.flow;
 
+import org.onlab.onos.ApplicationId;
 import org.onlab.onos.net.DeviceId;
 
 /**
@@ -43,6 +44,20 @@
      */
     void removeFlowRules(FlowRule... flowRules);
 
+    /**
+     * Removes all rules by id.
+     *
+     * @param appId id to remove
+     */
+    void removeFlowRulesById(ApplicationId appId);
+
+    /**
+     * Returns a list of rules with this application id.
+     *
+     * @param id the id to look up
+     * @return collection of flow rules
+     */
+    Iterable<FlowRule> getFlowRulesById(ApplicationId id);
 
     /**
      * Adds the specified flow rule listener.
@@ -58,4 +73,6 @@
      */
     void removeListener(FlowRuleListener listener);
 
+
+
 }
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleStore.java b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleStore.java
index f00b595..28793e6 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleStore.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleStore.java
@@ -1,5 +1,6 @@
 package org.onlab.onos.net.flow;
 
+import org.onlab.onos.ApplicationId;
 import org.onlab.onos.net.DeviceId;
 
 /**
@@ -8,6 +9,13 @@
 public interface FlowRuleStore {
 
     /**
+     * Returns the stored flow.
+     * @param rule the rule to look for
+     * @return a flow rule
+     */
+    FlowRule getFlowRule(FlowRule rule);
+
+    /**
      * Returns the flow entries associated with a device.
      *
      * @param deviceId the device ID
@@ -16,6 +24,14 @@
     Iterable<FlowRule> getFlowEntries(DeviceId deviceId);
 
     /**
+     * Returns the flow entries associated with an application.
+     *
+     * @param appId the application id
+     * @return the flow entries
+     */
+    Iterable<FlowRule> getFlowEntriesByAppId(ApplicationId appId);
+
+    /**
      * Stores a new flow rule without generating events.
      *
      * @param rule the flow rule to add