[ONOS-5264] [ONOS-5242] Intents w/ FilteredConnectPoint

Change-Id: Ibe9062c904ad9a6c3ba001fe57be7cec49eb8a4d
diff --git a/core/api/src/test/java/org/onosproject/net/intent/ConnectivityIntentTest.java b/core/api/src/test/java/org/onosproject/net/intent/ConnectivityIntentTest.java
index 9cbe99f..bab715f 100644
--- a/core/api/src/test/java/org/onosproject/net/intent/ConnectivityIntentTest.java
+++ b/core/api/src/test/java/org/onosproject/net/intent/ConnectivityIntentTest.java
@@ -15,7 +15,6 @@
  */
 package org.onosproject.net.intent;
 
-import java.util.Collections;
 import java.util.Map;
 import java.util.Set;
 
@@ -25,6 +24,7 @@
 import org.onosproject.TestApplicationId;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DeviceId;
+import org.onosproject.net.FilteredConnectPoint;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.flow.DefaultTrafficSelector;
 import org.onosproject.net.flow.DefaultTrafficTreatment;
@@ -42,8 +42,6 @@
     public static final IntentId IID = new IntentId(123);
     public static final TrafficSelector MATCH = DefaultTrafficSelector.emptySelector();
     public static final TrafficTreatment NOP = DefaultTrafficTreatment.emptyTreatment();
-    public static final Map<ConnectPoint, TrafficSelector> MATCHES = Collections.emptyMap();
-    public static final Map<ConnectPoint, TrafficTreatment> TREATMENTS = Collections.emptyMap();
 
     public static final ConnectPoint P1 = new ConnectPoint(DeviceId.deviceId("111"), PortNumber.portNumber(0x1));
     public static final ConnectPoint P2 = new ConnectPoint(DeviceId.deviceId("222"), PortNumber.portNumber(0x2));
@@ -52,6 +50,7 @@
     public static final Set<ConnectPoint> PS1 = itemSet(new ConnectPoint[]{P1, P3});
     public static final Set<ConnectPoint> PS2 = itemSet(new ConnectPoint[]{P2, P3});
 
+
     public static final TrafficSelector VLANMATCH1 = DefaultTrafficSelector.builder()
             .matchVlanId(VlanId.vlanId("2"))
             .build();
@@ -59,6 +58,13 @@
             .matchVlanId(VlanId.vlanId("3"))
             .build();
 
+    public static final FilteredConnectPoint FP1 = new FilteredConnectPoint(P1, VLANMATCH1);
+    public static final FilteredConnectPoint FP2 = new FilteredConnectPoint(P2, VLANMATCH1);
+    public static final FilteredConnectPoint FP3 = new FilteredConnectPoint(P3, VLANMATCH2);
+
+    public static final Set<FilteredConnectPoint> FPS1 = itemSet(new FilteredConnectPoint[]{FP1, FP3});
+    public static final Set<FilteredConnectPoint> FPS2 = itemSet(new FilteredConnectPoint[]{FP2, FP3});
+
     public static final Map<ConnectPoint, TrafficSelector> VLANMATCHES = Maps.newHashMap();
     static {
         VLANMATCHES.put(P1, VLANMATCH1);
diff --git a/core/api/src/test/java/org/onosproject/net/intent/IntentTestsMocks.java b/core/api/src/test/java/org/onosproject/net/intent/IntentTestsMocks.java
index c090fae..931ac72 100644
--- a/core/api/src/test/java/org/onosproject/net/intent/IntentTestsMocks.java
+++ b/core/api/src/test/java/org/onosproject/net/intent/IntentTestsMocks.java
@@ -26,7 +26,7 @@
 import org.onosproject.net.NetTestTools;
 import org.onosproject.net.NetworkResource;
 import org.onosproject.net.Path;
-import org.onosproject.net.flow.FlowRule.FlowRemoveReason;
+import org.onosproject.net.device.DeviceServiceAdapter;
 import org.onosproject.net.flow.FlowId;
 import org.onosproject.net.flow.FlowRule;
 import org.onosproject.net.flow.FlowRuleExtPayLoad;
@@ -180,6 +180,67 @@
         }
     }
 
+    /**
+     * Mock path service for creating paths within the test.
+     *
+     */
+    public static class Mp2MpMockPathService
+            extends PathServiceAdapter {
+
+        final String[] pathHops;
+        final String[] reversePathHops;
+
+        /**
+         * Constructor that provides a set of hops to mock.
+         *
+         * @param pathHops path hops to mock
+         */
+        public Mp2MpMockPathService(String[] pathHops) {
+            this.pathHops = pathHops;
+            String[] reversed = pathHops.clone();
+            Collections.reverse(Arrays.asList(reversed));
+            reversePathHops = reversed;
+        }
+
+        @Override
+        public Set<Path> getPaths(ElementId src, ElementId dst) {
+            Set<Path> result = new HashSet<>();
+
+            String[] allHops = new String[pathHops.length + 2];
+            allHops[0] = src.toString();
+            allHops[allHops.length - 1] = dst.toString();
+
+            if (pathHops.length != 0) {
+                System.arraycopy(pathHops, 0, allHops, 1, pathHops.length);
+            }
+
+            result.add(createPath(allHops));
+
+            return result;
+        }
+
+        @Override
+        public Set<Path> getPaths(ElementId src, ElementId dst, LinkWeight weight) {
+            final Set<Path> paths = getPaths(src, dst);
+
+            for (Path path : paths) {
+                final DeviceId srcDevice = path.src().elementId() instanceof DeviceId ? path.src().deviceId() : null;
+                final DeviceId dstDevice = path.dst().elementId() instanceof DeviceId ? path.dst().deviceId() : null;
+                if (srcDevice != null && dstDevice != null) {
+                    final TopologyVertex srcVertex = new DefaultTopologyVertex(srcDevice);
+                    final TopologyVertex dstVertex = new DefaultTopologyVertex(dstDevice);
+                    final Link link = link(src.toString(), 1, dst.toString(), 1);
+
+                    final double weightValue = weight.weight(new DefaultTopologyEdge(srcVertex, dstVertex, link));
+                    if (weightValue < 0) {
+                        return new HashSet<>();
+                    }
+                }
+            }
+            return paths;
+        }
+    }
+
     public static final class MockResourceService implements ResourceService {
 
         private final double bandwidth;
@@ -429,4 +490,14 @@
         }
     }
 
+    /**
+     * Mocks the device service so that a device appears available in the test.
+     */
+    public static class MockDeviceService extends DeviceServiceAdapter {
+        @Override
+        public boolean isAvailable(DeviceId deviceId) {
+            return true;
+        }
+    }
+
 }
diff --git a/core/api/src/test/java/org/onosproject/net/intent/LinkCollectionIntentTest.java b/core/api/src/test/java/org/onosproject/net/intent/LinkCollectionIntentTest.java
index 006ca57..cb25b3c 100644
--- a/core/api/src/test/java/org/onosproject/net/intent/LinkCollectionIntentTest.java
+++ b/core/api/src/test/java/org/onosproject/net/intent/LinkCollectionIntentTest.java
@@ -21,8 +21,10 @@
 import java.util.List;
 import java.util.Set;
 
+import com.google.common.collect.Sets;
 import org.junit.Test;
 import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.FilteredConnectPoint;
 import org.onosproject.net.Link;
 import org.onosproject.net.NetTestTools;
 import org.onosproject.net.flow.TrafficSelector;
@@ -49,6 +51,8 @@
     final ConnectPoint egress = NetTestTools.connectPoint("egress", 3);
     final TrafficSelector selector = new IntentTestsMocks.MockSelector();
     final IntentTestsMocks.MockTreatment treatment = new IntentTestsMocks.MockTreatment();
+    final FilteredConnectPoint filteredIngress = new FilteredConnectPoint(ingress);
+    final FilteredConnectPoint filteredEgress = new FilteredConnectPoint(egress);
 
     /**
      * Checks that the LinkCollectionIntent class is immutable.
@@ -179,6 +183,39 @@
         assertThat(createdConstraints, hasSize(0));
     }
 
+    /**
+     * Test filtered connection point for LinkCollection intent.
+     */
+    @Test
+    public void testFilteredConnectedPoint() {
+        LinkCollectionIntent intent = createFilteredOne();
+        Set<Link> links = Sets.newHashSet();
+        links.add(link("A", 1, "B", 1));
+        links.add(link("A", 2, "C", 1));
+
+        assertThat(intent.appId(), is(APP_ID));
+        assertThat(intent.treatment(), is(treatment));
+        assertThat(intent.links(), is(links));
+        assertThat(intent.applyTreatmentOnEgress(), is(false));
+        assertThat(intent.filteredIngressPoints(), is(ImmutableSet.of(filteredIngress)));
+        assertThat(intent.filteredEgressPoints(), is(ImmutableSet.of(filteredEgress)));
+
+        intent = createAnotherFiltered();
+        links = Sets.newHashSet();
+        links.add(link("A", 1, "B", 1));
+        links.add(link("A", 2, "C", 1));
+        links.add(link("B", 2, "D", 1));
+        links.add(link("B", 3, "E", 1));
+
+        assertThat(intent.appId(), is(APP_ID));
+        assertThat(intent.treatment(), is(treatment));
+        assertThat(intent.links(), is(links));
+        assertThat(intent.applyTreatmentOnEgress(), is(true));
+        assertThat(intent.filteredIngressPoints(), is(ImmutableSet.of(filteredIngress)));
+        assertThat(intent.filteredEgressPoints(), is(ImmutableSet.of(filteredEgress)));
+
+    }
+
     @Override
     protected Intent createOne() {
         HashSet<Link> links1 = new HashSet<>();
@@ -206,4 +243,33 @@
                 .egressPoints(ImmutableSet.of(egress))
                 .build();
     }
+
+    protected LinkCollectionIntent createFilteredOne() {
+        Set<Link> links = Sets.newHashSet();
+        links.add(link("A", 1, "B", 1));
+        links.add(link("A", 2, "C", 1));
+        return LinkCollectionIntent.builder()
+                .appId(APP_ID)
+                .treatment(treatment)
+                .links(links)
+                .filteredIngressPoints(ImmutableSet.of(filteredIngress))
+                .filteredEgressPoints(ImmutableSet.of(filteredEgress))
+                .build();
+    }
+
+    protected LinkCollectionIntent createAnotherFiltered() {
+        Set<Link> links = Sets.newHashSet();
+        links.add(link("A", 1, "B", 1));
+        links.add(link("A", 2, "C", 1));
+        links.add(link("B", 2, "D", 1));
+        links.add(link("B", 3, "E", 1));
+        return LinkCollectionIntent.builder()
+                .appId(APP_ID)
+                .treatment(treatment)
+                .links(links)
+                .applyTreatmentOnEgress(true)
+                .filteredIngressPoints(ImmutableSet.of(filteredIngress))
+                .filteredEgressPoints(ImmutableSet.of(filteredEgress))
+                .build();
+    }
 }
diff --git a/core/api/src/test/java/org/onosproject/net/intent/MultiPointToSinglePointIntentTest.java b/core/api/src/test/java/org/onosproject/net/intent/MultiPointToSinglePointIntentTest.java
index 115af4a..a41214b 100644
--- a/core/api/src/test/java/org/onosproject/net/intent/MultiPointToSinglePointIntentTest.java
+++ b/core/api/src/test/java/org/onosproject/net/intent/MultiPointToSinglePointIntentTest.java
@@ -16,9 +16,7 @@
 
 package org.onosproject.net.intent;
 
-import org.junit.Rule;
 import org.junit.Test;
-import org.junit.rules.ExpectedException;
 
 import static org.junit.Assert.assertEquals;
 import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
@@ -36,6 +34,9 @@
         assertThatClassIsImmutable(MultiPointToSinglePointIntent.class);
     }
 
+    /**
+     * Create three intents with normal connect points.
+     */
     @Test
     public void basics() {
         MultiPointToSinglePointIntent intent = createOne();
@@ -43,40 +44,38 @@
         assertEquals("incorrect match", MATCH, intent.selector());
         assertEquals("incorrect ingress", PS1, intent.ingressPoints());
         assertEquals("incorrect egress", P2, intent.egressPoint());
-    }
 
-    @Rule
-    public ExpectedException wrongMultiple = ExpectedException.none();
-
-    @Test
-    public void multipleSelectors() {
-
-        MultiPointToSinglePointIntent intent = createFirstMultiple();
+        intent = createAnother();
         assertEquals("incorrect id", APPID, intent.appId());
         assertEquals("incorrect match", MATCH, intent.selector());
-        assertEquals("incorrect ingress", PS1, intent.ingressPoints());
-        assertEquals("incorrect egress", P2, intent.egressPoint());
-        assertEquals("incorrect selectors", MATCHES, intent.ingressSelectors());
+        assertEquals("incorrect ingress", PS2, intent.ingressPoints());
+        assertEquals("incorrect egress", P1, intent.egressPoint());
 
-        intent = createSecondMultiple();
+        intent = createVlanMatch();
         assertEquals("incorrect id", APPID, intent.appId());
         assertEquals("incorrect match", VLANMATCH1, intent.selector());
         assertEquals("incorrect ingress", PS1, intent.ingressPoints());
         assertEquals("incorrect egress", P2, intent.egressPoint());
-        assertEquals("incorrect selectors", MATCHES, intent.ingressSelectors());
-
-        intent = createThirdMultiple();
-        assertEquals("incorrect id", APPID, intent.appId());
-        assertEquals("incorrect match", MATCH, intent.selector());
-        assertEquals("incorrect ingress", PS1, intent.ingressPoints());
-        assertEquals("incorrect egress", P2, intent.egressPoint());
-        assertEquals("incorrect selectors", VLANMATCHES, intent.ingressSelectors());
-
-        wrongMultiple.expect(IllegalArgumentException.class);
-        wrongMultiple.expectMessage("Selector and Multiple Selectors are both set");
-        intent = createWrongMultiple();
     }
 
+    /**
+     * Create two intents with filtered connect points.
+     */
+    @Test
+    public void filteredIntent() {
+        MultiPointToSinglePointIntent intent = createFilteredOne();
+        assertEquals("incorrect id", APPID, intent.appId());
+        assertEquals("incorrect match", MATCH, intent.selector());
+        assertEquals("incorrect filtered ingress", FPS1, intent.filteredIngressPoints());
+        assertEquals("incorrect filtered egress", FP2, intent.filteredEgressPoint());
+
+        intent = createAnotherFiltered();
+        assertEquals("incorrect id", APPID, intent.appId());
+        assertEquals("incorrect match", MATCH, intent.selector());
+        assertEquals("incorrect filtered ingress", FPS2, intent.filteredIngressPoints());
+        assertEquals("incorrect filtered egress", FP1, intent.filteredEgressPoint());
+
+    }
 
     @Override
     protected MultiPointToSinglePointIntent createOne() {
@@ -100,47 +99,42 @@
                 .build();
     }
 
-    protected MultiPointToSinglePointIntent createFirstMultiple() {
-        return MultiPointToSinglePointIntent.builder()
-                .appId(APPID)
-                .selector(MATCH)
-                .treatment(NOP)
-                .ingressPoints(PS1)
-                .egressPoint(P2)
-                .selectors(MATCHES)
-                .build();
-    }
-
-    protected MultiPointToSinglePointIntent createSecondMultiple() {
+    protected MultiPointToSinglePointIntent createVlanMatch() {
         return MultiPointToSinglePointIntent.builder()
                 .appId(APPID)
                 .selector(VLANMATCH1)
                 .treatment(NOP)
                 .ingressPoints(PS1)
                 .egressPoint(P2)
-                .selectors(MATCHES)
                 .build();
     }
 
-    protected MultiPointToSinglePointIntent createThirdMultiple() {
+
+    protected MultiPointToSinglePointIntent createFilteredOne() {
         return MultiPointToSinglePointIntent.builder()
                 .appId(APPID)
-                .selector(MATCH)
                 .treatment(NOP)
-                .ingressPoints(PS1)
-                .egressPoint(P2)
-                .selectors(VLANMATCHES)
+                .filteredIngressPoints(FPS1)
+                .filteredEgressPoint(FP2)
                 .build();
     }
 
-    protected MultiPointToSinglePointIntent createWrongMultiple() {
+    protected MultiPointToSinglePointIntent createAnotherFiltered() {
+        return MultiPointToSinglePointIntent.builder()
+                .appId(APPID)
+                .treatment(NOP)
+                .filteredIngressPoints(FPS2)
+                .filteredEgressPoint(FP1)
+                .build();
+    }
+
+    protected MultiPointToSinglePointIntent createWrongIntent() {
         return MultiPointToSinglePointIntent.builder()
                 .appId(APPID)
                 .selector(VLANMATCH1)
                 .treatment(NOP)
-                .ingressPoints(PS1)
-                .egressPoint(P2)
-                .selectors(VLANMATCHES)
+                .filteredIngressPoints(FPS1)
+                .filteredEgressPoint(FP2)
                 .build();
     }
 
diff --git a/core/api/src/test/java/org/onosproject/net/intent/SinglePointToMultiPointIntentTest.java b/core/api/src/test/java/org/onosproject/net/intent/SinglePointToMultiPointIntentTest.java
index f3db2fb..76aaa85 100644
--- a/core/api/src/test/java/org/onosproject/net/intent/SinglePointToMultiPointIntentTest.java
+++ b/core/api/src/test/java/org/onosproject/net/intent/SinglePointToMultiPointIntentTest.java
@@ -15,9 +15,7 @@
  */
 package org.onosproject.net.intent;
 
-import org.junit.Rule;
 import org.junit.Test;
-import org.junit.rules.ExpectedException;
 
 import static org.junit.Assert.assertEquals;
 import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
@@ -42,41 +40,28 @@
         assertEquals("incorrect match", MATCH, intent.selector());
         assertEquals("incorrect ingress", P1, intent.ingressPoint());
         assertEquals("incorrect egress", PS2, intent.egressPoints());
+
+        intent = createAnother();
+        assertEquals("incorrect id", APPID, intent.appId());
+        assertEquals("incorrect match", MATCH, intent.selector());
+        assertEquals("incorrect ingress", P2, intent.ingressPoint());
+        assertEquals("incorrect egress", PS1, intent.egressPoints());
     }
 
-    @Rule
-    public ExpectedException wrongMultiple = ExpectedException.none();
-
     @Test
-    public void multipleTreatments() {
-
-        SinglePointToMultiPointIntent intent = createFirstMultiple();
+    public void filteredIntent() {
+        SinglePointToMultiPointIntent intent = createFilteredOne();
         assertEquals("incorrect id", APPID, intent.appId());
         assertEquals("incorrect match", MATCH, intent.selector());
-        assertEquals("incorrect ingress", P1, intent.ingressPoint());
-        assertEquals("incorrect egress", PS2, intent.egressPoints());
-        assertEquals("incorrect treatment", NOP, intent.treatment());
-        assertEquals("incorrect treatments", TREATMENTS, intent.egressTreatments());
+        assertEquals("incorrect filtered ingress", FP2, intent.filteredIngressPoint());
+        assertEquals("incorrect filtered egress", FPS1, intent.filteredEgressPoints());
 
-        intent = createSecondMultiple();
+        intent = createAnotherFiltered();
         assertEquals("incorrect id", APPID, intent.appId());
         assertEquals("incorrect match", MATCH, intent.selector());
-        assertEquals("incorrect ingress", P1, intent.ingressPoint());
-        assertEquals("incorrect egress", PS2, intent.egressPoints());
-        assertEquals("incorrect treatment", VLANACTION1, intent.treatment());
-        assertEquals("incorrect selectors", TREATMENTS, intent.egressTreatments());
+        assertEquals("incorrect filtered ingress", FP1, intent.filteredIngressPoint());
+        assertEquals("incorrect filtered egress", FPS2, intent.filteredEgressPoints());
 
-        intent = createThirdMultiple();
-        assertEquals("incorrect id", APPID, intent.appId());
-        assertEquals("incorrect match", MATCH, intent.selector());
-        assertEquals("incorrect ingress", P1, intent.ingressPoint());
-        assertEquals("incorrect egress", PS2, intent.egressPoints());
-        assertEquals("incorrect treatment", NOP, intent.treatment());
-        assertEquals("incorrect selectors", VLANACTIONS, intent.egressTreatments());
-
-        wrongMultiple.expect(IllegalArgumentException.class);
-        wrongMultiple.expectMessage("Treatment and Multiple Treatments are both set");
-        intent = createWrongMultiple();
     }
 
     @Override
@@ -101,48 +86,31 @@
                 .build();
     }
 
-
-    protected SinglePointToMultiPointIntent createFirstMultiple() {
+    protected SinglePointToMultiPointIntent createFilteredOne() {
         return SinglePointToMultiPointIntent.builder()
                 .appId(APPID)
-                .selector(MATCH)
                 .treatment(NOP)
-                .ingressPoint(P1)
-                .egressPoints(PS2)
-                .treatments(TREATMENTS)
+                .filteredEgressPoints(FPS1)
+                .filteredIngressPoint(FP2)
                 .build();
     }
 
-    protected SinglePointToMultiPointIntent createSecondMultiple() {
+    protected SinglePointToMultiPointIntent createAnotherFiltered() {
         return SinglePointToMultiPointIntent.builder()
                 .appId(APPID)
-                .selector(MATCH)
-                .treatment(VLANACTION1)
-                .ingressPoint(P1)
-                .egressPoints(PS2)
-                .treatments(TREATMENTS)
-                .build();
-    }
-
-    protected SinglePointToMultiPointIntent createThirdMultiple() {
-        return SinglePointToMultiPointIntent.builder()
-                .appId(APPID)
-                .selector(MATCH)
                 .treatment(NOP)
-                .ingressPoint(P1)
-                .egressPoints(PS2)
-                .treatments(VLANACTIONS)
+                .filteredEgressPoints(FPS2)
+                .filteredIngressPoint(FP1)
                 .build();
     }
 
-    protected SinglePointToMultiPointIntent createWrongMultiple() {
+    protected SinglePointToMultiPointIntent createWrongIntent() {
         return SinglePointToMultiPointIntent.builder()
                 .appId(APPID)
-                .selector(MATCH)
-                .treatment(VLANACTION1)
-                .ingressPoint(P1)
-                .egressPoints(PS2)
-                .treatments(VLANACTIONS)
+                .treatment(NOP)
+                .selector(VLANMATCH1)
+                .filteredEgressPoints(FPS2)
+                .filteredIngressPoint(FP1)
                 .build();
     }