[Emu] openTAM: NewAdaptiveFlowStatsCollector Implementation

  - NewAdaptiveFlowStatsCollector.java
   .Bug fix to initialize callCountCalAndShortFlowsTask value
   .Added flowMissingXid variable to identify individual StatsRequest or match all StatsRequest message or not
  - DefaultTypedFlowEntry.java, TypedStoredFlowEntry.java
   .Added javadoc for class
  - OpenFlowRuleProvider.java
   .Line 2: 2014 -> 2015
   .Added adaptiveFlowSampling boolean property with default
   .Added call providerService.pushFlowMetricsWithoutFlowMissing in case of  individual StatsRequest
  - FlowRuleProviderService.java
   .Added pushFlowMetricsWithoutFlowMissing() function
  - FlowRuleManager.java
   .Added pushFlowMetricsWithoutFlowMissing() implementation
  - OpenFlowControllerImpl.java
   .Bug fix to unchange the StatsRequest Xid value in case of StatsReply Flow message type

Change-Id: Id4dc4a164da654af7b6dfb090af7336e748ef118
diff --git a/core/api/src/main/java/org/onosproject/net/flow/DefaultTypedFlowEntry.java b/core/api/src/main/java/org/onosproject/net/flow/DefaultTypedFlowEntry.java
new file mode 100644
index 0000000..afceb14
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/DefaultTypedFlowEntry.java
@@ -0,0 +1,122 @@
+/*

+ * Copyright 2015 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.

+ * You may obtain a copy of the License at

+ *

+ *     http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing, software

+ * distributed under the License is distributed on an "AS IS" BASIS,

+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * See the License for the specific language governing permissions and

+ * limitations under the License.

+ */

+

+package org.onosproject.net.flow;

+

+import static com.google.common.base.MoreObjects.toStringHelper;

+

+/**

+ * Default flow entry class with FlowLiveType value, IMMEDIATE_FLOW, SHORT_FLOW, MID_FLOW, LONG_FLOW.

+ */

+public class DefaultTypedFlowEntry extends DefaultFlowEntry

+    implements TypedStoredFlowEntry {

+    private FlowLiveType liveType;

+

+    /**

+     * Creates a typed flow entry from flow rule and its statistics, with default flow live type(IMMEDIATE_FLOW).

+     *

+     * @param rule the flow rule

+     * @param state the flow state

+     * @param life the flow duration since creation

+     * @param packets the flow packets count

+     * @param bytes the flow bytes count

+     *

+     */

+    public DefaultTypedFlowEntry(FlowRule rule, FlowEntryState state,

+                            long life, long packets, long bytes) {

+        super(rule, state, life, packets, bytes);

+        this.liveType = FlowLiveType.IMMEDIATE_FLOW;

+    }

+

+    /**

+     * Creates a typed flow entry from flow rule,  with default flow live type(IMMEDIATE_FLOW).

+     *

+     * @param rule the flow rule

+     *

+     */

+    public DefaultTypedFlowEntry(FlowRule rule) {

+        super(rule);

+        this.liveType = FlowLiveType.IMMEDIATE_FLOW;

+    }

+

+    /**

+     * Creates a typed flow entry from flow entry,  with default flow live type(IMMEDIATE_FLOW).

+     *

+     * @param fe the flow entry

+     *

+     */

+    public DefaultTypedFlowEntry(FlowEntry fe) {

+        super(fe, fe.state(), fe.life(), fe.packets(), fe.bytes());

+        this.liveType = FlowLiveType.IMMEDIATE_FLOW;

+    }

+

+    /**

+     * Creates a typed flow entry from flow rule and flow live type.

+     *

+     * @param rule the flow rule

+     * @param liveType the flow live type

+     *

+     */

+    public DefaultTypedFlowEntry(FlowRule rule, FlowLiveType liveType) {

+        super(rule);

+        this.liveType = liveType;

+    }

+

+    /**

+     * Creates a typed flow entry from flow entry and flow live type.

+     *

+     * @param fe the flow rule

+     * @param liveType the flow live type

+     *

+     */

+    public DefaultTypedFlowEntry(FlowEntry fe,  FlowLiveType liveType) {

+        super(fe, fe.state(), fe.life(), fe.packets(), fe.bytes());

+        this.liveType = liveType;

+    }

+

+    /**

+     * Creates a typed flow entry from flow rule, error code and flow live type.

+     *

+     * @param rule the flow rule

+     * @param errType the flow error type

+     * @param errCode the flow error code

+     * @param liveType the flow live type

+     *

+     */

+    public DefaultTypedFlowEntry(FlowRule rule, int errType, int errCode, FlowLiveType liveType) {

+        super(rule, errType, errCode);

+        this.liveType = liveType;

+    }

+

+    @Override

+    public FlowLiveType flowLiveType() {

+        return this.liveType;

+    }

+

+    @Override

+    public void setFlowLiveType(FlowLiveType liveType) {

+        this.liveType = liveType;

+    }

+

+    @Override

+    public String toString() {

+        return toStringHelper(this)

+                .add("entry", super.toString())

+                .add("type", liveType)

+                .toString();

+    }

+}

+

diff --git a/core/api/src/main/java/org/onosproject/net/flow/FlowRuleProviderService.java b/core/api/src/main/java/org/onosproject/net/flow/FlowRuleProviderService.java
index 8a36a92..48aa504 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/FlowRuleProviderService.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/FlowRuleProviderService.java
@@ -41,6 +41,15 @@
     void pushFlowMetrics(DeviceId deviceId, Iterable<FlowEntry> flowEntries);
 
     /**
+     * Pushes the collection of flow entries currently applied on the given
+     * device without flowMissing process.
+     *
+     * @param deviceId device identifier
+     * @param flowEntries collection of flow rules
+     */
+    void pushFlowMetricsWithoutFlowMissing(DeviceId deviceId, Iterable<FlowEntry> flowEntries);
+
+    /**
      * Indicates to the core that the requested batch operation has
      * been completed.
      *
diff --git a/core/api/src/main/java/org/onosproject/net/flow/TypedStoredFlowEntry.java b/core/api/src/main/java/org/onosproject/net/flow/TypedStoredFlowEntry.java
new file mode 100644
index 0000000..a93dc07
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/TypedStoredFlowEntry.java
@@ -0,0 +1,65 @@
+/*

+ * Copyright 2015 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.

+ * You may obtain a copy of the License at

+ *

+ *     http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing, software

+ * distributed under the License is distributed on an "AS IS" BASIS,

+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * See the License for the specific language governing permissions and

+ * limitations under the License.

+ */

+

+package org.onosproject.net.flow;

+

+/**

+ * Represents a flow live type for a given flow entry.

+ */

+public interface TypedStoredFlowEntry extends StoredFlowEntry {

+    enum FlowLiveType {

+        /**

+         * Indicates that this rule has been submitted for addition immediately.

+         * Not necessarily collecting flow stats.

+         */

+        IMMEDIATE_FLOW,

+

+        /**

+         * Indicates that this rule has been submitted for a short time.

+         * Necessarily collecting flow stats every calAndPollInterval.

+         */

+        SHORT_FLOW,

+

+        /**

+         * Indicates that this rule has been submitted for a mid time.

+         * Necessarily collecting flow stats every midPollInterval.

+         */

+        MID_FLOW,

+

+        /**

+         * Indicates that this rule has been submitted for a long time.

+         * Necessarily collecting flow stats every longPollInterval.

+         */

+        LONG_FLOW,

+

+        /**

+         * Indicates that this rule has been submitted for UNKNOWN or ERROR.

+         * Not necessarily collecting flow stats.

+         */

+        UNKNOWN_FLOW

+    }

+

+    /**

+     * Gets the flow live type for this entry.

+     */

+    FlowLiveType flowLiveType();

+

+    /**

+     * Sets the new flow live type for this entry.

+     * @param liveType new flow live type.

+     */

+    void setFlowLiveType(FlowLiveType liveType);

+}

diff --git a/core/net/src/main/java/org/onosproject/net/flow/impl/FlowRuleManager.java b/core/net/src/main/java/org/onosproject/net/flow/impl/FlowRuleManager.java
index a1d046c..9bbd0aa 100644
--- a/core/net/src/main/java/org/onosproject/net/flow/impl/FlowRuleManager.java
+++ b/core/net/src/main/java/org/onosproject/net/flow/impl/FlowRuleManager.java
@@ -388,6 +388,16 @@
 
         @Override
         public void pushFlowMetrics(DeviceId deviceId, Iterable<FlowEntry> flowEntries) {
+            pushFlowMetricsInternal(deviceId, flowEntries, true);
+        }
+
+        @Override
+        public void pushFlowMetricsWithoutFlowMissing(DeviceId deviceId, Iterable<FlowEntry> flowEntries) {
+            pushFlowMetricsInternal(deviceId, flowEntries, false);
+        }
+
+        private void pushFlowMetricsInternal(DeviceId deviceId, Iterable<FlowEntry> flowEntries,
+                                             boolean useMissingFlow) {
             Map<FlowEntry, FlowEntry> storedRules = Maps.newHashMap();
             store.getFlowEntries(deviceId).forEach(f -> storedRules.put(f, f));
 
@@ -415,17 +425,20 @@
                     continue;
                 }
             }
-            for (FlowEntry rule : storedRules.keySet()) {
-                try {
-                    // there are rules in the store that aren't on the switch
-                    log.debug("Adding rule in store, but not on switch {}", rule);
-                    flowMissing(rule);
-                } catch (Exception e) {
-                    log.debug("Can't add missing flow rule {}", e.getMessage());
-                    continue;
+
+            // DO NOT reinstall
+            if (useMissingFlow) {
+                for (FlowEntry rule : storedRules.keySet()) {
+                    try {
+                        // there are rules in the store that aren't on the switch
+                        log.debug("Adding rule in store, but not on switch {}", rule);
+                        flowMissing(rule);
+                    } catch (Exception e) {
+                        log.debug("Can't add missing flow rule {}", e.getMessage());
+                        continue;
+                    }
                 }
             }
-
         }
 
         @Override