[ONOS-4387] Support for multiple selectors in mp2sp intents

Changes:
- Adds extension to mp2sp intents;
- Adds extension to linkcollection intents;
- Adds extension to mp2sp compiler;
- Adds extension to linkcollection compiler;
- Adds unit tests for both mp2sp and linkcollection intents;

Change-Id: I673c2b660d2364c510b1b3050ed3626ad2f37bda
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionCompiler.java
index 9fbedb9..b37095a 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionCompiler.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionCompiler.java
@@ -48,6 +48,7 @@
 import org.onosproject.net.intent.LinkCollectionIntent;
 
 import java.util.List;
+import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
 
@@ -155,12 +156,15 @@
      *
      * @param intent the intent to compile
      * @param inPort the input port
+     * @param deviceId the current device
      * @param outPorts the output ports
      * @param ingressPorts the ingress ports
      * @param egressPorts the egress ports
      * @return the forwarding instruction object which encapsulates treatment and selector
      */
-    protected ForwardingInstructions createForwardingInstructions(LinkCollectionIntent intent, PortNumber inPort,
+    protected ForwardingInstructions createForwardingInstructions(LinkCollectionIntent intent,
+                                                                  PortNumber inPort,
+                                                                  DeviceId deviceId,
                                                                   Set<PortNumber> outPorts,
                                                                   Set<PortNumber> ingressPorts,
                                                                   Set<PortNumber> egressPorts) {
@@ -178,8 +182,27 @@
             intentTreatment = ingressTreatmentBuilder.build();
 
             if (ingressPorts.contains(inPort)) {
-                selectorBuilder = DefaultTrafficSelector.builder(intent.selector());
-                treatment = intentTreatment;
+                if (intent.ingressSelectors() != null && !intent.ingressSelectors().isEmpty()) {
+                    /**
+                     * We iterate on the ingress points looking for the connect point
+                     * associated to inPort.
+                     */
+                    Optional<ConnectPoint> connectPoint = intent.ingressPoints()
+                            .stream()
+                            .filter(ingressPoint -> ingressPoint.port().equals(inPort)
+                                    && ingressPoint.deviceId().equals(deviceId))
+                            .findFirst();
+                    if (connectPoint.isPresent()) {
+                        selectorBuilder = DefaultTrafficSelector
+                                .builder(intent.ingressSelectors().get(connectPoint.get()));
+                    } else {
+                        throw new IntentCompilationException("Looking for connect point associated to the selector." +
+                                                                     "inPort not in IngressPoints");
+                    }
+                } else {
+                    selectorBuilder = DefaultTrafficSelector.builder(intent.selector());
+                }
+                treatment = this.updateBuilder(ingressTreatmentBuilder, selectorBuilder.build()).build();
             } else {
                 selectorBuilder = this.createSelectorFromFwdInstructions(
                         new ForwardingInstructions(intentTreatment, intent.selector())
@@ -207,6 +230,18 @@
     }
 
     /**
+     * Update the original builder with the necessary operations
+     * to have a correct forwarding given an ingress selector.
+     *
+     * @param treatmentBuilder the builder to modify
+     * @return the new treatment created
+     */
+    private TrafficTreatment.Builder updateBuilder(TrafficTreatment.Builder treatmentBuilder,
+                                                   TrafficSelector intentSelector) {
+        return treatmentBuilder;
+    }
+
+    /**
      * Update the selector builder using a L0 instruction.
      *
      * @param builder the builder to update