Refactored intent framework to deal with batches.

There is still work to be done, but for now, submit, withdraw and reroute are working.

Change-Id: Ib94cf8c4be03786cc070f402d1f296f5dfa6588b
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/BatchOperation.java b/core/api/src/main/java/org/onlab/onos/net/flow/BatchOperation.java
index 16ce184..6fd16b9 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/BatchOperation.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/BatchOperation.java
@@ -15,13 +15,13 @@
  */
 package org.onlab.onos.net.flow;
 
-import static com.google.common.base.Preconditions.checkNotNull;
-
 import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+
 /**
  * A list of BatchOperationEntry.
  *
@@ -88,6 +88,16 @@
         return ops.add(entry) ? this : null;
     }
 
+    /**
+     * Add all operations from another batch to this batch.
+     *
+     * @param another another batch
+     * @return true if success
+     */
+    public boolean addAll(BatchOperation<T> another) {
+        return ops.addAll(another.getOperations());
+    }
+
     @Override
     public boolean equals(Object o) {
         if (this == o) {
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/CompletedBatchOperation.java b/core/api/src/main/java/org/onlab/onos/net/flow/CompletedBatchOperation.java
index 3758ea9..b988744 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/CompletedBatchOperation.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/CompletedBatchOperation.java
@@ -19,12 +19,20 @@
 
 import com.google.common.collect.ImmutableSet;
 
+/**
+ * Representation of a completed flow rule batch operation.
+ */
 public class CompletedBatchOperation implements BatchOperationResult<FlowRule> {
 
-
     private final boolean success;
     private final Set<FlowRule> failures;
 
+    /**
+     * Creates a new batch completion result.
+     *
+     * @param success  indicates whether the completion is successful.
+     * @param failures set of any failures encountered
+     */
     public CompletedBatchOperation(boolean success, Set<? extends FlowRule> failures) {
         this.success = success;
         this.failures = ImmutableSet.copyOf(failures);
@@ -40,5 +48,4 @@
         return failures;
     }
 
-
 }
diff --git a/core/api/src/main/java/org/onlab/onos/net/intent/IntentBatchDelegate.java b/core/api/src/main/java/org/onlab/onos/net/intent/IntentBatchDelegate.java
new file mode 100644
index 0000000..248d82e
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/intent/IntentBatchDelegate.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2014 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.onlab.onos.net.intent;
+
+/**
+ * Facade for receiving notifications from the intent batch service.
+ */
+public interface IntentBatchDelegate {
+
+    /**
+     * Submits the specified batch of intent operations for processing.
+     *
+     * @param operations batch of operations
+     */
+    void execute(IntentOperations operations);
+
+    /**
+     * Cancesl the specified batch of intent operations.
+     *
+     * @param operations batch of operations to be cancelled
+     */
+    void cancel(IntentOperations operations);
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/intent/IntentBatchService.java b/core/api/src/main/java/org/onlab/onos/net/intent/IntentBatchService.java
new file mode 100644
index 0000000..37a1d4a
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/intent/IntentBatchService.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2014 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.onlab.onos.net.intent;
+
+import java.util.Set;
+
+/**
+ * Service for tracking and delegating batches of intent operations.
+ */
+public interface IntentBatchService {
+
+    /**
+     * Submits a batch of intent operations.
+     *
+     * @param operations batch of operations
+     */
+    void addIntentOperations(IntentOperations operations);
+
+    /**
+     * Removes the specified batch of intent operations after completion.
+     *
+     * @param operations batch of operations
+     */
+    void removeIntentOperations(IntentOperations operations);
+
+    /**
+     * Returns the set of intent batches currently being tracked.
+     * @return set of batches
+     */
+    Set<IntentOperations> getIntentOperations();
+
+    /**
+     * Sets the batch service delegate.
+     *
+     * @param delegate delegate to apply
+     */
+    void setDelegate(IntentBatchDelegate delegate);
+
+    /**
+     * Unsets the batch service delegate.
+     *
+     * @param delegate delegate to unset
+     */
+    void unsetDelegate(IntentBatchDelegate delegate);
+
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/intent/IntentCompiler.java b/core/api/src/main/java/org/onlab/onos/net/intent/IntentCompiler.java
index f6dcd17..2d6d94b 100644
--- a/core/api/src/main/java/org/onlab/onos/net/intent/IntentCompiler.java
+++ b/core/api/src/main/java/org/onlab/onos/net/intent/IntentCompiler.java
@@ -15,7 +15,10 @@
  */
 package org.onlab.onos.net.intent;
 
+import org.onlab.onos.net.resource.LinkResourceAllocations;
+
 import java.util.List;
+import java.util.Set;
 
 /**
  * Abstraction of a compiler which is capable of taking an intent
@@ -27,9 +30,13 @@
     /**
      * Compiles the specified intent into other intents.
      *
-     * @param intent intent to be compiled
+     * @param intent      intent to be compiled
+     * @param installable previously compilation result; optional
+     * @param resources   previously allocated resources; optional
      * @return list of resulting intents
      * @throws IntentException if issues are encountered while compiling the intent
      */
-    List<Intent> compile(T intent);
+    List<Intent> compile(T intent, List<Intent> installable,
+                         Set<LinkResourceAllocations> resources);
+
 }
diff --git a/core/api/src/main/java/org/onlab/onos/net/intent/IntentInstaller.java b/core/api/src/main/java/org/onlab/onos/net/intent/IntentInstaller.java
index 93d8a40..5ef717f 100644
--- a/core/api/src/main/java/org/onlab/onos/net/intent/IntentInstaller.java
+++ b/core/api/src/main/java/org/onlab/onos/net/intent/IntentInstaller.java
@@ -15,10 +15,10 @@
  */
 package org.onlab.onos.net.intent;
 
-import java.util.List;
-
 import org.onlab.onos.net.flow.FlowRuleBatchOperation;
 
+import java.util.List;
+
 /**
  * Abstraction of entity capable of installing intents to the environment.
  */
@@ -26,8 +26,8 @@
     /**
      * Installs the specified intent to the environment.
      *
-     * @param intent intent to be installed
-     * @return FlowRule operations to install
+     * @param intent    intent to be installed
+     * @return flow rule operations to complete install
      * @throws IntentException if issues are encountered while installing the intent
      */
     List<FlowRuleBatchOperation> install(T intent);
@@ -35,9 +35,20 @@
     /**
      * Uninstalls the specified intent from the environment.
      *
-     * @param intent intent to be uninstalled
-     * @return FlowRule operations to uninstall
+     * @param intent    intent to be uninstalled
+     * @return flow rule operations to complete uninstall
      * @throws IntentException if issues are encountered while uninstalling the intent
      */
     List<FlowRuleBatchOperation> uninstall(T intent);
+
+    /**
+     * Replaces the specified intent with a new one in the environment.
+     *
+     * @param oldIntent intent to be removed
+     * @param newIntent intent to be installed
+     * @return flow rule operations to complete the replace
+     * @throws IntentException if issues are encountered while uninstalling the intent
+     */
+    List<FlowRuleBatchOperation> replace(T oldIntent, T newIntent);
+
 }
diff --git a/core/api/src/main/java/org/onlab/onos/net/intent/IntentOperation.java b/core/api/src/main/java/org/onlab/onos/net/intent/IntentOperation.java
index 902f418..28508b6 100644
--- a/core/api/src/main/java/org/onlab/onos/net/intent/IntentOperation.java
+++ b/core/api/src/main/java/org/onlab/onos/net/intent/IntentOperation.java
@@ -15,6 +15,11 @@
  */
 package org.onlab.onos.net.intent;
 
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
 /**
  * Abstraction of an intent-related operation, e.g. add, remove, replace.
  */
@@ -27,7 +32,7 @@
     /**
      * Operation type.
      */
-    enum Type {
+    public enum Type {
         /**
          * Indicates that an intent should be added.
          */
@@ -41,15 +46,20 @@
         /**
          * Indicates that an intent should be replaced with another.
          */
-        REPLACE
+        REPLACE,
+
+        /**
+         * Indicates that an intent should be updated (i.e. recompiled/reinstalled).
+         */
+        UPDATE,
     }
 
     /**
      * Creates an intent operation.
      *
-     * @param type operation type
+     * @param type     operation type
      * @param intentId identifier of the intent subject to the operation
-     * @param intent intent subject
+     * @param intent   intent subject
      */
     IntentOperation(Type type, IntentId intentId, Intent intent) {
         this.type = type;
@@ -85,4 +95,32 @@
         return intent;
     }
 
+    @Override
+    public int hashCode() {
+        return Objects.hash(type, intentId, intent);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null || getClass() != obj.getClass()) {
+            return false;
+        }
+        final IntentOperation other = (IntentOperation) obj;
+        return Objects.equals(this.type, other.type) &&
+                Objects.equals(this.intentId, other.intentId) &&
+                Objects.equals(this.intent, other.intent);
+    }
+
+
+    @Override
+    public String toString() {
+        return toStringHelper(this)
+                .add("type", type)
+                .add("intentId", intentId)
+                .add("intent", intent)
+                .toString();
+    }
 }
diff --git a/core/api/src/main/java/org/onlab/onos/net/intent/IntentOperations.java b/core/api/src/main/java/org/onlab/onos/net/intent/IntentOperations.java
index 9e31ca3..eca51f0 100644
--- a/core/api/src/main/java/org/onlab/onos/net/intent/IntentOperations.java
+++ b/core/api/src/main/java/org/onlab/onos/net/intent/IntentOperations.java
@@ -18,11 +18,11 @@
 import com.google.common.collect.ImmutableList;
 
 import java.util.List;
+import java.util.Objects;
 
+import static com.google.common.base.MoreObjects.toStringHelper;
 import static com.google.common.base.Preconditions.checkNotNull;
-import static org.onlab.onos.net.intent.IntentOperation.Type.REPLACE;
-import static org.onlab.onos.net.intent.IntentOperation.Type.SUBMIT;
-import static org.onlab.onos.net.intent.IntentOperation.Type.WITHDRAW;
+import static org.onlab.onos.net.intent.IntentOperation.Type.*;
 
 /**
  * Batch of intent submit/withdraw/replace operations.
@@ -58,6 +58,31 @@
         return new Builder();
     }
 
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(operations);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null || getClass() != obj.getClass()) {
+            return false;
+        }
+        final IntentOperations other = (IntentOperations) obj;
+        return Objects.equals(this.operations, other.operations);
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this)
+                .add("operations", operations)
+                .toString();
+    }
+
     /**
      * Builder for batches of intent operations.
      */
@@ -108,6 +133,18 @@
         }
 
         /**
+         * Adds an intent update operation.
+         *
+         * @param intentId identifier of the intent to be updated
+         * @return self
+         */
+        public Builder addUpdateOperation(IntentId intentId) {
+            checkNotNull(intentId, "Intent ID cannot be null");
+            builder.add(new IntentOperation(UPDATE, intentId, null));
+            return this;
+        }
+
+        /**
          * Builds a batch of intent operations.
          *
          * @return immutable batch of intent operations
diff --git a/core/api/src/main/java/org/onlab/onos/net/intent/IntentService.java b/core/api/src/main/java/org/onlab/onos/net/intent/IntentService.java
index 090af63..9abb584 100644
--- a/core/api/src/main/java/org/onlab/onos/net/intent/IntentService.java
+++ b/core/api/src/main/java/org/onlab/onos/net/intent/IntentService.java
@@ -17,7 +17,6 @@
 
 
 import java.util.List;
-import java.util.concurrent.Future;
 
 /**
  * Service for application submitting or withdrawing their intents.
@@ -59,9 +58,8 @@
      * affected at later time.
      * </p>
      * @param operations batch of intent operations
-     * @return Future to get execution result
      */
-    Future<IntentOperations> execute(IntentOperations operations);
+    void execute(IntentOperations operations);
 
     /**
      * Returns an iterable of intents currently in the system.