FlowRule private extension refactor.
1.merge private flow into regular flowrule subsystem.no mirror code any
more.no change flowrule api.
2.define a rich-data-type to carry private flow.
3.modify OpenFlowRuleProvider.class to support for 3rd party private
flow.i don't know whether is suitable.because this class name is
relative with open flow protocal.
4.fix some junit test bug caused by modification of FlowRule interface.

Change-Id: I6c54d1e97f231a75bd1b416f0893e0379613d7ce
diff --git a/core/api/src/main/java/org/onosproject/net/flow/DefaultFlowRule.java b/core/api/src/main/java/org/onosproject/net/flow/DefaultFlowRule.java
index 81c0638..1c13ef0 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/DefaultFlowRule.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/DefaultFlowRule.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2014-2015 Open Networking Laboratory
+ * Copyright 2014 Open Networking Laboratory
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -15,17 +15,17 @@
  */
 package org.onosproject.net.flow;
 
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Objects;
+
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.DefaultGroupId;
 import org.onosproject.core.GroupId;
 import org.onosproject.net.DeviceId;
 
-import java.util.Objects;
-
-import static com.google.common.base.MoreObjects.toStringHelper;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
 public class DefaultFlowRule implements FlowRule {
 
     private final DeviceId deviceId;
@@ -43,12 +43,12 @@
     private final GroupId groupId;
 
     private final Integer tableId;
-
+    private final FlowRuleExtPayLoad payLoad;
 
     @Deprecated
     public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
-            TrafficTreatment treatment, int priority, long flowId,
-            int timeout, boolean permanent) {
+                           TrafficTreatment treatment, int priority,
+                           long flowId, int timeout, boolean permanent) {
         this.deviceId = deviceId;
         this.priority = priority;
         this.selector = selector;
@@ -61,12 +61,14 @@
         this.groupId = new DefaultGroupId((short) ((flowId >>> 32) & 0xFFFF));
         this.id = FlowId.valueOf(flowId);
         this.tableId = 0;
+        this.payLoad = null;
     }
 
     @Deprecated
     public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
-                           TrafficTreatment treatment, int priority, long flowId,
-                           int timeout, boolean permanent, Type tableType) {
+                           TrafficTreatment treatment, int priority,
+                           long flowId, int timeout, boolean permanent,
+                           Type tableType) {
         this.deviceId = deviceId;
         this.priority = priority;
         this.selector = selector;
@@ -80,23 +82,26 @@
         this.id = FlowId.valueOf(flowId);
         this.tableId = tableType.ordinal();
 
+        this.payLoad = null;
     }
 
     @Deprecated
     public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
-                           TrafficTreatment treatment, int priority, ApplicationId appId,
-                           int timeout, boolean permanent) {
-        this(deviceId, selector, treatment, priority, appId, new DefaultGroupId(0),
-                timeout, permanent);
+                           TrafficTreatment treatment, int priority,
+                           ApplicationId appId, int timeout, boolean permanent) {
+        this(deviceId, selector, treatment, priority, appId,
+             new DefaultGroupId(0), timeout, permanent);
     }
 
     @Deprecated
     public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
-                           TrafficTreatment treatment, int priority, ApplicationId appId,
-                           int timeout, boolean permanent, Type type) {
+                           TrafficTreatment treatment, int priority,
+                           ApplicationId appId, int timeout, boolean permanent,
+                           Type type) {
 
         if (priority < FlowRule.MIN_PRIORITY) {
-            throw new IllegalArgumentException("Priority cannot be less than " + MIN_PRIORITY);
+            throw new IllegalArgumentException("Priority cannot be less than "
+                    + MIN_PRIORITY);
         }
 
         this.deviceId = deviceId;
@@ -110,22 +115,26 @@
         this.created = System.currentTimeMillis();
         this.tableId = type.ordinal();
 
+        this.payLoad = null;
         /*
-         * id consists of the following.
-         * | appId (16 bits) | groupId (16 bits) | flowId (32 bits) |
+         * id consists of the following. | appId (16 bits) | groupId (16 bits) |
+         * flowId (32 bits) |
          */
-        this.id = FlowId.valueOf((((long) this.appId) << 48) | (((long) this.groupId.id()) << 32)
+        this.id = FlowId.valueOf((((long) this.appId) << 48)
+                | (((long) this.groupId.id()) << 32)
                 | (this.hash() & 0xffffffffL));
 
     }
 
     @Deprecated
     public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
-                           TrafficTreatment treatment, int priority, ApplicationId appId,
-                           GroupId groupId, int timeout, boolean permanent) {
+                           TrafficTreatment treatment, int priority,
+                           ApplicationId appId, GroupId groupId, int timeout,
+                           boolean permanent) {
 
         if (priority < FlowRule.MIN_PRIORITY) {
-            throw new IllegalArgumentException("Priority cannot be less than " + MIN_PRIORITY);
+            throw new IllegalArgumentException("Priority cannot be less than "
+                    + MIN_PRIORITY);
         }
 
         this.deviceId = deviceId;
@@ -138,12 +147,14 @@
         this.permanent = permanent;
         this.created = System.currentTimeMillis();
         this.tableId = 0;
+        this.payLoad = null;
 
         /*
-         * id consists of the following.
-         * | appId (16 bits) | groupId (16 bits) | flowId (32 bits) |
+         * id consists of the following. | appId (16 bits) | groupId (16 bits) |
+         * flowId (32 bits) |
          */
-        this.id = FlowId.valueOf((((long) this.appId) << 48) | (((long) this.groupId.id()) << 32)
+        this.id = FlowId.valueOf((((long) this.appId) << 48)
+                | (((long) this.groupId.id()) << 32)
                 | (this.hash() & 0xffffffffL));
     }
 
@@ -159,7 +170,7 @@
         this.permanent = rule.isPermanent();
         this.created = System.currentTimeMillis();
         this.tableId = rule.tableId();
-
+        this.payLoad = rule.payLoad();
     }
 
     private DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
@@ -181,8 +192,98 @@
 
         //FIXME: fields below will be removed.
         this.groupId = null;
+        this.payLoad = null;
+    }
 
+    /**
+     * Support for the third party flow rule. Creates a flow rule of flow table.
+     *
+     * @param deviceId the identity of the device where this rule applies
+     * @param selector the traffic selector that identifies what traffic this
+     *            rule
+     * @param treatment the traffic treatment that applies to selected traffic
+     * @param priority the flow rule priority given in natural order
+     * @param appId the application id of this flow
+     * @param timeout the timeout for this flow requested by an application
+     * @param permanent whether the flow is permanent i.e. does not time out
+     * @param payLoad 3rd-party origin private flow
+     */
+    public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
+                           TrafficTreatment treatment, int priority,
+                           ApplicationId appId, int timeout, boolean permanent,
+                           FlowRuleExtPayLoad payLoad) {
 
+        if (priority < FlowRule.MIN_PRIORITY) {
+            throw new IllegalArgumentException("Priority cannot be less than "
+                    + MIN_PRIORITY);
+        }
+
+        this.deviceId = deviceId;
+        this.priority = priority;
+        this.selector = selector;
+        this.treatment = treatment;
+        this.appId = appId.id();
+        this.groupId = new DefaultGroupId(0);
+        this.timeout = timeout;
+        this.permanent = permanent;
+        this.tableId = 0;
+        this.created = System.currentTimeMillis();
+        this.payLoad = payLoad;
+
+        /*
+         * id consists of the following. | appId (16 bits) | groupId (16 bits) |
+         * flowId (32 bits) |
+         */
+        this.id = FlowId.valueOf((((long) this.appId) << 48)
+                | (((long) this.groupId.id()) << 32)
+                | (this.hash() & 0xffffffffL));
+    }
+
+    /**
+     * Support for the third party flow rule. Creates a flow rule of group
+     * table.
+     *
+     * @param deviceId the identity of the device where this rule applies
+     * @param selector the traffic selector that identifies what traffic this
+     *            rule
+     * @param treatment the traffic treatment that applies to selected traffic
+     * @param priority the flow rule priority given in natural order
+     * @param appId the application id of this flow
+     * @param groupId the group id of this flow
+     * @param timeout the timeout for this flow requested by an application
+     * @param permanent whether the flow is permanent i.e. does not time out
+     * @param payLoad 3rd-party origin private flow
+     *
+     */
+    public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
+                           TrafficTreatment treatment, int priority,
+                           ApplicationId appId, GroupId groupId, int timeout,
+                           boolean permanent, FlowRuleExtPayLoad payLoad) {
+
+        if (priority < FlowRule.MIN_PRIORITY) {
+            throw new IllegalArgumentException("Priority cannot be less than "
+                    + MIN_PRIORITY);
+        }
+
+        this.deviceId = deviceId;
+        this.priority = priority;
+        this.selector = selector;
+        this.treatment = treatment;
+        this.appId = appId.id();
+        this.groupId = groupId;
+        this.timeout = timeout;
+        this.permanent = permanent;
+        this.created = System.currentTimeMillis();
+        this.tableId = 0;
+        this.payLoad = payLoad;
+
+        /*
+         * id consists of the following. | appId (16 bits) | groupId (16 bits) |
+         * flowId (32 bits) |
+         */
+        this.id = FlowId.valueOf((((long) this.appId) << 48)
+                | (((long) this.groupId.id()) << 32)
+                | (this.hash() & 0xffffffffL));
     }
 
     @Override
@@ -225,14 +326,15 @@
      * The priority and statistics can change on a given treatment and selector
      *
      * (non-Javadoc)
+     *
      * @see java.lang.Object#equals(java.lang.Object)
      */
     public int hashCode() {
-        return Objects.hash(deviceId, selector, priority, tableId);
+        return Objects.hash(deviceId, selector, priority, tableId, payLoad);
     }
 
     public int hash() {
-        return Objects.hash(deviceId, selector, treatment, tableId);
+        return Objects.hash(deviceId, selector, treatment, tableId, payLoad);
     }
 
     @Override
@@ -240,6 +342,7 @@
      * The priority and statistics can change on a given treatment and selector
      *
      * (non-Javadoc)
+     *
      * @see java.lang.Object#equals(java.lang.Object)
      */
     public boolean equals(Object obj) {
@@ -251,8 +354,8 @@
             return Objects.equals(deviceId, that.deviceId) &&
                     Objects.equals(priority, that.priority) &&
                     Objects.equals(selector, that.selector) &&
-                    Objects.equals(tableId, that.tableId);
-
+                    Objects.equals(tableId, that.tableId)
+                     && Objects.equals(payLoad, that.payLoad);
         }
         return false;
     }
@@ -267,6 +370,7 @@
                 .add("treatment", treatment == null ? "N/A" : treatment.allInstructions())
                 .add("tableId", tableId)
                 .add("created", created)
+                .add("payLoad", payLoad).toString()
                 .toString();
     }
 
@@ -383,4 +487,9 @@
 
     }
 
+    @Override
+    public FlowRuleExtPayLoad payLoad() {
+        return payLoad;
+    }
+
 }