Refactor Intent subsystem to eliminate using FlowRuleBatchOperation

Change-Id: Iee76dac5fa9935713ffc370b34ac47d9286ff351
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java b/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java
index 84969f8..2f1326fa 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java
@@ -15,8 +15,23 @@
  */
 package org.onosproject.net.intent.impl;
 
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.stream.Collectors;
+
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
@@ -27,9 +42,7 @@
 import org.onosproject.core.IdGenerator;
 import org.onosproject.event.AbstractListenerRegistry;
 import org.onosproject.event.EventDeliveryService;
-import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.FlowRuleBatchEntry;
-import org.onosproject.net.flow.FlowRuleBatchOperation;
+import org.onosproject.net.flow.FlowRuleOperation;
 import org.onosproject.net.flow.FlowRuleOperations;
 import org.onosproject.net.flow.FlowRuleOperationsContext;
 import org.onosproject.net.flow.FlowRuleService;
@@ -55,21 +68,8 @@
 import org.onosproject.net.intent.impl.phase.Withdrawn;
 import org.slf4j.Logger;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
-import java.util.stream.Collectors;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Preconditions.checkState;
@@ -77,7 +77,11 @@
 import static java.util.concurrent.Executors.newSingleThreadExecutor;
 import static org.onlab.util.Tools.groupedThreads;
 import static org.onlab.util.Tools.isNullOrEmpty;
-import static org.onosproject.net.intent.IntentState.*;
+import static org.onosproject.net.intent.IntentState.FAILED;
+import static org.onosproject.net.intent.IntentState.INSTALLED;
+import static org.onosproject.net.intent.IntentState.INSTALL_REQ;
+import static org.onosproject.net.intent.IntentState.WITHDRAWN;
+import static org.onosproject.net.intent.IntentState.WITHDRAW_REQ;
 import static org.slf4j.LoggerFactory.getLogger;
 
 /**
@@ -301,7 +305,7 @@
                    oldInstallables.size() == newInstallables.size(),
                    "Old and New Intent must have equivalent installable intents.");
 
-        List<List<FlowRuleBatchOperation>> plans = new ArrayList<>();
+        List<List<Set<FlowRuleOperation>>> plans = new ArrayList<>();
         for (int i = 0; i < newInstallables.size(); i++) {
             Intent newInstallable = newInstallables.get(i);
             registerSubclassInstallerIfNeeded(newInstallable);
@@ -359,7 +363,7 @@
     // TODO: make this non-public due to short term hack for ONOS-1051
     public FlowRuleOperations uninstallCoordinate(IntentData current, IntentData pending) {
         List<Intent> installables = current.installables();
-        List<List<FlowRuleBatchOperation>> plans = new ArrayList<>();
+        List<List<Set<FlowRuleOperation>>> plans = new ArrayList<>();
         for (Intent installable : installables) {
             plans.add(getInstaller(installable).uninstall(installable));
             trackerService.removeTrackedResources(pending.key(), installable.resources());
@@ -385,35 +389,22 @@
 
 
     // TODO needs tests... or maybe it's just perfect
-    private FlowRuleOperations.Builder merge(List<List<FlowRuleBatchOperation>> plans) {
+    private FlowRuleOperations.Builder merge(List<List<Set<FlowRuleOperation>>> plans) {
         FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
         // Build a batch one stage at a time
         for (int stageNumber = 0;; stageNumber++) {
-            // Get the sub-stage from each plan (List<FlowRuleBatchOperation>)
-            for (Iterator<List<FlowRuleBatchOperation>> itr = plans.iterator(); itr.hasNext();) {
-                List<FlowRuleBatchOperation> plan = itr.next();
+            // Get the sub-stage from each plan (List<Set<FlowRuleOperation>)
+            for (Iterator<List<Set<FlowRuleOperation>>> itr = plans.iterator(); itr.hasNext();) {
+                List<Set<FlowRuleOperation>> plan = itr.next();
                 if (plan.size() <= stageNumber) {
                     // we have consumed all stages from this plan, so remove it
                     itr.remove();
                     continue;
                 }
                 // write operations from this sub-stage into the builder
-                FlowRuleBatchOperation stage = plan.get(stageNumber);
-                for (FlowRuleBatchEntry entry : stage.getOperations()) {
-                    FlowRule rule = entry.target();
-                    switch (entry.operator()) {
-                        case ADD:
-                            builder.add(rule);
-                            break;
-                        case REMOVE:
-                            builder.remove(rule);
-                            break;
-                        case MODIFY:
-                            builder.modify(rule);
-                            break;
-                        default:
-                            break;
-                    }
+                Set<FlowRuleOperation> stage = plan.get(stageNumber);
+                for (FlowRuleOperation entry : stage) {
+                    builder.operation(entry);
                 }
             }
             // we are done with the stage, start the next one...
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/LinkCollectionIntentInstaller.java b/core/net/src/main/java/org/onosproject/net/intent/impl/LinkCollectionIntentInstaller.java
index cb6c6e4..ef6e8b5 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/LinkCollectionIntentInstaller.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/LinkCollectionIntentInstaller.java
@@ -15,9 +15,10 @@
  */
 package org.onosproject.net.intent.impl;
 
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.SetMultimap;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
@@ -34,19 +35,17 @@
 import org.onosproject.net.flow.DefaultTrafficSelector;
 import org.onosproject.net.flow.DefaultTrafficTreatment;
 import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.FlowRuleBatchEntry;
-import org.onosproject.net.flow.FlowRuleBatchEntry.FlowRuleOperation;
-import org.onosproject.net.flow.FlowRuleBatchOperation;
+import org.onosproject.net.flow.FlowRuleOperation;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
 import org.onosproject.net.intent.IntentExtensionService;
 import org.onosproject.net.intent.IntentInstaller;
 import org.onosproject.net.intent.LinkCollectionIntent;
 
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import java.util.stream.Collectors;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.SetMultimap;
 
 /**
  * Installer for {@link org.onosproject.net.intent.LinkCollectionIntent} path
@@ -76,17 +75,17 @@
     }
 
     @Override
-    public List<FlowRuleBatchOperation> install(LinkCollectionIntent intent) {
-        return generateBatchOperations(intent, FlowRuleOperation.ADD);
+    public List<Set<FlowRuleOperation>> install(LinkCollectionIntent intent) {
+        return generateBatchOperations(intent, FlowRuleOperation.Type.ADD);
     }
 
     @Override
-    public List<FlowRuleBatchOperation> uninstall(LinkCollectionIntent intent) {
-        return generateBatchOperations(intent, FlowRuleOperation.REMOVE);
+    public List<Set<FlowRuleOperation>> uninstall(LinkCollectionIntent intent) {
+        return generateBatchOperations(intent, FlowRuleOperation.Type.REMOVE);
     }
 
-    private List<FlowRuleBatchOperation> generateBatchOperations(
-            LinkCollectionIntent intent, FlowRuleOperation operation) {
+    private List<Set<FlowRuleOperation>> generateBatchOperations(
+            LinkCollectionIntent intent, FlowRuleOperation.Type operation) {
 
         SetMultimap<DeviceId, PortNumber> outputPorts = HashMultimap.create();
 
@@ -99,23 +98,33 @@
         }
 
         //FIXME change to new api
-        FlowRuleBatchOperation batchOperation =
-                new FlowRuleBatchOperation(outputPorts
+        /* Fear of streams */
+        /*
+        Set<FlowRuleBatchEntry> rules = Sets.newHashSet();
+        for (DeviceId deviceId : outputPorts.keys()) {
+            rules.add(createBatchEntry(operation,
+                      intent, deviceId,
+                      outputPorts.get(deviceId)));
+        }
+        */
+
+        Set<FlowRuleOperation> rules =
+                outputPorts
                         .keys()
                         .stream()
                         .map(deviceId -> createBatchEntry(operation,
-                                                   intent, deviceId,
-                                                   outputPorts.get(deviceId)))
-                        .collect(Collectors.toList()), null, 0);
+                                intent, deviceId,
+                                outputPorts.get(deviceId)))
+                        .collect(Collectors.toSet());
 
-        return Collections.singletonList(batchOperation);
+        return Lists.newArrayList(ImmutableSet.of(rules));
     }
 
     @Override
-    public List<FlowRuleBatchOperation> replace(LinkCollectionIntent oldIntent,
+    public List<Set<FlowRuleOperation>> replace(LinkCollectionIntent oldIntent,
                                                 LinkCollectionIntent newIntent) {
         // FIXME: implement this in a more intelligent/less brute force way
-        List<FlowRuleBatchOperation> batches = Lists.newArrayList();
+        List<Set<FlowRuleOperation>> batches = Lists.newArrayList();
         batches.addAll(uninstall(oldIntent));
         batches.addAll(install(newIntent));
         return batches;
@@ -130,10 +139,10 @@
      * @param outPorts the set of output ports for the flow rule
      * @return the new flow rule batch entry
      */
-    private FlowRuleBatchEntry createBatchEntry(FlowRuleOperation operation,
-                                                LinkCollectionIntent intent,
-                                                DeviceId deviceId,
-                                                Set<PortNumber> outPorts) {
+    private FlowRuleOperation createBatchEntry(FlowRuleOperation.Type operation,
+                                               LinkCollectionIntent intent,
+                                               DeviceId deviceId,
+                                               Set<PortNumber> outPorts) {
 
         TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment
                 .builder(intent.treatment());
@@ -151,6 +160,6 @@
                 new DefaultGroupId((short) (intent.id().fingerprint() & 0xffff)),
                 0, true);
 
-        return new FlowRuleBatchEntry(operation, rule);
+        return new FlowRuleOperation(rule, operation);
     }
 }
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/MplsPathIntentInstaller.java b/core/net/src/main/java/org/onosproject/net/intent/impl/MplsPathIntentInstaller.java
index 09c6551..9ad1fe5 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/MplsPathIntentInstaller.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/MplsPathIntentInstaller.java
@@ -1,7 +1,5 @@
 package org.onosproject.net.intent.impl;
 
-import static org.slf4j.LoggerFactory.getLogger;
-
 import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
@@ -22,11 +20,9 @@
 import org.onosproject.net.flow.DefaultTrafficSelector;
 import org.onosproject.net.flow.DefaultTrafficTreatment;
 import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.FlowRuleBatchEntry;
-import org.onosproject.net.flow.FlowRuleBatchOperation;
+import org.onosproject.net.flow.FlowRuleOperation;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.flow.FlowRuleBatchEntry.FlowRuleOperation;
 import org.onosproject.net.flow.criteria.Criteria.EthTypeCriterion;
 import org.onosproject.net.flow.criteria.Criterion;
 import org.onosproject.net.flow.criteria.Criterion.Type;
@@ -44,11 +40,13 @@
 import org.onosproject.net.resource.ResourceType;
 import org.slf4j.Logger;
 
-import static com.google.common.base.Preconditions.checkNotNull;
-
+import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
+
 /**
  * Installer for {@link MplsPathIntent packet path connectivity intents}.
  */
@@ -83,29 +81,26 @@
     }
 
     @Override
-    public List<FlowRuleBatchOperation> install(MplsPathIntent intent) {
+    public List<Set<FlowRuleOperation>> install(MplsPathIntent intent) {
         LinkResourceAllocations allocations = assignMplsLabel(intent);
-        return generateRules(intent, allocations, FlowRuleOperation.ADD);
+        return generateRules(intent, allocations, FlowRuleOperation.Type.ADD);
 
     }
 
     @Override
-    public List<FlowRuleBatchOperation> uninstall(MplsPathIntent intent) {
+    public List<Set<FlowRuleOperation>> uninstall(MplsPathIntent intent) {
         LinkResourceAllocations allocations = resourceService
                 .getAllocations(intent.id());
         resourceService.releaseResources(allocations);
 
-        List<FlowRuleBatchOperation> rules = generateRules(intent,
-                                                           allocations,
-                                                           FlowRuleOperation.REMOVE);
-        return rules;
+        return generateRules(intent, allocations, FlowRuleOperation.Type.REMOVE);
     }
 
     @Override
-    public List<FlowRuleBatchOperation> replace(MplsPathIntent oldIntent,
-                                                MplsPathIntent newIntent) {
+    public List<Set<FlowRuleOperation>> replace(MplsPathIntent oldIntent,
+                                                 MplsPathIntent newIntent) {
 
-        List<FlowRuleBatchOperation> batches = Lists.newArrayList();
+        List<Set<FlowRuleOperation>> batches = Lists.newArrayList();
         batches.addAll(uninstall(oldIntent));
         batches.addAll(install(newIntent));
         return batches;
@@ -145,9 +140,9 @@
         return null;
     }
 
-    private List<FlowRuleBatchOperation> generateRules(MplsPathIntent intent,
+    private List<Set<FlowRuleOperation>> generateRules(MplsPathIntent intent,
                                                        LinkResourceAllocations allocations,
-                                                       FlowRuleOperation operation) {
+                                                       FlowRuleOperation.Type operation) {
 
         Iterator<Link> links = intent.path().links().iterator();
         Link srcLink = links.next();
@@ -155,7 +150,7 @@
 
         Link link = links.next();
         // List of flow rules to be installed
-        List<FlowRuleBatchEntry> rules = Lists.newLinkedList();
+        Set<FlowRuleOperation> rules = Sets.newHashSet();
 
         // Ingress traffic
         // Get the new MPLS label
@@ -187,13 +182,13 @@
 
             prev = link.dst();
         }
-        return Lists.newArrayList(new FlowRuleBatchOperation(rules, null, 0));
+        return Lists.newArrayList(ImmutableSet.of(rules));
     }
 
-    private FlowRuleBatchEntry ingressFlow(PortNumber inPort, Link link,
+    private FlowRuleOperation ingressFlow(PortNumber inPort, Link link,
                                            MplsPathIntent intent,
                                            MplsLabel label,
-                                           FlowRuleOperation operation) {
+                                           FlowRuleOperation.Type operation) {
 
         TrafficSelector.Builder ingressSelector = DefaultTrafficSelector
                 .builder(intent.selector());
@@ -213,16 +208,16 @@
         // Add the output action
         treat.setOutput(link.src().port());
 
-        return flowRuleBatchEntry(intent, link.src().deviceId(),
-                                  ingressSelector.build(), treat.build(),
-                                  operation);
+        return flowRuleOperation(intent, link.src().deviceId(),
+                ingressSelector.build(), treat.build(),
+                operation);
     }
 
-    private FlowRuleBatchEntry transitFlow(PortNumber inPort, Link link,
+    private FlowRuleOperation transitFlow(PortNumber inPort, Link link,
                                            MplsPathIntent intent,
                                            MplsLabel prevLabel,
                                            MplsLabel outLabel,
-                                           FlowRuleOperation operation) {
+                                           FlowRuleOperation.Type operation) {
 
         // Ignore the ingress Traffic Selector and use only the MPLS label
         // assigned in the previous link
@@ -238,14 +233,14 @@
         }
 
         treat.setOutput(link.src().port());
-        return flowRuleBatchEntry(intent, link.src().deviceId(),
-                                  selector.build(), treat.build(), operation);
+        return flowRuleOperation(intent, link.src().deviceId(),
+                selector.build(), treat.build(), operation);
     }
 
-    private FlowRuleBatchEntry egressFlow(PortNumber inPort, Link link,
+    private FlowRuleOperation egressFlow(PortNumber inPort, Link link,
                                           MplsPathIntent intent,
                                           MplsLabel prevLabel,
-                                          FlowRuleOperation operation) {
+                                          FlowRuleOperation.Type operation) {
         // egress point: either set the egress MPLS label or pop the
         // MPLS label based on the intent annotations
 
@@ -272,15 +267,15 @@
 
         }
         treat.setOutput(link.src().port());
-        return flowRuleBatchEntry(intent, link.src().deviceId(),
-                                  selector.build(), treat.build(), operation);
+        return flowRuleOperation(intent, link.src().deviceId(),
+                selector.build(), treat.build(), operation);
     }
 
-    protected FlowRuleBatchEntry flowRuleBatchEntry(MplsPathIntent intent,
+    protected FlowRuleOperation flowRuleOperation(MplsPathIntent intent,
                                                     DeviceId deviceId,
                                                     TrafficSelector selector,
                                                     TrafficTreatment treat,
-                                                    FlowRuleOperation operation) {
+                                                    FlowRuleOperation.Type operation) {
         FlowRule rule = new DefaultFlowRule(
                                             deviceId,
                                             selector,
@@ -289,8 +284,7 @@
                                             appId,
                                             0,
                                             true);
-        return new FlowRuleBatchEntry(operation, rule, intent.id()
-                .fingerprint());
+        return new FlowRuleOperation(rule, operation);
 
     }
 }
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/OpticalPathIntentInstaller.java b/core/net/src/main/java/org/onosproject/net/intent/impl/OpticalPathIntentInstaller.java
index 5b226a3..e2dc0d4 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/OpticalPathIntentInstaller.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/OpticalPathIntentInstaller.java
@@ -15,7 +15,9 @@
  */
 package org.onosproject.net.intent.impl;
 
-import com.google.common.collect.Lists;
+import java.util.List;
+import java.util.Set;
+
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
@@ -29,9 +31,7 @@
 import org.onosproject.net.flow.DefaultTrafficSelector;
 import org.onosproject.net.flow.DefaultTrafficTreatment;
 import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.FlowRuleBatchEntry;
-import org.onosproject.net.flow.FlowRuleBatchEntry.FlowRuleOperation;
-import org.onosproject.net.flow.FlowRuleBatchOperation;
+import org.onosproject.net.flow.FlowRuleOperation;
 import org.onosproject.net.flow.FlowRuleService;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
@@ -49,7 +49,9 @@
 import org.onosproject.net.topology.TopologyService;
 import org.slf4j.Logger;
 
-import java.util.List;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
 
 import static org.onosproject.net.flow.DefaultTrafficTreatment.builder;
 import static org.slf4j.LoggerFactory.getLogger;
@@ -92,24 +94,24 @@
     }
 
     @Override
-    public List<FlowRuleBatchOperation> install(OpticalPathIntent intent) {
+    public List<Set<FlowRuleOperation>> install(OpticalPathIntent intent) {
         LinkResourceAllocations allocations = assignWavelength(intent);
-        return generateRules(intent, allocations, FlowRuleOperation.ADD);
+        return generateRules(intent, allocations, FlowRuleOperation.Type.ADD);
     }
 
     @Override
-    public List<FlowRuleBatchOperation> uninstall(OpticalPathIntent intent) {
+    public List<Set<FlowRuleOperation>> uninstall(OpticalPathIntent intent) {
         LinkResourceAllocations allocations = resourceService.getAllocations(intent.id());
-        List<FlowRuleBatchOperation> rules = generateRules(intent, allocations, FlowRuleOperation.REMOVE);
+        List<Set<FlowRuleOperation>> rules = generateRules(intent, allocations, FlowRuleOperation.Type.REMOVE);
         log.info("uninstall rules: {}", rules);
         return rules;
     }
 
     @Override
-    public List<FlowRuleBatchOperation> replace(OpticalPathIntent oldIntent,
+    public List<Set<FlowRuleOperation>> replace(OpticalPathIntent oldIntent,
                                                 OpticalPathIntent newIntent) {
         // FIXME: implement this
-        List<FlowRuleBatchOperation> batches = Lists.newArrayList();
+        List<Set<FlowRuleOperation>> batches = Lists.newArrayList();
         batches.addAll(uninstall(oldIntent));
         batches.addAll(install(newIntent));
         return batches;
@@ -123,13 +125,13 @@
         return retLambda;
     }
 
-    private List<FlowRuleBatchOperation> generateRules(OpticalPathIntent intent,
-                                                       LinkResourceAllocations allocations,
-                                                       FlowRuleOperation operation) {
+    private List<Set<FlowRuleOperation>> generateRules(OpticalPathIntent intent,
+                                                        LinkResourceAllocations allocations,
+                                                        FlowRuleOperation.Type operation) {
         TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
         selectorBuilder.matchInPort(intent.src().port());
 
-        List<FlowRuleBatchEntry> rules = Lists.newLinkedList();
+        Set<FlowRuleOperation> rules = Sets.newHashSet();
         ConnectPoint prev = intent.src();
 
         //FIXME check for null allocations
@@ -160,7 +162,7 @@
                                                 100,
                                                 true);
 
-            rules.add(new FlowRuleBatchEntry(operation, rule));
+            rules.add(new FlowRuleOperation(rule, operation));
 
             prev = link.dst();
             selectorBuilder.matchInPort(link.dst().port());
@@ -179,9 +181,9 @@
                                             appId,
                                             100,
                                             true);
-        rules.add(new FlowRuleBatchEntry(operation, rule));
+        rules.add(new FlowRuleOperation(rule, operation));
 
         //FIXME change to new api
-        return Lists.newArrayList(new FlowRuleBatchOperation(rules, null, 0));
+        return Lists.newArrayList(ImmutableSet.of(rules));
     }
 }
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/PathIntentInstaller.java b/core/net/src/main/java/org/onosproject/net/intent/impl/PathIntentInstaller.java
index b29bb08..65b6314 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/PathIntentInstaller.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/PathIntentInstaller.java
@@ -17,6 +17,7 @@
 
 import java.util.Iterator;
 import java.util.List;
+import java.util.Set;
 
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
@@ -31,9 +32,7 @@
 import org.onosproject.net.flow.DefaultFlowRule;
 import org.onosproject.net.flow.DefaultTrafficSelector;
 import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.FlowRuleBatchEntry;
-import org.onosproject.net.flow.FlowRuleBatchEntry.FlowRuleOperation;
-import org.onosproject.net.flow.FlowRuleBatchOperation;
+import org.onosproject.net.flow.FlowRuleOperation;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
 import org.onosproject.net.intent.Constraint;
@@ -46,7 +45,9 @@
 import org.onosproject.net.resource.LinkResourceService;
 import org.slf4j.Logger;
 
+import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
 
 import static org.onosproject.net.flow.DefaultTrafficTreatment.builder;
 import static org.slf4j.LoggerFactory.getLogger;
@@ -82,14 +83,14 @@
     }
 
     @Override
-    public List<FlowRuleBatchOperation> install(PathIntent intent) {
+    public List<Set<FlowRuleOperation>> install(PathIntent intent) {
         LinkResourceAllocations allocations = allocateResources(intent);
 
         TrafficSelector.Builder builder =
                 DefaultTrafficSelector.builder(intent.selector());
         Iterator<Link> links = intent.path().links().iterator();
         ConnectPoint prev = links.next().dst();
-        List<FlowRuleBatchEntry> rules = Lists.newLinkedList();
+        Set<FlowRuleOperation> rules = Sets.newHashSet();
         // TODO Generate multiple batches
         while (links.hasNext()) {
             builder.matchInPort(prev.port());
@@ -104,23 +105,21 @@
                     appId,
                     new DefaultGroupId((short) (intent.id().fingerprint() & 0xffff)),
                     0, true);
-            rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule,
-                                             intent.id().fingerprint()));
+            rules.add(new FlowRuleOperation(rule, FlowRuleOperation.Type.ADD));
             prev = link.dst();
         }
-        //FIXME this should change to new api.
-        return Lists.newArrayList(new FlowRuleBatchOperation(rules, null, 0));
+
+        return Lists.newArrayList(ImmutableSet.of(rules));
     }
 
     @Override
-    public List<FlowRuleBatchOperation> uninstall(PathIntent intent) {
+    public List<Set<FlowRuleOperation>> uninstall(PathIntent intent) {
         deallocateResources(intent);
-
         TrafficSelector.Builder builder =
                 DefaultTrafficSelector.builder(intent.selector());
         Iterator<Link> links = intent.path().links().iterator();
         ConnectPoint prev = links.next().dst();
-        List<FlowRuleBatchEntry> rules = Lists.newLinkedList();
+        Set<FlowRuleOperation> rules = Sets.newHashSet();
         // TODO Generate multiple batches
         while (links.hasNext()) {
             builder.matchInPort(prev.port());
@@ -133,18 +132,17 @@
                     builder.build(), treatment, 123, appId,
                     new DefaultGroupId((short) (intent.id().fingerprint() & 0xffff)),
                     0, true);
-            rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, rule,
-                                             intent.id().fingerprint()));
+            rules.add(new FlowRuleOperation(rule, FlowRuleOperation.Type.REMOVE));
             prev = link.dst();
         }
         // FIXME this should change to new api
-        return Lists.newArrayList(new FlowRuleBatchOperation(rules, null, 0));
+        return Lists.newArrayList(ImmutableSet.of(rules));
     }
 
     @Override
-    public List<FlowRuleBatchOperation> replace(PathIntent oldIntent, PathIntent newIntent) {
+    public List<Set<FlowRuleOperation>> replace(PathIntent oldIntent, PathIntent newIntent) {
         // FIXME: implement this
-        List<FlowRuleBatchOperation> batches = Lists.newArrayList();
+        List<Set<FlowRuleOperation>> batches = Lists.newArrayList();
         batches.addAll(uninstall(oldIntent));
         batches.addAll(install(newIntent));
         return batches;