fix: (vnet) sync batch flow rule batch operation

The current version of flow rule provider always returned success
regradless of physical flow rule's installation.
This commit makes to enable to  sync with virtual and physical rule
batch operation

Change-Id: I1c9bfc30d23e0e7b24bf8be8774f67e304f3b28e
diff --git a/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualFlowRuleProvider.java b/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualFlowRuleProvider.java
index 69f764e..4f9a8ff 100644
--- a/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualFlowRuleProvider.java
+++ b/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualFlowRuleProvider.java
@@ -18,6 +18,8 @@
 
 import com.google.common.collect.HashBasedTable;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 import com.google.common.collect.Table;
@@ -47,6 +49,7 @@
 import org.onosproject.net.Path;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.BatchOperationEntry;
 import org.onosproject.net.flow.CompletedBatchOperation;
 import org.onosproject.net.flow.DefaultFlowEntry;
 import org.onosproject.net.flow.DefaultFlowRule;
@@ -58,6 +61,8 @@
 import org.onosproject.net.flow.FlowRuleBatchOperation;
 import org.onosproject.net.flow.FlowRuleEvent;
 import org.onosproject.net.flow.FlowRuleListener;
+import org.onosproject.net.flow.FlowRuleOperations;
+import org.onosproject.net.flow.FlowRuleOperationsContext;
 import org.onosproject.net.flow.FlowRuleService;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
@@ -127,7 +132,6 @@
         super(new ProviderId("vnet-flow", "org.onosproject.virtual.vnet-flow"));
     }
 
-
     @Activate
     public void activate() {
         appId = coreService.registerApplication(APP_ID_STR);
@@ -177,32 +181,56 @@
         checkNotNull(batch);
 
         for (FlowRuleBatchEntry fop : batch.getOperations()) {
+            FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
+
             switch (fop.operator()) {
                 case ADD:
-                    devirtualize(networkId, fop.target())
-                            .forEach(f -> flowRuleService.applyFlowRules(f));
+                    devirtualize(networkId, fop.target()).forEach(builder::add);
                     break;
                 case REMOVE:
-                    devirtualize(networkId, fop.target())
-                            .forEach(f -> flowRuleService.removeFlowRules(f));
+                    devirtualize(networkId, fop.target()).forEach(builder::remove);
                     break;
                 case MODIFY:
+                    devirtualize(networkId, fop.target()).forEach(builder::modify);
                     break;
                 default:
                     break;
             }
+
+            flowRuleService.apply(builder.build(new FlowRuleOperationsContext() {
+                @Override
+                public void onSuccess(FlowRuleOperations ops) {
+                    CompletedBatchOperation status =
+                            new CompletedBatchOperation(true,
+                                                        Sets.newConcurrentHashSet(),
+                                                        batch.deviceId());
+
+                    VirtualFlowRuleProviderService providerService =
+                            (VirtualFlowRuleProviderService) providerRegistryService
+                                    .getProviderService(networkId,
+                                                        VirtualFlowRuleProvider.class);
+                    providerService.batchOperationCompleted(batch.id(), status);
+                }
+
+                @Override
+                public void onError(FlowRuleOperations ops) {
+                    Set<FlowRule> failures = ImmutableSet.copyOf(
+                            Lists.transform(batch.getOperations(),
+                                            BatchOperationEntry::target));
+
+                    CompletedBatchOperation status =
+                            new CompletedBatchOperation(false,
+                                                        failures,
+                                                        batch.deviceId());
+
+                    VirtualFlowRuleProviderService providerService =
+                            (VirtualFlowRuleProviderService) providerRegistryService
+                                    .getProviderService(networkId,
+                                                        VirtualFlowRuleProvider.class);
+                    providerService.batchOperationCompleted(batch.id(), status);
+                }
+            }));
         }
-
-        //FIXME: check the success of the all batch operations
-        CompletedBatchOperation status =
-                new CompletedBatchOperation(true, Sets.newConcurrentHashSet(),
-                                            batch.deviceId());
-
-        VirtualFlowRuleProviderService providerService =
-                (VirtualFlowRuleProviderService) providerRegistryService
-                        .getProviderService(networkId,
-                                            VirtualFlowRuleProvider.class);
-        providerService.batchOperationCompleted(batch.id(), status);
     }
 
     public void setEmbeddingAlgorithm(InternalRoutingAlgorithm
@@ -243,7 +271,6 @@
                                                 flowEntry.life(),
                                                 flowEntry.packets(),
                                                 flowEntry.bytes());
-
         return vEntry;
     }
 
diff --git a/incubator/store/src/main/java/org/onosproject/incubator/store/virtual/impl/SimpleVirtualFlowRuleStore.java b/incubator/store/src/main/java/org/onosproject/incubator/store/virtual/impl/SimpleVirtualFlowRuleStore.java
index 0952574..4b22d9e 100644
--- a/incubator/store/src/main/java/org/onosproject/incubator/store/virtual/impl/SimpleVirtualFlowRuleStore.java
+++ b/incubator/store/src/main/java/org/onosproject/incubator/store/virtual/impl/SimpleVirtualFlowRuleStore.java
@@ -214,13 +214,14 @@
         }
 
         SettableFuture<CompletedBatchOperation> r = SettableFuture.create();
-        final int batchId = localBatchIdGen.incrementAndGet();
+        final int futureId = localBatchIdGen.incrementAndGet();
 
-        pendingFutures.put(batchId, r);
+        pendingFutures.put(futureId, r);
 
         toAdd.addAll(toRemove);
         notifyDelegate(networkId, FlowRuleBatchEvent.requested(
-                new FlowRuleBatchRequest(batchId, Sets.newHashSet(toAdd)), batchOperation.deviceId()));
+                new FlowRuleBatchRequest(batchOperation.id(),
+                                         Sets.newHashSet(toAdd)), batchOperation.deviceId()));
 
     }