Added suggest path to PointToPointIntent

Change-Id: Ie8ae3af6bd97af3628334d37482e63196d15b094
diff --git a/core/api/src/main/java/org/onosproject/net/intent/PointToPointIntent.java b/core/api/src/main/java/org/onosproject/net/intent/PointToPointIntent.java
index 1a38bfd..d0a9d54 100644
--- a/core/api/src/main/java/org/onosproject/net/intent/PointToPointIntent.java
+++ b/core/api/src/main/java/org/onosproject/net/intent/PointToPointIntent.java
@@ -19,6 +19,7 @@
 import com.google.common.base.MoreObjects;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.net.FilteredConnectPoint;
+import org.onosproject.net.Link;
 import org.onosproject.net.ResourceGroup;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
@@ -38,6 +39,8 @@
     private final FilteredConnectPoint ingressPoint;
     private final FilteredConnectPoint egressPoint;
 
+    private final List<Link> suggestedPath;
+
     /**
      * Returns a new point to point intent builder. The application id,
      * ingress point and egress point are required fields.  If they are
@@ -57,6 +60,8 @@
         FilteredConnectPoint ingressPoint;
         FilteredConnectPoint egressPoint;
 
+        List<Link> suggestedPath;
+
         private Builder() {
             // Hide constructor
         }
@@ -121,12 +126,36 @@
         }
 
         /**
+         * Sets the suggested path as list of links.
+         *
+         * @param links list of suggested links
+         * @return this builder
+         */
+        public Builder suggestedPath(List<Link> links) {
+            this.suggestedPath = links;
+            return this;
+        }
+
+        /**
          * Builds a point to point intent from the accumulated parameters.
          *
          * @return point to point intent
          */
         public PointToPointIntent build() {
-
+            if (suggestedPath != null &&
+                    suggestedPath.size() > 0 &&
+                    (!suggestedPath.get(0)
+                            .src()
+                            .deviceId()
+                            .equals(ingressPoint.connectPoint().deviceId()) ||
+                     !suggestedPath.get(suggestedPath.size() - 1)
+                             .dst()
+                             .deviceId()
+                             .equals(egressPoint.connectPoint().deviceId()))
+                    ) {
+                throw new IllegalArgumentException(
+                        "Suggested path not compatible with ingress and egress connect points");
+            }
             return new PointToPointIntent(
                     appId,
                     key,
@@ -136,6 +165,7 @@
                     egressPoint,
                     constraints,
                     priority,
+                    suggestedPath,
                     resourceGroup
             );
         }
@@ -147,16 +177,17 @@
      * Creates a new point-to-point intent with the supplied ingress/egress
      * ports and constraints.
      *
-     * @param appId        application identifier
-     * @param key          key of the intent
-     * @param selector     traffic selector
-     * @param treatment    treatment
-     * @param ingressPoint filtered ingress port
-     * @param egressPoint  filtered egress port
-     * @param constraints  optional list of constraints
-     * @param priority     priority to use for flows generated by this intent
+     * @param appId             application identifier
+     * @param key               key of the intent
+     * @param selector          traffic selector
+     * @param treatment         treatment
+     * @param ingressPoint      filtered ingress port
+     * @param egressPoint       filtered egress port
+     * @param constraints       optional list of constraints
+     * @param priority          priority to use for flows generated by this intent
+     * @param suggestedPath     suggested path
      * @throws NullPointerException if {@code ingressPoint} or
-     *        {@code egressPoints} or {@code appId} is null.
+     *        {@code egressPoints} or {@code appId} is null or {@code path} is null.
      */
     private PointToPointIntent(ApplicationId appId,
                                Key key,
@@ -166,15 +197,24 @@
                                FilteredConnectPoint egressPoint,
                                List<Constraint> constraints,
                                int priority,
+                               List<Link> suggestedPath,
                                ResourceGroup resourceGroup) {
-        super(appId, key, Collections.emptyList(), selector, treatment, constraints,
-                priority, resourceGroup);
+        super(appId,
+              key,
+              suggestedPath != null ? resources(suggestedPath) : Collections.emptyList(),
+              selector,
+              treatment,
+              constraints,
+              priority,
+              resourceGroup);
 
         checkArgument(!ingressPoint.equals(egressPoint),
                 "ingress and egress should be different (ingress: %s, egress: %s)", ingressPoint, egressPoint);
 
         this.ingressPoint = checkNotNull(ingressPoint);
         this.egressPoint = checkNotNull(egressPoint);
+        this.suggestedPath = suggestedPath;
+
     }
 
     /**
@@ -184,6 +224,7 @@
         super();
         this.ingressPoint = null;
         this.egressPoint = null;
+        this.suggestedPath = null;
     }
 
     /**
@@ -205,6 +246,16 @@
         return egressPoint;
     }
 
+
+    /**
+     * Return the suggested path (as a list of links) that the compiler should use.
+     *
+     * @return suggested path
+     */
+    public List<Link> suggestedPath() {
+        return suggestedPath;
+    }
+
     @Override
     public String toString() {
         return MoreObjects.toStringHelper(getClass())
@@ -218,6 +269,7 @@
                 .add("ingress", filteredIngressPoint())
                 .add("egress", filteredEgressPoint())
                 .add("constraints", constraints())
+                .add("links", suggestedPath())
                 .add("resourceGroup", resourceGroup())
                 .toString();
     }