Add path intent compiler that generates flow objective intents

Change-Id: I11bee398d927f0e3f32b7cf81d98cfe5816db477
diff --git a/core/api/src/main/java/org/onosproject/net/intent/FlowObjectiveIntent.java b/core/api/src/main/java/org/onosproject/net/intent/FlowObjectiveIntent.java
index 18dcb6e..55c883a 100644
--- a/core/api/src/main/java/org/onosproject/net/intent/FlowObjectiveIntent.java
+++ b/core/api/src/main/java/org/onosproject/net/intent/FlowObjectiveIntent.java
@@ -17,19 +17,25 @@
 package org.onosproject.net.intent;
 
 import com.google.common.base.MoreObjects;
+import com.google.common.collect.ImmutableList;
 import org.onosproject.core.ApplicationId;
+import org.onosproject.net.DeviceId;
 import org.onosproject.net.NetworkResource;
 import org.onosproject.net.flowobjective.Objective;
 
 import java.util.Collection;
+import java.util.List;
+
+import static com.google.common.base.Preconditions.checkArgument;
 
 /**
  * Intent expressed as (and backed by) a collection of flow objectives through
  * which the intent is to be accomplished.
  */
-public class FlowObjectiveIntent extends Intent {
+public final class FlowObjectiveIntent extends Intent {
 
-    private final Collection<Objective> objectives;
+    private final List<Objective> objectives;
+    private final List<DeviceId> devices;
 
     /**
      * Constructor for serialization.
@@ -37,6 +43,7 @@
     protected FlowObjectiveIntent() {
         super();
         this.objectives = null;
+        this.devices = null;
     }
 
     /**
@@ -44,13 +51,15 @@
      * resources.
      *
      * @param appId      application id
+     * @param devices    list of target devices; in same order as the objectives
      * @param objectives backing flow objectives
      * @param resources  backing network resources
      */
     public FlowObjectiveIntent(ApplicationId appId,
-                               Collection<Objective> objectives,
+                               List<DeviceId> devices,
+                               List<Objective> objectives,
                                Collection<NetworkResource> resources) {
-        this(appId, null, objectives, resources);
+        this(appId, null, devices, objectives, resources);
     }
 
     /**
@@ -59,14 +68,20 @@
      *
      * @param appId      application id
      * @param key        intent key
+     * @param devices    list of target devices; in same order as the objectives
      * @param objectives backing flow objectives
      * @param resources  backing network resources
      */
-    public FlowObjectiveIntent(ApplicationId appId, Key key,
-                               Collection<Objective> objectives,
+    public FlowObjectiveIntent(ApplicationId appId,
+                               Key key,
+                               List<DeviceId> devices,
+                               List<Objective> objectives,
                                Collection<NetworkResource> resources) {
         super(appId, key, resources, DEFAULT_INTENT_PRIORITY);
-        this.objectives = objectives;
+        checkArgument(devices.size() == objectives.size(),
+                      "Number of devices and objectives does not match");
+        this.objectives = ImmutableList.copyOf(objectives);
+        this.devices = ImmutableList.copyOf(devices);
     }
 
     /**
@@ -74,10 +89,19 @@
      *
      * @return flow objectives
      */
-    Collection<Objective> objectives() {
+    public List<Objective> objectives() {
         return objectives;
     }
 
+    /**
+     * Returns the list of devices for the flow objectives.
+     *
+     * @return devices
+     */
+    public List<DeviceId> devices() {
+        return devices;
+    }
+
 
     @Override
     public boolean isInstallable() {
@@ -91,7 +115,8 @@
                 .add("key", key())
                 .add("appId", appId())
                 .add("resources", resources())
-                .add("objectives", objectives)
+                .add("device", devices())
+                .add("objectives", objectives())
                 .toString();
     }
 }
diff --git a/core/api/src/test/java/org/onosproject/net/intent/FlowObjectiveIntentTest.java b/core/api/src/test/java/org/onosproject/net/intent/FlowObjectiveIntentTest.java
index ec3e334..54f9aa7 100644
--- a/core/api/src/test/java/org/onosproject/net/intent/FlowObjectiveIntentTest.java
+++ b/core/api/src/test/java/org/onosproject/net/intent/FlowObjectiveIntentTest.java
@@ -16,11 +16,13 @@
 
 package org.onosproject.net.intent;
 
-import com.google.common.collect.ImmutableSet;
-import com.google.common.testing.EqualsTester;
+import java.util.Collection;
+import java.util.List;
+
 import org.junit.Test;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.net.DeviceId;
 import org.onosproject.net.NetworkResource;
 import org.onosproject.net.flow.DefaultTrafficSelector;
 import org.onosproject.net.flow.DefaultTrafficTreatment;
@@ -30,7 +32,9 @@
 import org.onosproject.net.flowobjective.ForwardingObjective;
 import org.onosproject.net.flowobjective.Objective;
 
-import java.util.Collection;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.testing.EqualsTester;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
@@ -52,8 +56,9 @@
             .withSelector(DefaultTrafficSelector.builder().matchEthType((short) 123).build())
             .withTreatment(DefaultTrafficTreatment.emptyTreatment())
             .withFlag(ForwardingObjective.Flag.VERSATILE).add();
-    private static final Collection<Objective> OBJECTIVES = ImmutableSet.of(FO1, FO2);
+    private static final List<Objective> OBJECTIVES = ImmutableList.of(FO1, FO2);
     private static final Collection<NetworkResource> RESOURCES = ImmutableSet.of();
+    private static final List<DeviceId> DEVICE = ImmutableList.of(DeviceId.NONE, DeviceId.NONE);
 
     /**
      * Tests basics of construction and getters.
@@ -61,7 +66,7 @@
     @Test
     public void basics() {
         FlowObjectiveIntent intent =
-                new FlowObjectiveIntent(APP_ID, KEY, OBJECTIVES, RESOURCES);
+                new FlowObjectiveIntent(APP_ID, KEY, DEVICE, OBJECTIVES, RESOURCES);
         assertEquals("incorrect app id", APP_ID, intent.appId());
         assertEquals("incorrect key", KEY, intent.key());
         assertEquals("incorrect objectives", OBJECTIVES, intent.objectives());
@@ -89,11 +94,11 @@
 
     @Override
     protected Intent createOne() {
-        return new FlowObjectiveIntent(APP_ID, OBJECTIVES, RESOURCES);
+        return new FlowObjectiveIntent(APP_ID, DEVICE, OBJECTIVES, RESOURCES);
     }
 
     @Override
     protected Intent createAnother() {
-        return new FlowObjectiveIntent(APP_ID, OBJECTIVES, RESOURCES);
+        return new FlowObjectiveIntent(APP_ID, DEVICE, OBJECTIVES, RESOURCES);
     }
-}
\ No newline at end of file
+}