[ONOS-5708] Implement VirtualNetworkFlowRuleManager

Changes
1. VirtualFlowRuleStore is added
2. VirtualFlowRuleManager test code is added
3. VirtualProviders can be registered through VirtualNetworkManager
4. VirtualFlowRuleManager is implemented
5. VnetServiceWithProvider service is added for interconnectiong
    VirtualProvider and VirtualProviderService

TODO
1. Implement more test cases

Change-Id: I0a1ce633b8ed78f0529e40ed34ae702974f53f69
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkAdminService.java b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkAdminService.java
index 38e745f..a7fbe13 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkAdminService.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkAdminService.java
@@ -176,5 +176,4 @@
      * @throws org.onlab.util.ItemNotFoundException if no such network or port found
      */
     void removeVirtualPort(NetworkId networkId, DeviceId deviceId, PortNumber portNumber);
-
 }
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkFlowRuleStore.java b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkFlowRuleStore.java
new file mode 100644
index 0000000..faca465
--- /dev/null
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkFlowRuleStore.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2016-present 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.incubator.net.virtual;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.FlowRuleBatchEvent;
+import org.onosproject.net.flow.FlowRuleBatchOperation;
+import org.onosproject.net.flow.FlowRuleEvent;
+import org.onosproject.net.flow.FlowRuleStoreDelegate;
+import org.onosproject.net.flow.TableStatisticsEntry;
+import org.onosproject.store.Store;
+
+import java.util.List;
+
+public interface VirtualNetworkFlowRuleStore
+        extends Store<FlowRuleBatchEvent, FlowRuleStoreDelegate> {
+    /**
+     * Returns the number of flow rule in the store.
+     *
+     * @param networkId virtual network identifier
+     * @return number of flow rules
+     */
+    int getFlowRuleCount(NetworkId networkId);
+
+    /**
+     * Returns the stored flow.
+     *
+     * @param networkId virtual network identifier
+     * @param rule the rule to look for
+     * @return a flow rule
+     */
+    FlowEntry getFlowEntry(NetworkId networkId, FlowRule rule);
+
+    /**
+     * Returns the flow entries associated with a device.
+     *
+     * @param networkId virtual network identifier
+     * @param deviceId the device ID
+     * @return the flow entries
+     */
+    Iterable<FlowEntry> getFlowEntries(NetworkId networkId, DeviceId deviceId);
+
+    /**
+     * // TODO: Better description of method behavior.
+     * Stores a new flow rule without generating events.
+     *
+     * @param networkId virtual network identifier
+     * @param rule the flow rule to add
+     * @deprecated in Cardinal Release
+     */
+    @Deprecated
+    void storeFlowRule(NetworkId networkId, FlowRule rule);
+
+    /**
+     * Stores a batch of flow rules.
+     *
+     * @param networkId virtual network identifier
+     * @param batchOperation batch of flow rules.
+     *           A batch can contain flow rules for a single device only.
+     *
+     */
+    void storeBatch(NetworkId networkId, FlowRuleBatchOperation batchOperation);
+
+    /**
+     * Invoked on the completion of a storeBatch operation.
+     *
+     * @param networkId virtual network identifier
+     * @param event flow rule batch event
+     */
+    void batchOperationComplete(NetworkId networkId, FlowRuleBatchEvent event);
+
+    /**
+     * Marks a flow rule for deletion. Actual deletion will occur
+     * when the provider indicates that the flow has been removed.
+     *
+     * @param networkId virtual network identifier
+     * @param rule the flow rule to delete
+     */
+    void deleteFlowRule(NetworkId networkId, FlowRule rule);
+
+    /**
+     * Stores a new flow rule, or updates an existing entry.
+     *
+     * @param networkId virtual network identifier
+     * @param rule the flow rule to add or update
+     * @return flow_added event, or null if just an update
+     */
+    FlowRuleEvent addOrUpdateFlowRule(NetworkId networkId, FlowEntry rule);
+
+    /**
+     * Removes an existing flow entry.
+     *
+     * @param rule the flow entry to remove
+     * @param networkId virtual network identifier
+     * @return flow_removed event, or null if nothing removed
+     */
+    FlowRuleEvent removeFlowRule(NetworkId networkId, FlowEntry rule);
+
+    /**
+     * Marks a flow rule as PENDING_ADD during retry.
+     *
+     * Emits flow_update event if the state is changed
+     *
+     * @param networkId virtual network identifier
+     * @param rule the flow rule that is retrying
+     * @return flow_updated event, or null if nothing updated
+     */
+    FlowRuleEvent pendingFlowRule(NetworkId networkId, FlowEntry rule);
+
+    /**
+     * Removes all flow entries of given device from store.
+     *
+     * @param networkId virtual network identifier
+     * @param deviceId device id
+     */
+    default void purgeFlowRule(NetworkId networkId, DeviceId deviceId) {}
+
+    /**
+     * Removes all flow entries from store.
+     *
+     * @param networkId virtual network identifier
+     */
+    void purgeFlowRules(NetworkId networkId);
+
+    /**
+     * Updates the flow table statistics of the specified device using
+     * the given statistics.
+     *
+     * @param networkId virtual network identifier
+     * @param deviceId    device identifier
+     * @param tableStats   list of table statistics
+     * @return ready to send event describing what occurred;
+     */
+    FlowRuleEvent updateTableStatistics(NetworkId networkId, DeviceId deviceId,
+                                        List<TableStatisticsEntry> tableStats);
+
+    /**
+     * Returns the flow table statistics associated with a device.
+     *
+     * @param networkId virtual network identifier
+     * @param deviceId the device ID
+     * @return the flow table statistics
+     */
+    Iterable<TableStatisticsEntry> getTableStatistics(NetworkId networkId, DeviceId deviceId);
+}
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/AbstractVirtualProviderService.java b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/AbstractVirtualProviderService.java
index e12f1ef..8603be5 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/AbstractVirtualProviderService.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/AbstractVirtualProviderService.java
@@ -25,7 +25,7 @@
  * @param <P> type of the information provider
  */
 public abstract class AbstractVirtualProviderService<P extends VirtualProvider>
-        implements VirtualProviderService {
+        implements VirtualProviderService<P> {
 
     private boolean isValid = true;
     private P provider = null;
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualFlowRuleProvider.java b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualFlowRuleProvider.java
index 89f1f43..87fe7a5 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualFlowRuleProvider.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualFlowRuleProvider.java
@@ -17,6 +17,7 @@
 
 import org.onosproject.incubator.net.virtual.NetworkId;
 import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.FlowRuleBatchOperation;
 
 /**
  * Abstraction of a virtual flow rule provider.
@@ -42,4 +43,13 @@
      * @param flowRules one or more flow rules
      */
     void removeFlowRule(NetworkId networkId, FlowRule... flowRules);
+
+    /**
+     * Installs a batch of flow rules. Each flowrule is associated to an
+     * operation which results in either addition, removal or modification.
+     *
+     * @param networkId the identity of the virtual network where this rule applies
+     * @param batch a batch of flow rules
+     */
+    void executeBatch(NetworkId networkId, FlowRuleBatchOperation batch);
 }
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualFlowRuleProviderService.java b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualFlowRuleProviderService.java
index 3f6bf8c..9b4fb50 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualFlowRuleProviderService.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualFlowRuleProviderService.java
@@ -15,8 +15,8 @@
  */
 package org.onosproject.incubator.net.virtual.provider;
 
-import org.onosproject.incubator.net.virtual.NetworkId;
 import org.onosproject.net.DeviceId;
+import org.onosproject.net.flow.CompletedBatchOperation;
 import org.onosproject.net.flow.FlowEntry;
 import org.onosproject.net.flow.TableStatisticsEntry;
 
@@ -32,42 +32,44 @@
     /**
      * Signals that a flow rule that was previously installed has been removed.
      *
-     * @param networkId the identity of the virtual network where this rule applies
      * @param flowEntry removed flow entry
      */
-    void flowRemoved(NetworkId networkId, FlowEntry flowEntry);
+    void flowRemoved(FlowEntry flowEntry);
 
     /**
      * Pushes the collection of flow entries currently applied on the given
      * virtual device.
      *
-     * @param networkId the identity of the virtual network where this rule applies
      * @param deviceId device identifier
      * @param flowEntries collection of flow rules
      */
-    void pushFlowMetrics(NetworkId networkId, DeviceId deviceId,
-                         Iterable<FlowEntry> flowEntries);
+    void pushFlowMetrics(DeviceId deviceId, Iterable<FlowEntry> flowEntries);
 
     /**
      * Pushes the collection of flow entries currently applied on the given
      * device without flowMissing process.
      *
-     * @param networkId the identity of the virtual network where this rule applies
      * @param deviceId device identifier
      * @param flowEntries collection of flow rules
      */
-    void pushFlowMetricsWithoutFlowMissing(NetworkId networkId, DeviceId deviceId,
-                                           Iterable<FlowEntry> flowEntries);
+    void pushFlowMetricsWithoutFlowMissing(DeviceId deviceId, Iterable<FlowEntry> flowEntries);
 
     /**
      * Pushes the collection of table statistics entries currently extracted
      * from the given virtual device.
      *
-     * @param networkId the identity of the virtual network where this rule applies
      * @param deviceId device identifier
      * @param tableStatsEntries collection of flow table statistics entries
      */
-    void pushTableStatistics(NetworkId networkId, DeviceId deviceId,
-                             List<TableStatisticsEntry> tableStatsEntries);
+    void pushTableStatistics(DeviceId deviceId, List<TableStatisticsEntry> tableStatsEntries);
+
+    /**
+     * Indicates to the core that the requested batch operation has
+     * been completed.
+     *
+     * @param batchId the batch which was processed
+     * @param operation the resulting outcome of the operation
+     */
+    void batchOperationCompleted(long batchId, CompletedBatchOperation operation);
 
 }
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkProvider.java b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualNetworkProvider.java
similarity index 92%
rename from incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkProvider.java
rename to incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualNetworkProvider.java
index 104c9d3..9f05f15 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkProvider.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualNetworkProvider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2015-present Open Networking Laboratory
+ * Copyright 2016-present 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.
@@ -13,9 +13,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.incubator.net.virtual;
+package org.onosproject.incubator.net.virtual.provider;
 
 import org.onosproject.incubator.net.tunnel.TunnelId;
+import org.onosproject.incubator.net.virtual.NetworkId;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.provider.Provider;
 
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkProviderRegistry.java b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualNetworkProviderRegistry.java
similarity index 88%
rename from incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkProviderRegistry.java
rename to incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualNetworkProviderRegistry.java
index 9febbe4..465301f 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkProviderRegistry.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualNetworkProviderRegistry.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2015-present Open Networking Laboratory
+ * Copyright 2016-present 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.
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.incubator.net.virtual;
+package org.onosproject.incubator.net.virtual.provider;
 
 import org.onosproject.net.provider.ProviderRegistry;
 
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkProviderService.java b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualNetworkProviderService.java
similarity index 92%
rename from incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkProviderService.java
rename to incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualNetworkProviderService.java
index 50f0fc3..330e5e8 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkProviderService.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/provider/VirtualNetworkProviderService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2015-present Open Networking Laboratory
+ * Copyright 2016-present 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.
@@ -13,9 +13,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.incubator.net.virtual;
+package org.onosproject.incubator.net.virtual.provider;
 
 import org.onosproject.incubator.net.tunnel.TunnelId;
+import org.onosproject.incubator.net.virtual.NetworkId;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.provider.ProviderService;