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/LinkCollectionIntent.java b/core/api/src/main/java/org/onosproject/net/intent/LinkCollectionIntent.java
index 17451cb..8cea253 100644
--- a/core/api/src/main/java/org/onosproject/net/intent/LinkCollectionIntent.java
+++ b/core/api/src/main/java/org/onosproject/net/intent/LinkCollectionIntent.java
@@ -15,8 +15,8 @@
  */
 package org.onosproject.net.intent;
 
-import com.google.common.base.MoreObjects;
-import com.google.common.collect.ImmutableSet;
+import java.util.List;
+import java.util.Set;
 
 import org.onosproject.core.ApplicationId;
 import org.onosproject.net.ConnectPoint;
@@ -24,9 +24,8 @@
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
 
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.ImmutableSet;
 
 /**
  * Abstraction of a connectivity intent that is implemented by a set of path
@@ -42,71 +41,21 @@
     /**
      * Creates a new actionable intent capable of funneling the selected
      * traffic along the specified convergent tree and out the given egress
-     * point.
-     *
-     * @param appId       application identifier
-     * @param selector    traffic match
-     * @param treatment   action
-     * @param links       traversed links
-     * @param ingressPoint ingress point
-     * @param egressPoint egress point
-     * @throws NullPointerException {@code path} is null
-     */
-    public LinkCollectionIntent(ApplicationId appId,
-                                TrafficSelector selector,
-                                TrafficTreatment treatment,
-                                Set<Link> links,
-                                ConnectPoint ingressPoint,
-                                ConnectPoint egressPoint) {
-        this(appId, selector, treatment, links, ingressPoint, egressPoint,
-             Collections.emptyList(), DEFAULT_INTENT_PRIORITY);
-    }
-
-    /**
-     * Creates a new actionable intent capable of funneling the selected
-     * traffic along the specified convergent tree and out the given egress
      * point satisfying the specified constraints.
      *
      * @param appId       application identifier
+     * @param key         key to use for the intent
      * @param selector    traffic match
      * @param treatment   action
      * @param links       traversed links
-     * @param ingressPoint ingress point
-     * @param egressPoint egress point
+     * @param ingressPoints ingress points
+     * @param egressPoints egress points
      * @param constraints optional list of constraints
      * @param priority    priority to use for the flows generated by this intent
      * @throws NullPointerException {@code path} is null
      */
-    public LinkCollectionIntent(ApplicationId appId,
-                                TrafficSelector selector,
-                                TrafficTreatment treatment,
-                                Set<Link> links,
-                                ConnectPoint ingressPoint,
-                                ConnectPoint egressPoint,
-                                List<Constraint> constraints,
-                                int priority) {
-        super(appId, resources(links), selector, treatment, constraints, priority);
-        this.links = links;
-        this.ingressPoints = ImmutableSet.of(ingressPoint);
-        this.egressPoints = ImmutableSet.of(egressPoint);
-    }
-
-    /**
-     * Creates a new actionable intent capable of funneling the selected
-     * traffic along the specified convergent tree and out the given egress
-     * point.
-     *
-     * @param appId        application identifier
-     * @param selector     traffic match
-     * @param treatment    action
-     * @param links        traversed links
-     * @param ingressPoints Set of ingress points
-     * @param egressPoints Set of egress points
-     * @param constraints  the constraints
-     * @param priority     priority to use for the flows generated by this intent
-     * @throws NullPointerException {@code path} is null
-     */
-    public LinkCollectionIntent(ApplicationId appId,
+    private LinkCollectionIntent(ApplicationId appId,
+                                Key key,
                                 TrafficSelector selector,
                                 TrafficTreatment treatment,
                                 Set<Link> links,
@@ -114,11 +63,10 @@
                                 Set<ConnectPoint> egressPoints,
                                 List<Constraint> constraints,
                                 int priority) {
-        super(appId, resources(links), selector, treatment, constraints, priority);
-
+        super(appId, key, resources(links), selector, treatment, constraints, priority);
         this.links = links;
-        this.ingressPoints = ImmutableSet.copyOf(ingressPoints);
-        this.egressPoints = ImmutableSet.copyOf(egressPoints);
+        this.ingressPoints = ingressPoints;
+        this.egressPoints = egressPoints;
     }
 
     /**
@@ -132,6 +80,120 @@
     }
 
     /**
+     * Returns a new link collection intent builder. The application id,
+     * ingress point and egress points are required fields.  If they are
+     * not set by calls to the appropriate methods, an exception will
+     * be thrown.
+     *
+     * @return single point to multi point builder
+     */
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder of a single point to multi point intent.
+     */
+    public static final class Builder extends ConnectivityIntent.Builder {
+        Set<Link> links;
+        Set<ConnectPoint> ingressPoints;
+        Set<ConnectPoint> egressPoints;
+
+        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 single point to multi point intent
+         * that will be built.
+         *
+         * @param ingressPoints ingress connect points
+         * @return this builder
+         */
+        public Builder ingressPoints(Set<ConnectPoint> ingressPoints) {
+            this.ingressPoints = ImmutableSet.copyOf(ingressPoints);
+            return this;
+        }
+
+        /**
+         * Sets the egress points of the single point to multi point intent
+         * that will be built.
+         *
+         * @param egressPoints egress connect points
+         * @return this builder
+         */
+        public Builder egressPoints(Set<ConnectPoint> egressPoints) {
+            this.egressPoints = ImmutableSet.copyOf(egressPoints);
+            return this;
+        }
+
+        /**
+         * Sets the links of the link collection intent
+         * that will be built.
+         *
+         * @param links links for the intent
+         * @return this builder
+         */
+        public Builder links(Set<Link> links) {
+            this.links = ImmutableSet.copyOf(links);
+            return this;
+        }
+
+
+        /**
+         * Builds a single point to multi point intent from the
+         * accumulated parameters.
+         *
+         * @return point to point intent
+         */
+        public LinkCollectionIntent build() {
+
+            return new LinkCollectionIntent(
+                    appId,
+                    key,
+                    selector,
+                    treatment,
+                    links,
+                    ingressPoints,
+                    egressPoints,
+                    constraints,
+                    priority
+            );
+        }
+    }
+
+
+    /**
      * Returns the set of links that represent the network connections needed
      * by this intent.
      *