Refactor connectivity intent creation to use builders

- Each connectivity intent now has only one constructor
- Intent constructors are now private for leaf classes and
  protected for classes that can be derived from
- Each intent class has a Builder class that accumulates
  parameters for intent creation
- Each intent class has a public static builder() method
  to create a builder
- Each Builder class has a build() method to create the
  intent from the accumulated parameters
- Added keys to a few intent types that were missing them
- Tightened up usage of checkNotNull(), taking advantage of
  the return value to save some lines of code
- Modified callers to use the builders instead of directly
  calling the constructors

Change-Id: I713185d5ecbadbf51f87ef7f68fec41102106c78
diff --git a/core/api/src/main/java/org/onosproject/net/intent/MplsIntent.java b/core/api/src/main/java/org/onosproject/net/intent/MplsIntent.java
index 524b231..1625f58 100644
--- a/core/api/src/main/java/org/onosproject/net/intent/MplsIntent.java
+++ b/core/api/src/main/java/org/onosproject/net/intent/MplsIntent.java
@@ -1,8 +1,5 @@
 package org.onosproject.net.intent;
 
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
 import java.util.Collections;
 import java.util.List;
 import java.util.Optional;
@@ -10,13 +7,13 @@
 import org.onlab.packet.MplsLabel;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.Link;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.intent.constraint.LinkTypeConstraint;
 
 import com.google.common.base.MoreObjects;
-import com.google.common.collect.ImmutableList;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 
 /**
@@ -30,30 +27,6 @@
     private final Optional<MplsLabel> egressLabel;
 
     /**
-     * Creates a new MPLS intent with the supplied ingress/egress
-     * ports and labels and with built-in link type constraint to avoid optical links.
-     *
-     * @param appId        application identifier
-     * @param selector     traffic selector
-     * @param treatment    treatment
-     * @param ingressPoint ingress port
-     * @param ingressLabel ingress MPLS label
-     * @param egressPoint  egress port
-     * @param egressLabel  egress MPLS label
-     * @throws NullPointerException if {@code ingressPoint} or {@code egressPoints} is null.
-     */
-    public MplsIntent(ApplicationId appId, TrafficSelector selector,
-                              TrafficTreatment treatment,
-                              ConnectPoint ingressPoint,
-                              Optional<MplsLabel> ingressLabel,
-                              ConnectPoint egressPoint,
-                              Optional<MplsLabel> egressLabel) {
-        this(appId, selector, treatment, ingressPoint, ingressLabel, egressPoint, egressLabel,
-             ImmutableList.of(new LinkTypeConstraint(false, Link.Type.OPTICAL)),
-             DEFAULT_INTENT_PRIORITY);
-    }
-
-    /**
      * Creates a new point-to-point intent with the supplied ingress/egress
      * ports, labels and constraints.
      *
@@ -68,32 +41,154 @@
      * @param priority    priority to use for flows generated by this intent
      * @throws NullPointerException if {@code ingressPoint} or {@code egressPoints} is null.
      */
-    public MplsIntent(ApplicationId appId, TrafficSelector selector,
-                              TrafficTreatment treatment,
-                              ConnectPoint ingressPoint,
-                              Optional<MplsLabel> ingressLabel,
-                              ConnectPoint egressPoint,
-                              Optional<MplsLabel> egressLabel,
-                              List<Constraint> constraints,
-                              int priority) {
+    private MplsIntent(ApplicationId appId,
+                      Key key,
+                      TrafficSelector selector,
+                      TrafficTreatment treatment,
+                      ConnectPoint ingressPoint,
+                      Optional<MplsLabel> ingressLabel,
+                      ConnectPoint egressPoint,
+                      Optional<MplsLabel> egressLabel,
+                      List<Constraint> constraints,
+                      int priority) {
 
-        super(appId, Collections.emptyList(), selector, treatment, constraints,
+        super(appId, key, Collections.emptyList(), selector, treatment, constraints,
               priority);
 
-        checkNotNull(ingressPoint);
-        checkNotNull(egressPoint);
-        checkArgument(!ingressPoint.equals(egressPoint),
-                "ingress and egress should be different (ingress: %s, egress: %s)", ingressPoint, egressPoint);
-        checkNotNull(ingressLabel);
-        checkNotNull(egressLabel);
-        this.ingressPoint = ingressPoint;
-        this.ingressLabel = ingressLabel;
-        this.egressPoint = egressPoint;
-        this.egressLabel = egressLabel;
+        this.ingressPoint = checkNotNull(ingressPoint);
+        this.ingressLabel = checkNotNull(ingressLabel);
+        this.egressPoint = checkNotNull(egressPoint);
+        this.egressLabel = checkNotNull(egressLabel);
 
+        checkArgument(!ingressPoint.equals(egressPoint),
+                "ingress and egress should be different (ingress: %s, egress: %s)",
+                ingressPoint, egressPoint);
     }
 
     /**
+     * Returns a new MPLS intent builder. The application id,
+     * ingress point, egress point, ingress label and egress label are
+     * required fields.  If they are not set by calls to the appropriate
+     * methods, an exception will be thrown.
+     *
+     * @return point to point builder
+     */
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder of an MPLS intent.
+     */
+    public static final class Builder extends ConnectivityIntent.Builder {
+        ConnectPoint ingressPoint;
+        ConnectPoint egressPoint;
+        Optional<MplsLabel> ingressLabel;
+        Optional<MplsLabel> egressLabel;
+
+        private Builder() {
+            // Hide constructor
+        }
+
+        @Override
+        public Builder appId(ApplicationId appId) {
+            return (Builder) super.appId(appId);
+        }
+
+        @Override
+        public Builder key(Key key) {
+            return (Builder) super.key(key);
+        }
+
+        @Override
+        public Builder selector(TrafficSelector selector) {
+            return (Builder) super.selector(selector);
+        }
+
+        @Override
+        public Builder treatment(TrafficTreatment treatment) {
+            return (Builder) super.treatment(treatment);
+        }
+
+        @Override
+        public Builder constraints(List<Constraint> constraints) {
+            return (Builder) super.constraints(constraints);
+        }
+
+        @Override
+        public Builder priority(int priority) {
+            return (Builder) super.priority(priority);
+        }
+
+        /**
+         * Sets the ingress point of the point to point intent that will be built.
+         *
+         * @param ingressPoint ingress connect point
+         * @return this builder
+         */
+        public Builder ingressPoint(ConnectPoint ingressPoint) {
+            this.ingressPoint = ingressPoint;
+            return this;
+        }
+
+        /**
+         * Sets the egress point of the point to point intent that will be built.
+         *
+         * @param egressPoint egress connect point
+         * @return this builder
+         */
+        public Builder egressPoint(ConnectPoint egressPoint) {
+            this.egressPoint = egressPoint;
+            return this;
+        }
+
+        /**
+         * Sets the ingress label of the intent that will be built.
+         *
+         * @param ingressLabel ingress label
+         * @return this builder
+         */
+        public Builder ingressLabel(Optional<MplsLabel> ingressLabel) {
+            this.ingressLabel = ingressLabel;
+            return this;
+        }
+
+        /**
+         * Sets the ingress label of the intent that will be built.
+         *
+         * @param egressLabel ingress label
+         * @return this builder
+         */
+        public Builder egressLabel(Optional<MplsLabel> egressLabel) {
+            this.egressLabel = egressLabel;
+            return this;
+        }
+
+        /**
+         * Builds a point to point intent from the accumulated parameters.
+         *
+         * @return point to point intent
+         */
+        public MplsIntent build() {
+
+            return new MplsIntent(
+                    appId,
+                    key,
+                    selector,
+                    treatment,
+                    ingressPoint,
+                    ingressLabel,
+                    egressPoint,
+                    egressLabel,
+                    constraints,
+                    priority
+            );
+        }
+    }
+
+
+
+    /**
      * Constructor for serializer.
      */
     protected MplsIntent() {
@@ -147,6 +242,7 @@
         return MoreObjects.toStringHelper(getClass())
                 .add("id", id())
                 .add("appId", appId())
+                .add("key", key())
                 .add("priority", priority())
                 .add("selector", selector())
                 .add("treatment", treatment())