Update FlowManager's API design and define batch operation map's API.

- FlowManager returns FlowBatchHandle as a handler to the batch execution.
 -- addFlow(), removeFlow() and executeBatch() methods are executed asynchronously.
 -- Users can get the current state of the batch via the FlowBatchHandle.
- Defined FlowOperationMap's inital API designs.

This task is a part of ONOS-1687, ONOS-1842, and ONOS-1692.

Change-Id: Ic9e8ce3ab0378615d9d3016b7755ee6d15e1e47c
diff --git a/src/main/java/net/onrc/onos/api/flowmanager/FlowBatchHandle.java b/src/main/java/net/onrc/onos/api/flowmanager/FlowBatchHandle.java
index 166a12f..351d9e9 100644
--- a/src/main/java/net/onrc/onos/api/flowmanager/FlowBatchHandle.java
+++ b/src/main/java/net/onrc/onos/api/flowmanager/FlowBatchHandle.java
@@ -1,9 +1,13 @@
 package net.onrc.onos.api.flowmanager;
 
+import net.onrc.onos.core.flowmanager.FlowOperationMap;
+
+
 /**
  * Handle class to handle flow batch operation.
  */
 public class FlowBatchHandle {
+    private final FlowOperationMap flowOperationMap;
     private final FlowBatchId batchId;
 
     /**
@@ -12,9 +16,12 @@
      * The ID is automatically generated and assigned by FlowManager, and used
      * as an internal key for the flow batch operation map.
      *
+     * @param opMap the FlowOperationMap object which maintains the flow batch
+     *        operation
      * @param id the batch operation ID
      */
-    public FlowBatchHandle(FlowBatchId id) {
+    public FlowBatchHandle(FlowOperationMap opMap, FlowBatchId id) {
+        flowOperationMap = opMap;
         batchId = id;
     }
 
@@ -26,4 +33,8 @@
     public FlowBatchId getBatchOperationId() {
         return batchId;
     }
+
+    public FlowBatchState getState() {
+        return flowOperationMap.getState(batchId);
+    }
 }
diff --git a/src/main/java/net/onrc/onos/api/flowmanager/FlowBatchState.java b/src/main/java/net/onrc/onos/api/flowmanager/FlowBatchState.java
index fd62a97..9205476 100644
--- a/src/main/java/net/onrc/onos/api/flowmanager/FlowBatchState.java
+++ b/src/main/java/net/onrc/onos/api/flowmanager/FlowBatchState.java
@@ -1,5 +1,6 @@
 package net.onrc.onos.api.flowmanager;
 
+
 /**
  * Represents the state of {@link FlowBatchOperation}.
  */
diff --git a/src/main/java/net/onrc/onos/api/flowmanager/FlowManagerListener.java b/src/main/java/net/onrc/onos/api/flowmanager/FlowManagerListener.java
index 0e70867..90ed2ca 100644
--- a/src/main/java/net/onrc/onos/api/flowmanager/FlowManagerListener.java
+++ b/src/main/java/net/onrc/onos/api/flowmanager/FlowManagerListener.java
@@ -1,5 +1,6 @@
 package net.onrc.onos.api.flowmanager;
 
+
 /**
  * An interface to the FlowManager's listener.
  */
diff --git a/src/main/java/net/onrc/onos/api/flowmanager/FlowManagerService.java b/src/main/java/net/onrc/onos/api/flowmanager/FlowManagerService.java
index 4812de2..347c5fa 100644
--- a/src/main/java/net/onrc/onos/api/flowmanager/FlowManagerService.java
+++ b/src/main/java/net/onrc/onos/api/flowmanager/FlowManagerService.java
@@ -15,20 +15,26 @@
  */
 public interface FlowManagerService {
     /**
-     * Adds Flow object, calculates match-action plan and executes it.
+     * Adds Flow object, calculates match-action plan and executes it
+     * asynchronously.
+     * <p>
+     * To track the execution result, use the returned FlowBatchHandle object.
      *
      * @param flow Flow object to be added
-     * @return true if succeeded, false otherwise
+     * @return FlowBatchHandle object if succeeded, null otherwise
      */
-    boolean addFlow(Flow flow);
+    FlowBatchHandle addFlow(Flow flow);
 
     /**
-     * Removes Flow object, calculates match-action plan and executes it.
+     * Removes Flow object, calculates match-action plan and executes it
+     * asynchronously.
+     * <p>
+     * To track the execution result, use the returned FlowBatchHandle object.
      *
      * @param id ID for Flow object to be removed
-     * @return true if succeeded, false otherwise
+     * @return FlowBatchHandle object if succeeded, null otherwise
      */
-    boolean removeFlow(FlowId id);
+    FlowBatchHandle removeFlow(FlowId id);
 
     /**
      * Gets Flow object.
@@ -46,12 +52,14 @@
     Collection<Flow> getFlows();
 
     /**
-     * Executes batch operation of Flow object.
+     * Executes batch operation of Flow object asynchronously.
+     * <p>
+     * To track the execution result, use the returned FlowBatchHandle object.
      *
      * @param ops flow operations to be executed
-     * @return true if succeeded, false otherwise
+     * @return FlowBatchHandle object if succeeded, null otherwise
      */
-    boolean executeBatch(FlowBatchOperation ops);
+    FlowBatchHandle executeBatch(FlowBatchOperation ops);
 
     /**
      * Sets a conflict detection policy.
diff --git a/src/main/java/net/onrc/onos/core/flowmanager/FlowManagerModule.java b/src/main/java/net/onrc/onos/core/flowmanager/FlowManagerModule.java
index 8336095..235e38a 100644
--- a/src/main/java/net/onrc/onos/core/flowmanager/FlowManagerModule.java
+++ b/src/main/java/net/onrc/onos/core/flowmanager/FlowManagerModule.java
@@ -4,6 +4,7 @@
 
 import net.onrc.onos.api.flowmanager.ConflictDetectionPolicy;
 import net.onrc.onos.api.flowmanager.Flow;
+import net.onrc.onos.api.flowmanager.FlowBatchHandle;
 import net.onrc.onos.api.flowmanager.FlowBatchOperation;
 import net.onrc.onos.api.flowmanager.FlowId;
 import net.onrc.onos.api.flowmanager.FlowManagerListener;
@@ -17,23 +18,25 @@
  */
 public class FlowManagerModule implements FlowManagerService {
     private ConflictDetectionPolicy conflictDetectionPolicy;
+    private FlowOperationMap flowOperationMap;
 
     /**
      * Constructor.
      */
     public FlowManagerModule() {
         this.conflictDetectionPolicy = ConflictDetectionPolicy.FREE;
+        this.flowOperationMap = new FlowOperationMap();
     }
 
     @Override
-    public boolean addFlow(Flow flow) {
+    public FlowBatchHandle addFlow(Flow flow) {
         FlowBatchOperation ops = new FlowBatchOperation();
         ops.addAddFlowOperation(flow);
         return executeBatch(ops);
     }
 
     @Override
-    public boolean removeFlow(FlowId id) {
+    public FlowBatchHandle removeFlow(FlowId id) {
         FlowBatchOperation ops = new FlowBatchOperation();
         ops.addRemoveFlowOperation(id);
         return executeBatch(ops);
@@ -52,9 +55,15 @@
     }
 
     @Override
-    public boolean executeBatch(FlowBatchOperation ops) {
-        // TODO Auto-generated method stub
-        return false;
+    public FlowBatchHandle executeBatch(FlowBatchOperation ops) {
+        // This method just put the batch-operation object to the global
+        // flow operation map with unique ID. The leader process will get
+        // the appended operation with events notified from the map.
+        FlowBatchHandle handler = flowOperationMap.putOperation(ops);
+
+        // Then it will return a handler to obtain the result of this operation,
+        // control the executing process, etc.
+        return handler;
     }
 
     @Override
diff --git a/src/main/java/net/onrc/onos/core/flowmanager/FlowOperationMap.java b/src/main/java/net/onrc/onos/core/flowmanager/FlowOperationMap.java
index 744c65e..e9d66c3 100644
--- a/src/main/java/net/onrc/onos/core/flowmanager/FlowOperationMap.java
+++ b/src/main/java/net/onrc/onos/core/flowmanager/FlowOperationMap.java
@@ -1,8 +1,49 @@
 package net.onrc.onos.core.flowmanager;
 
+import net.onrc.onos.api.flowmanager.FlowBatchHandle;
+import net.onrc.onos.api.flowmanager.FlowBatchId;
+import net.onrc.onos.api.flowmanager.FlowBatchOperation;
+import net.onrc.onos.api.flowmanager.FlowBatchState;
+
 /**
  * Manages the set of flow operations throughout the ONOS instances.
  */
 public class FlowOperationMap {
-    // TODO implement it
+    public FlowBatchHandle putOperation(FlowBatchOperation ops) {
+        FlowBatchId id = getUniqueBatchOperationId();
+        if (id == null) {
+            return null;
+        }
+        if (putBatchOperation(id, ops)) {
+            return null;
+        }
+
+        return new FlowBatchHandle(this, id);
+    }
+
+    public void setState(long id, FlowBatchState state) {
+        // TODO implement it
+    }
+
+    public FlowBatchOperation getOperation(long id) {
+        // TODO implement it
+        return null;
+    }
+
+    public FlowBatchState getState(FlowBatchId id) {
+        // TODO implement it
+        return null;
+    }
+
+    // ====== private methods
+
+    private FlowBatchId getUniqueBatchOperationId() {
+        // TODO implement it
+        return null;
+    }
+
+    private boolean putBatchOperation(FlowBatchId id, FlowBatchOperation ops) {
+        // TODO implement it
+        return false;
+    }
 }