Yi Tseng

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

Change-Id: Ibe9062c904ad9a6c3ba001fe57be7cec49eb8a4d
Showing 18 changed files with 1636 additions and 758 deletions
1 +/*
2 + * Copyright 2016-present Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.net;
18 +
19 +import com.google.common.base.MoreObjects;
20 +import org.onosproject.net.flow.DefaultTrafficSelector;
21 +import org.onosproject.net.flow.TrafficSelector;
22 +
23 +import java.util.Objects;
24 +
25 +/**
26 + * Connection point with TrafficSelector field.
27 + */
28 +public class FilteredConnectPoint {
29 + private final ConnectPoint connectPoint;
30 + private final TrafficSelector trafficSelector;
31 +
32 + /**
33 + * Creates filtered connect point with default traffic selector.
34 + *
35 + * @param connectPoint
36 + */
37 + public FilteredConnectPoint(ConnectPoint connectPoint) {
38 + this.connectPoint = connectPoint;
39 + this.trafficSelector = DefaultTrafficSelector.emptySelector();
40 + }
41 +
42 + /**
43 + * Creates new filtered connection point.
44 + *
45 + * @param connectPoint connect point
46 + * @param trafficSelector traffic selector for this connect point
47 + */
48 + public FilteredConnectPoint(ConnectPoint connectPoint, TrafficSelector trafficSelector) {
49 + this.connectPoint = connectPoint;
50 + this.trafficSelector = trafficSelector;
51 + }
52 +
53 + /**
54 + * Returns the traffic selector for this connect point.
55 + *
56 + * @return Traffic selector for this connect point
57 + */
58 + public TrafficSelector trafficSelector() {
59 + return trafficSelector;
60 + }
61 +
62 + /**
63 + * Returns the connection point.
64 + * @return
65 + */
66 + public ConnectPoint connectPoint() {
67 + return connectPoint;
68 + }
69 +
70 + @Override
71 + public int hashCode() {
72 + return Objects.hash(connectPoint, trafficSelector);
73 + }
74 +
75 + @Override
76 + public String toString() {
77 + return MoreObjects.toStringHelper(getClass())
78 + .add("connectPoint", connectPoint)
79 + .add("trafficSelector", trafficSelector)
80 + .toString();
81 + }
82 +
83 + @Override
84 + public boolean equals(Object obj) {
85 + if (obj == null) {
86 + return false;
87 + }
88 +
89 + if (this == obj) {
90 + return true;
91 + }
92 +
93 + if (obj instanceof FilteredConnectPoint) {
94 + FilteredConnectPoint other = (FilteredConnectPoint) obj;
95 + return other.connectPoint().equals(connectPoint) &&
96 + other.trafficSelector().equals(trafficSelector());
97 + } else {
98 + return false;
99 + }
100 + }
101 +}
...@@ -475,6 +475,23 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { ...@@ -475,6 +475,23 @@ public final class DefaultTrafficTreatment implements TrafficTreatment {
475 } 475 }
476 476
477 @Override 477 @Override
478 + public TrafficTreatment.Builder addTreatment(TrafficTreatment treatment) {
479 + List<Instruction> previous = current;
480 + deferred();
481 + treatment.deferred().forEach(i -> add(i));
482 +
483 + immediate();
484 + treatment.immediate().stream()
485 + // NOACTION will get re-added if there are no other actions
486 + .filter(i -> i.type() != Instruction.Type.NOACTION)
487 + .forEach(i -> add(i));
488 +
489 + clear = treatment.clearedDeferred();
490 + current = previous;
491 + return this;
492 + }
493 +
494 + @Override
478 public TrafficTreatment build() { 495 public TrafficTreatment build() {
479 if (deferred.size() == 0 && immediate.size() == 0 496 if (deferred.size() == 0 && immediate.size() == 0
480 && table == null && !clear) { 497 && table == null && !clear) {
......
...@@ -397,6 +397,14 @@ public interface TrafficTreatment { ...@@ -397,6 +397,14 @@ public interface TrafficTreatment {
397 Builder extension(ExtensionTreatment extension, DeviceId deviceId); 397 Builder extension(ExtensionTreatment extension, DeviceId deviceId);
398 398
399 /** 399 /**
400 + * Add all instructions from another treatment.
401 + *
402 + * @param treatment another treatment
403 + * @return a treatment builder
404 + */
405 + Builder addTreatment(TrafficTreatment treatment);
406 +
407 + /**
400 * Builds an immutable traffic treatment descriptor. 408 * Builds an immutable traffic treatment descriptor.
401 * <p> 409 * <p>
402 * If the treatment is empty when build() is called, it will add a default 410 * If the treatment is empty when build() is called, it will add a default
......
...@@ -58,18 +58,18 @@ public final class IntentUtils { ...@@ -58,18 +58,18 @@ public final class IntentUtils {
58 58
59 return Objects.equals(intent1.selector(), intent2.selector()) && 59 return Objects.equals(intent1.selector(), intent2.selector()) &&
60 Objects.equals(intent1.treatment(), intent2.treatment()) && 60 Objects.equals(intent1.treatment(), intent2.treatment()) &&
61 - Objects.equals(intent1.constraints(), intent2.constraints()) && 61 + Objects.equals(intent1.filteredIngressPoint(), intent2.filteredIngressPoint()) &&
62 - Objects.equals(intent1.ingressPoint(), intent2.ingressPoint()) && 62 + Objects.equals(intent1.filteredEgressPoints(), intent2.filteredEgressPoints()) &&
63 - Objects.equals(intent1.egressPoints(), intent2.egressPoints()); 63 + Objects.equals(intent1.constraints(), intent2.constraints());
64 } else if (one instanceof MultiPointToSinglePointIntent) { 64 } else if (one instanceof MultiPointToSinglePointIntent) {
65 MultiPointToSinglePointIntent intent1 = (MultiPointToSinglePointIntent) one; 65 MultiPointToSinglePointIntent intent1 = (MultiPointToSinglePointIntent) one;
66 MultiPointToSinglePointIntent intent2 = (MultiPointToSinglePointIntent) two; 66 MultiPointToSinglePointIntent intent2 = (MultiPointToSinglePointIntent) two;
67 67
68 return Objects.equals(intent1.selector(), intent2.selector()) && 68 return Objects.equals(intent1.selector(), intent2.selector()) &&
69 + Objects.equals(intent1.filteredIngressPoints(), intent2.filteredIngressPoints()) &&
70 + Objects.equals(intent1.filteredEgressPoint(), intent2.filteredEgressPoint()) &&
69 Objects.equals(intent1.treatment(), intent2.treatment()) && 71 Objects.equals(intent1.treatment(), intent2.treatment()) &&
70 - Objects.equals(intent1.constraints(), intent2.constraints()) && 72 + Objects.equals(intent1.constraints(), intent2.constraints());
71 - Objects.equals(intent1.ingressPoints(), intent2.ingressPoints()) &&
72 - Objects.equals(intent1.egressPoint(), intent2.egressPoint());
73 } else if (one instanceof PointToPointIntent) { 73 } else if (one instanceof PointToPointIntent) {
74 PointToPointIntent intent1 = (PointToPointIntent) one; 74 PointToPointIntent intent1 = (PointToPointIntent) one;
75 PointToPointIntent intent2 = (PointToPointIntent) two; 75 PointToPointIntent intent2 = (PointToPointIntent) two;
......
...@@ -17,19 +17,22 @@ ...@@ -17,19 +17,22 @@
17 package org.onosproject.net.intent; 17 package org.onosproject.net.intent;
18 18
19 import java.util.List; 19 import java.util.List;
20 -import java.util.Map;
21 import java.util.Set; 20 import java.util.Set;
21 +import java.util.stream.Collectors;
22 22
23 import com.google.common.annotations.Beta; 23 import com.google.common.annotations.Beta;
24 -import com.google.common.collect.ImmutableMap;
25 import org.onosproject.core.ApplicationId; 24 import org.onosproject.core.ApplicationId;
26 import org.onosproject.net.ConnectPoint; 25 import org.onosproject.net.ConnectPoint;
26 +import org.onosproject.net.FilteredConnectPoint;
27 import org.onosproject.net.Link; 27 import org.onosproject.net.Link;
28 import org.onosproject.net.flow.TrafficSelector; 28 import org.onosproject.net.flow.TrafficSelector;
29 import org.onosproject.net.flow.TrafficTreatment; 29 import org.onosproject.net.flow.TrafficTreatment;
30 30
31 import com.google.common.base.MoreObjects; 31 import com.google.common.base.MoreObjects;
32 import com.google.common.collect.ImmutableSet; 32 import com.google.common.collect.ImmutableSet;
33 +import org.slf4j.Logger;
34 +
35 +import static org.slf4j.LoggerFactory.getLogger;
33 36
34 /** 37 /**
35 * Abstraction of a connectivity intent that is implemented by a set of path 38 * Abstraction of a connectivity intent that is implemented by a set of path
...@@ -40,17 +43,11 @@ public final class LinkCollectionIntent extends ConnectivityIntent { ...@@ -40,17 +43,11 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
40 43
41 private final Set<Link> links; 44 private final Set<Link> links;
42 45
43 - private final Set<ConnectPoint> ingressPoints; 46 + private final Set<FilteredConnectPoint> ingressPoints;
44 - private final Set<ConnectPoint> egressPoints; 47 + private final Set<FilteredConnectPoint> egressPoints;
45 private final boolean egressTreatmentFlag; 48 private final boolean egressTreatmentFlag;
46 - /** 49 +
47 - * To manage multiple selectors use case. 50 +
48 - */
49 - private final Map<ConnectPoint, TrafficSelector> ingressSelectors;
50 - /**
51 - * To manage multiple treatments use case.
52 - */
53 - private final Map<ConnectPoint, TrafficTreatment> egressTreatments;
54 51
55 /** 52 /**
56 * Creates a new actionable intent capable of funneling the selected 53 * Creates a new actionable intent capable of funneling the selected
...@@ -62,13 +59,11 @@ public final class LinkCollectionIntent extends ConnectivityIntent { ...@@ -62,13 +59,11 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
62 * @param selector traffic match 59 * @param selector traffic match
63 * @param treatment action 60 * @param treatment action
64 * @param links traversed links 61 * @param links traversed links
65 - * @param ingressPoints ingress points 62 + * @param ingressPoints filtered ingress points
66 - * @param egressPoints egress points 63 + * @param egressPoints filtered egress points
67 * @param constraints optional list of constraints 64 * @param constraints optional list of constraints
68 * @param priority priority to use for the flows generated by this intent 65 * @param priority priority to use for the flows generated by this intent
69 * @param egressTreatment true if treatment should be applied by the egress device 66 * @param egressTreatment true if treatment should be applied by the egress device
70 - * @param ingressSelectors map to store the association ingress to selector
71 - * @param egressTreatments map to store the association egress to treatment
72 * @throws NullPointerException {@code path} is null 67 * @throws NullPointerException {@code path} is null
73 */ 68 */
74 private LinkCollectionIntent(ApplicationId appId, 69 private LinkCollectionIntent(ApplicationId appId,
...@@ -76,20 +71,16 @@ public final class LinkCollectionIntent extends ConnectivityIntent { ...@@ -76,20 +71,16 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
76 TrafficSelector selector, 71 TrafficSelector selector,
77 TrafficTreatment treatment, 72 TrafficTreatment treatment,
78 Set<Link> links, 73 Set<Link> links,
79 - Set<ConnectPoint> ingressPoints, 74 + Set<FilteredConnectPoint> ingressPoints,
80 - Set<ConnectPoint> egressPoints, 75 + Set<FilteredConnectPoint> egressPoints,
81 List<Constraint> constraints, 76 List<Constraint> constraints,
82 int priority, 77 int priority,
83 - boolean egressTreatment, 78 + boolean egressTreatment) {
84 - Map<ConnectPoint, TrafficSelector> ingressSelectors,
85 - Map<ConnectPoint, TrafficTreatment> egressTreatments) {
86 super(appId, key, resources(links), selector, treatment, constraints, priority); 79 super(appId, key, resources(links), selector, treatment, constraints, priority);
87 this.links = links; 80 this.links = links;
88 this.ingressPoints = ingressPoints; 81 this.ingressPoints = ingressPoints;
89 this.egressPoints = egressPoints; 82 this.egressPoints = egressPoints;
90 this.egressTreatmentFlag = egressTreatment; 83 this.egressTreatmentFlag = egressTreatment;
91 - this.ingressSelectors = ingressSelectors;
92 - this.egressTreatments = egressTreatments;
93 } 84 }
94 85
95 /** 86 /**
...@@ -101,8 +92,6 @@ public final class LinkCollectionIntent extends ConnectivityIntent { ...@@ -101,8 +92,6 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
101 this.ingressPoints = null; 92 this.ingressPoints = null;
102 this.egressPoints = null; 93 this.egressPoints = null;
103 this.egressTreatmentFlag = false; 94 this.egressTreatmentFlag = false;
104 - this.ingressSelectors = null;
105 - this.egressTreatments = null;
106 } 95 }
107 96
108 /** 97 /**
...@@ -121,12 +110,11 @@ public final class LinkCollectionIntent extends ConnectivityIntent { ...@@ -121,12 +110,11 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
121 * Builder of a single point to multi point intent. 110 * Builder of a single point to multi point intent.
122 */ 111 */
123 public static final class Builder extends ConnectivityIntent.Builder { 112 public static final class Builder extends ConnectivityIntent.Builder {
124 - Set<Link> links; 113 + private final Logger log = getLogger(getClass());
125 - Set<ConnectPoint> ingressPoints; 114 + private Set<Link> links;
126 - Set<ConnectPoint> egressPoints; 115 + private Set<FilteredConnectPoint> ingressPoints;
127 - Map<ConnectPoint, TrafficSelector> ingressSelectors = ImmutableMap.of(); 116 + private Set<FilteredConnectPoint> egressPoints;
128 - Map<ConnectPoint, TrafficTreatment> egressTreatments = ImmutableMap.of(); 117 + private boolean egressTreatmentFlag;
129 - boolean egressTreatmentFlag;
130 118
131 private Builder() { 119 private Builder() {
132 // Hide constructor 120 // Hide constructor
...@@ -169,8 +157,15 @@ public final class LinkCollectionIntent extends ConnectivityIntent { ...@@ -169,8 +157,15 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
169 * @param ingressPoints ingress connect points 157 * @param ingressPoints ingress connect points
170 * @return this builder 158 * @return this builder
171 */ 159 */
160 + @Deprecated
172 public Builder ingressPoints(Set<ConnectPoint> ingressPoints) { 161 public Builder ingressPoints(Set<ConnectPoint> ingressPoints) {
173 - this.ingressPoints = ImmutableSet.copyOf(ingressPoints); 162 + if (this.ingressPoints != null) {
163 + log.warn("Ingress points are already set, " +
164 + "this will override original ingress points.");
165 + }
166 + this.ingressPoints = ingressPoints.stream()
167 + .map(FilteredConnectPoint::new)
168 + .collect(Collectors.toSet());
174 return this; 169 return this;
175 } 170 }
176 171
...@@ -181,30 +176,39 @@ public final class LinkCollectionIntent extends ConnectivityIntent { ...@@ -181,30 +176,39 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
181 * @param egressPoints egress connect points 176 * @param egressPoints egress connect points
182 * @return this builder 177 * @return this builder
183 */ 178 */
179 + @Deprecated
184 public Builder egressPoints(Set<ConnectPoint> egressPoints) { 180 public Builder egressPoints(Set<ConnectPoint> egressPoints) {
185 - this.egressPoints = ImmutableSet.copyOf(egressPoints); 181 + if (this.egressPoints != null) {
182 + log.warn("Egress points are already set, " +
183 + "this will override original egress points.");
184 + }
185 + this.egressPoints = egressPoints.stream()
186 + .map(FilteredConnectPoint::new)
187 + .collect(Collectors.toSet());
186 return this; 188 return this;
187 } 189 }
188 190
189 /** 191 /**
190 - * Sets the map ingress selectors to connection points of the intent. 192 + * Sets the filtered ingress point of the single point to multi point intent
193 + * that will be built.
191 * 194 *
192 - * @param ingressSelectors maps connection point to traffic selector 195 + * @param ingressPoints ingress connect points
193 * @return this builder 196 * @return this builder
194 */ 197 */
195 - public Builder ingressSelectors(Map<ConnectPoint, TrafficSelector> ingressSelectors) { 198 + public Builder filteredIngressPoints(Set<FilteredConnectPoint> ingressPoints) {
196 - this.ingressSelectors = ImmutableMap.copyOf(ingressSelectors); 199 + this.ingressPoints = ImmutableSet.copyOf(ingressPoints);
197 return this; 200 return this;
198 } 201 }
199 202
200 /** 203 /**
201 - * Sets the map egress treatments to connection points of the intent. 204 + * Sets the filtered egress points of the single point to multi point intent
205 + * that will be built.
202 * 206 *
203 - * @param egressTreatments maps connection point to traffic treatment 207 + * @param egressPoints egress connect points
204 * @return this builder 208 * @return this builder
205 */ 209 */
206 - public Builder egressTreatments(Map<ConnectPoint, TrafficTreatment> egressTreatments) { 210 + public Builder filteredEgressPoints(Set<FilteredConnectPoint> egressPoints) {
207 - this.egressTreatments = ImmutableMap.copyOf(egressTreatments); 211 + this.egressPoints = ImmutableSet.copyOf(egressPoints);
208 return this; 212 return this;
209 } 213 }
210 214
...@@ -250,9 +254,7 @@ public final class LinkCollectionIntent extends ConnectivityIntent { ...@@ -250,9 +254,7 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
250 egressPoints, 254 egressPoints,
251 constraints, 255 constraints,
252 priority, 256 priority,
253 - egressTreatmentFlag, 257 + egressTreatmentFlag
254 - ingressSelectors,
255 - egressTreatments
256 ); 258 );
257 } 259 }
258 } 260 }
...@@ -273,7 +275,12 @@ public final class LinkCollectionIntent extends ConnectivityIntent { ...@@ -273,7 +275,12 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
273 * @return the ingress points 275 * @return the ingress points
274 */ 276 */
275 public Set<ConnectPoint> ingressPoints() { 277 public Set<ConnectPoint> ingressPoints() {
276 - return ingressPoints; 278 + if (this.ingressPoints == null) {
279 + return null;
280 + }
281 + return ingressPoints.stream()
282 + .map(FilteredConnectPoint::connectPoint)
283 + .collect(Collectors.toSet());
277 } 284 }
278 285
279 /** 286 /**
...@@ -282,23 +289,30 @@ public final class LinkCollectionIntent extends ConnectivityIntent { ...@@ -282,23 +289,30 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
282 * @return the egress points 289 * @return the egress points
283 */ 290 */
284 public Set<ConnectPoint> egressPoints() { 291 public Set<ConnectPoint> egressPoints() {
285 - return egressPoints; 292 + if (this.egressPoints == null) {
293 + return null;
294 + }
295 + return egressPoints.stream()
296 + .map(FilteredConnectPoint::connectPoint)
297 + .collect(Collectors.toSet());
286 } 298 }
287 299
288 /** 300 /**
289 - * Returns the multiple selectors jointly with their connection points. 301 + * Returns the filtered ingress points of the intent.
290 - * @return multiple selectors 302 + *
303 + * @return the ingress points
291 */ 304 */
292 - public Map<ConnectPoint, TrafficSelector> ingressSelectors() { 305 + public Set<FilteredConnectPoint> filteredIngressPoints() {
293 - return ingressSelectors; 306 + return ingressPoints;
294 } 307 }
295 308
296 /** 309 /**
297 - * Returns the multiple treatments jointly with their connection points. 310 + * Returns the egress points of the intent.
298 - * @return multiple treatments 311 + *
312 + * @return the egress points
299 */ 313 */
300 - public Map<ConnectPoint, TrafficTreatment> egressTreatments() { 314 + public Set<FilteredConnectPoint> filteredEgressPoints() {
301 - return egressTreatments; 315 + return egressPoints;
302 } 316 }
303 317
304 /** 318 /**
...@@ -323,8 +337,6 @@ public final class LinkCollectionIntent extends ConnectivityIntent { ...@@ -323,8 +337,6 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
323 .add("links", links()) 337 .add("links", links())
324 .add("ingress", ingressPoints()) 338 .add("ingress", ingressPoints())
325 .add("egress", egressPoints()) 339 .add("egress", egressPoints())
326 - .add("selectors", ingressSelectors())
327 - .add("treatments", egressTreatments())
328 .add("treatementOnEgress", applyTreatmentOnEgress()) 340 .add("treatementOnEgress", applyTreatmentOnEgress())
329 .toString(); 341 .toString();
330 } 342 }
......
...@@ -17,20 +17,21 @@ package org.onosproject.net.intent; ...@@ -17,20 +17,21 @@ package org.onosproject.net.intent;
17 17
18 import com.google.common.annotations.Beta; 18 import com.google.common.annotations.Beta;
19 import com.google.common.base.MoreObjects; 19 import com.google.common.base.MoreObjects;
20 -import com.google.common.collect.ImmutableMap;
21 import com.google.common.collect.ImmutableSet; 20 import com.google.common.collect.ImmutableSet;
22 -import com.google.common.collect.Sets;
23 import org.onosproject.core.ApplicationId; 21 import org.onosproject.core.ApplicationId;
24 import org.onosproject.net.ConnectPoint; 22 import org.onosproject.net.ConnectPoint;
23 +import org.onosproject.net.FilteredConnectPoint;
25 import org.onosproject.net.flow.TrafficSelector; 24 import org.onosproject.net.flow.TrafficSelector;
26 import org.onosproject.net.flow.TrafficTreatment; 25 import org.onosproject.net.flow.TrafficTreatment;
26 +import org.slf4j.Logger;
27 27
28 import java.util.List; 28 import java.util.List;
29 -import java.util.Map;
30 import java.util.Set; 29 import java.util.Set;
30 +import java.util.stream.Collectors;
31 31
32 import static com.google.common.base.Preconditions.checkArgument; 32 import static com.google.common.base.Preconditions.checkArgument;
33 import static com.google.common.base.Preconditions.checkNotNull; 33 import static com.google.common.base.Preconditions.checkNotNull;
34 +import static org.slf4j.LoggerFactory.getLogger;
34 35
35 /** 36 /**
36 * Abstraction of multiple source to single destination connectivity intent. 37 * Abstraction of multiple source to single destination connectivity intent.
...@@ -38,26 +39,21 @@ import static com.google.common.base.Preconditions.checkNotNull; ...@@ -38,26 +39,21 @@ import static com.google.common.base.Preconditions.checkNotNull;
38 @Beta 39 @Beta
39 public final class MultiPointToSinglePointIntent extends ConnectivityIntent { 40 public final class MultiPointToSinglePointIntent extends ConnectivityIntent {
40 41
41 - private final Set<ConnectPoint> ingressPoints; 42 + private final Set<FilteredConnectPoint> ingressPoints;
42 - private final ConnectPoint egressPoint; 43 + private final FilteredConnectPoint egressPoint;
43 - /**
44 - * To manage multiple selectors use case.
45 - */
46 - private final Map<ConnectPoint, TrafficSelector> ingressSelectors;
47 44
48 /** 45 /**
49 * Creates a new multi-to-single point connectivity intent for the specified 46 * Creates a new multi-to-single point connectivity intent for the specified
50 - * traffic selector and treatment. 47 + * traffic selector and treatment with filtered connect point.
51 * 48 *
52 * @param appId application identifier 49 * @param appId application identifier
53 * @param key intent key 50 * @param key intent key
54 * @param selector traffic selector 51 * @param selector traffic selector
55 * @param treatment treatment 52 * @param treatment treatment
56 - * @param ingressPoints set of ports from which ingress traffic originates 53 + * @param ingressPoints set of filtered ports from which ingress traffic originates
57 - * @param egressPoint port to which traffic will egress 54 + * @param egressPoint filtered port to which traffic will egress
58 * @param constraints constraints to apply to the intent 55 * @param constraints constraints to apply to the intent
59 * @param priority priority to use for flows generated by this intent 56 * @param priority priority to use for flows generated by this intent
60 - * @param ingressSelectors map to store the association ingress to selector
61 * @throws NullPointerException if {@code ingressPoints} or 57 * @throws NullPointerException if {@code ingressPoints} or
62 * {@code egressPoint} is null. 58 * {@code egressPoint} is null.
63 * @throws IllegalArgumentException if the size of {@code ingressPoints} is 59 * @throws IllegalArgumentException if the size of {@code ingressPoints} is
...@@ -67,11 +63,10 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent { ...@@ -67,11 +63,10 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent {
67 Key key, 63 Key key,
68 TrafficSelector selector, 64 TrafficSelector selector,
69 TrafficTreatment treatment, 65 TrafficTreatment treatment,
70 - Set<ConnectPoint> ingressPoints, 66 + Set<FilteredConnectPoint> ingressPoints,
71 - ConnectPoint egressPoint, 67 + FilteredConnectPoint egressPoint,
72 List<Constraint> constraints, 68 List<Constraint> constraints,
73 - int priority, 69 + int priority
74 - Map<ConnectPoint, TrafficSelector> ingressSelectors
75 ) { 70 ) {
76 super(appId, key, ImmutableSet.of(), selector, treatment, constraints, 71 super(appId, key, ImmutableSet.of(), selector, treatment, constraints,
77 priority); 72 priority);
...@@ -82,9 +77,8 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent { ...@@ -82,9 +77,8 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent {
82 checkArgument(!ingressPoints.contains(egressPoint), 77 checkArgument(!ingressPoints.contains(egressPoint),
83 "Set of ingresses should not contain egress (egress: %s)", egressPoint); 78 "Set of ingresses should not contain egress (egress: %s)", egressPoint);
84 79
85 - this.ingressPoints = Sets.newHashSet(ingressPoints); 80 + this.ingressPoints = ImmutableSet.copyOf(ingressPoints);
86 this.egressPoint = egressPoint; 81 this.egressPoint = egressPoint;
87 - this.ingressSelectors = ingressSelectors;
88 } 82 }
89 83
90 /** 84 /**
...@@ -94,7 +88,6 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent { ...@@ -94,7 +88,6 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent {
94 super(); 88 super();
95 this.ingressPoints = null; 89 this.ingressPoints = null;
96 this.egressPoint = null; 90 this.egressPoint = null;
97 - this.ingressSelectors = null;
98 } 91 }
99 92
100 /** 93 /**
...@@ -124,9 +117,9 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent { ...@@ -124,9 +117,9 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent {
124 * Builder of a multi point to single point intent. 117 * Builder of a multi point to single point intent.
125 */ 118 */
126 public static final class Builder extends ConnectivityIntent.Builder { 119 public static final class Builder extends ConnectivityIntent.Builder {
127 - Set<ConnectPoint> ingressPoints; 120 + private final Logger log = getLogger(getClass());
128 - ConnectPoint egressPoint; 121 + private Set<FilteredConnectPoint> ingressPoints;
129 - Map<ConnectPoint, TrafficSelector> ingressSelectors = ImmutableMap.of(); 122 + private FilteredConnectPoint egressPoint;
130 123
131 private Builder() { 124 private Builder() {
132 // Hide constructor 125 // Hide constructor
...@@ -141,8 +134,9 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent { ...@@ -141,8 +134,9 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent {
141 protected Builder(MultiPointToSinglePointIntent intent) { 134 protected Builder(MultiPointToSinglePointIntent intent) {
142 super(intent); 135 super(intent);
143 136
144 - this.ingressPoints(intent.ingressPoints()) 137 + this.filteredIngressPoints(intent.filteredIngressPoints())
145 - .egressPoint(intent.egressPoint()); 138 + .filteredEgressPoint(intent.filteredEgressPoint());
139 +
146 } 140 }
147 141
148 @Override 142 @Override
...@@ -182,8 +176,15 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent { ...@@ -182,8 +176,15 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent {
182 * @param ingressPoints ingress connect points 176 * @param ingressPoints ingress connect points
183 * @return this builder 177 * @return this builder
184 */ 178 */
179 + @Deprecated
185 public Builder ingressPoints(Set<ConnectPoint> ingressPoints) { 180 public Builder ingressPoints(Set<ConnectPoint> ingressPoints) {
186 - this.ingressPoints = ImmutableSet.copyOf(ingressPoints); 181 + if (this.ingressPoints != null) {
182 + log.warn("Ingress points are already set, " +
183 + "this will override original ingress points.");
184 + }
185 + this.ingressPoints = ingressPoints.stream()
186 + .map(FilteredConnectPoint::new)
187 + .collect(Collectors.toSet());
187 return this; 188 return this;
188 } 189 }
189 190
...@@ -194,20 +195,37 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent { ...@@ -194,20 +195,37 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent {
194 * @param egressPoint egress connect point 195 * @param egressPoint egress connect point
195 * @return this builder 196 * @return this builder
196 */ 197 */
198 + @Deprecated
197 public Builder egressPoint(ConnectPoint egressPoint) { 199 public Builder egressPoint(ConnectPoint egressPoint) {
198 - this.egressPoint = egressPoint; 200 + if (this.egressPoint != null) {
201 + log.warn("Egress point is already set, " +
202 + "this will override original egress point.");
203 + }
204 + this.egressPoint = new FilteredConnectPoint(egressPoint);
205 + return this;
206 + }
207 +
208 + /**
209 + * Sets the filtered ingress point of the single point to multi point intent
210 + * that will be built.
211 + *
212 + * @param ingressPoints filtered ingress connect points
213 + * @return this builder
214 + */
215 + public Builder filteredIngressPoints(Set<FilteredConnectPoint> ingressPoints) {
216 + this.ingressPoints = ImmutableSet.copyOf(ingressPoints);
199 return this; 217 return this;
200 } 218 }
201 219
202 /** 220 /**
203 - * Sets the selectors of the multi point to single point intent 221 + * Sets the filtered egress point of the multi point to single point intent
204 * that will be built. 222 * that will be built.
205 * 223 *
206 - * @param ingressSelectors the multiple selectos 224 + * @param egressPoint filtered egress connect point
207 * @return this builder 225 * @return this builder
208 */ 226 */
209 - public Builder selectors(Map<ConnectPoint, TrafficSelector> ingressSelectors) { 227 + public Builder filteredEgressPoint(FilteredConnectPoint egressPoint) {
210 - this.ingressSelectors = ImmutableMap.copyOf(ingressSelectors); 228 + this.egressPoint = egressPoint;
211 return this; 229 return this;
212 } 230 }
213 231
...@@ -219,11 +237,6 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent { ...@@ -219,11 +237,6 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent {
219 */ 237 */
220 public MultiPointToSinglePointIntent build() { 238 public MultiPointToSinglePointIntent build() {
221 239
222 - if (selector != null && !selector.criteria().isEmpty() &&
223 - ingressSelectors != null && !ingressSelectors.isEmpty()) {
224 - throw new IllegalArgumentException("Selector and Multiple Selectors are both set");
225 - }
226 -
227 return new MultiPointToSinglePointIntent( 240 return new MultiPointToSinglePointIntent(
228 appId, 241 appId,
229 key, 242 key,
...@@ -232,8 +245,7 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent { ...@@ -232,8 +245,7 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent {
232 ingressPoints, 245 ingressPoints,
233 egressPoint, 246 egressPoint,
234 constraints, 247 constraints,
235 - priority, 248 + priority
236 - ingressSelectors
237 ); 249 );
238 } 250 }
239 } 251 }
...@@ -246,7 +258,9 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent { ...@@ -246,7 +258,9 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent {
246 * @return set of ingress ports 258 * @return set of ingress ports
247 */ 259 */
248 public Set<ConnectPoint> ingressPoints() { 260 public Set<ConnectPoint> ingressPoints() {
249 - return ingressPoints; 261 + return ingressPoints.stream()
262 + .map(FilteredConnectPoint::connectPoint)
263 + .collect(Collectors.toSet());
250 } 264 }
251 265
252 /** 266 /**
...@@ -255,17 +269,29 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent { ...@@ -255,17 +269,29 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent {
255 * @return egress port 269 * @return egress port
256 */ 270 */
257 public ConnectPoint egressPoint() { 271 public ConnectPoint egressPoint() {
258 - return egressPoint; 272 + return egressPoint.connectPoint();
273 + }
274 +
275 + /**
276 + * Returns the set of ports on which ingress traffic should be connected to
277 + * the egress port.
278 + *
279 + * @return set of ingress ports
280 + */
281 + public Set<FilteredConnectPoint> filteredIngressPoints() {
282 + return ingressPoints;
259 } 283 }
260 284
261 /** 285 /**
262 - * Returns the multiple selectors jointly with their connection points. 286 + * Returns the port on which the traffic should egress.
263 - * @return multiple selectors 287 + *
288 + * @return egress port
264 */ 289 */
265 - public Map<ConnectPoint, TrafficSelector> ingressSelectors() { 290 + public FilteredConnectPoint filteredEgressPoint() {
266 - return ingressSelectors; 291 + return egressPoint;
267 } 292 }
268 293
294 +
269 @Override 295 @Override
270 public String toString() { 296 public String toString() {
271 return MoreObjects.toStringHelper(getClass()) 297 return MoreObjects.toStringHelper(getClass())
...@@ -278,7 +304,8 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent { ...@@ -278,7 +304,8 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent {
278 .add("treatment", treatment()) 304 .add("treatment", treatment())
279 .add("ingress", ingressPoints()) 305 .add("ingress", ingressPoints())
280 .add("egress", egressPoint()) 306 .add("egress", egressPoint())
281 - .add("selectors", ingressSelectors()) 307 + .add("filteredIngressCPs", filteredIngressPoints())
308 + .add("filteredEgressCP", filteredEgressPoint())
282 .add("constraints", constraints()) 309 .add("constraints", constraints())
283 .toString(); 310 .toString();
284 } 311 }
......
...@@ -18,35 +18,31 @@ package org.onosproject.net.intent; ...@@ -18,35 +18,31 @@ package org.onosproject.net.intent;
18 import com.google.common.annotations.Beta; 18 import com.google.common.annotations.Beta;
19 import com.google.common.base.MoreObjects; 19 import com.google.common.base.MoreObjects;
20 import com.google.common.collect.ImmutableList; 20 import com.google.common.collect.ImmutableList;
21 -import com.google.common.collect.ImmutableMap;
22 import com.google.common.collect.ImmutableSet; 21 import com.google.common.collect.ImmutableSet;
23 22
24 import com.google.common.collect.Sets; 23 import com.google.common.collect.Sets;
25 import org.onosproject.core.ApplicationId; 24 import org.onosproject.core.ApplicationId;
26 import org.onosproject.net.ConnectPoint; 25 import org.onosproject.net.ConnectPoint;
27 -import org.onosproject.net.flow.DefaultTrafficTreatment; 26 +import org.onosproject.net.FilteredConnectPoint;
28 import org.onosproject.net.flow.TrafficSelector; 27 import org.onosproject.net.flow.TrafficSelector;
29 import org.onosproject.net.flow.TrafficTreatment; 28 import org.onosproject.net.flow.TrafficTreatment;
29 +import org.slf4j.Logger;
30 30
31 -import java.util.Map;
32 import java.util.Set; 31 import java.util.Set;
33 import java.util.List; 32 import java.util.List;
33 +import java.util.stream.Collectors;
34 34
35 import static com.google.common.base.Preconditions.checkArgument; 35 import static com.google.common.base.Preconditions.checkArgument;
36 import static com.google.common.base.Preconditions.checkNotNull; 36 import static com.google.common.base.Preconditions.checkNotNull;
37 +import static org.slf4j.LoggerFactory.getLogger;
37 38
38 /** 39 /**
39 * Abstraction of single source, multiple destination connectivity intent. 40 * Abstraction of single source, multiple destination connectivity intent.
40 */ 41 */
41 @Beta 42 @Beta
42 public final class SinglePointToMultiPointIntent extends ConnectivityIntent { 43 public final class SinglePointToMultiPointIntent extends ConnectivityIntent {
43 - 44 + private final FilteredConnectPoint ingressPoint;
44 - private final ConnectPoint ingressPoint; 45 + private final Set<FilteredConnectPoint> egressPoints;
45 - private final Set<ConnectPoint> egressPoints;
46 - /**
47 - * To manage multiple treatments use case.
48 - */
49 - private final Map<ConnectPoint, TrafficTreatment> egressTreatments;
50 46
51 /** 47 /**
52 * Creates a new single-to-multi point connectivity intent. 48 * Creates a new single-to-multi point connectivity intent.
...@@ -59,7 +55,6 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent { ...@@ -59,7 +55,6 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent {
59 * @param egressPoints set of ports on which traffic will egress 55 * @param egressPoints set of ports on which traffic will egress
60 * @param constraints constraints to apply to the intent 56 * @param constraints constraints to apply to the intent
61 * @param priority priority to use for flows generated by this intent 57 * @param priority priority to use for flows generated by this intent
62 - * @param egressTreatments map to store the association egress to treatment
63 * @throws NullPointerException if {@code ingressPoint} or 58 * @throws NullPointerException if {@code ingressPoint} or
64 * {@code egressPoints} is null 59 * {@code egressPoints} is null
65 * @throws IllegalArgumentException if the size of {@code egressPoints} is 60 * @throws IllegalArgumentException if the size of {@code egressPoints} is
...@@ -69,11 +64,10 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent { ...@@ -69,11 +64,10 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent {
69 Key key, 64 Key key,
70 TrafficSelector selector, 65 TrafficSelector selector,
71 TrafficTreatment treatment, 66 TrafficTreatment treatment,
72 - ConnectPoint ingressPoint, 67 + FilteredConnectPoint ingressPoint,
73 - Set<ConnectPoint> egressPoints, 68 + Set<FilteredConnectPoint> egressPoints,
74 List<Constraint> constraints, 69 List<Constraint> constraints,
75 - int priority, 70 + int priority) {
76 - Map<ConnectPoint, TrafficTreatment> egressTreatments) {
77 super(appId, key, ImmutableList.of(), selector, treatment, constraints, 71 super(appId, key, ImmutableList.of(), selector, treatment, constraints,
78 priority); 72 priority);
79 checkNotNull(egressPoints); 73 checkNotNull(egressPoints);
...@@ -84,7 +78,6 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent { ...@@ -84,7 +78,6 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent {
84 78
85 this.ingressPoint = ingressPoint; 79 this.ingressPoint = ingressPoint;
86 this.egressPoints = Sets.newHashSet(egressPoints); 80 this.egressPoints = Sets.newHashSet(egressPoints);
87 - this.egressTreatments = egressTreatments;
88 } 81 }
89 82
90 /** 83 /**
...@@ -100,17 +93,42 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent { ...@@ -100,17 +93,42 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent {
100 } 93 }
101 94
102 /** 95 /**
96 + * Creates a new builder pre-populated with the information in the given
97 + * intent.
98 + *
99 + * @param intent initial intent
100 + * @return intent builder
101 + */
102 + public static Builder builder(SinglePointToMultiPointIntent intent) {
103 + return new Builder(intent);
104 + }
105 +
106 + /**
103 * Builder of a single point to multi point intent. 107 * Builder of a single point to multi point intent.
104 */ 108 */
105 public static final class Builder extends ConnectivityIntent.Builder { 109 public static final class Builder extends ConnectivityIntent.Builder {
106 - ConnectPoint ingressPoint; 110 + private final Logger log = getLogger(getClass());
107 - Set<ConnectPoint> egressPoints; 111 + private FilteredConnectPoint ingressPoint;
108 - Map<ConnectPoint, TrafficTreatment> egressTreatments = ImmutableMap.of(); 112 + private Set<FilteredConnectPoint> egressPoints;
109 113
110 private Builder() { 114 private Builder() {
111 // Hide constructor 115 // Hide constructor
112 } 116 }
113 117
118 + /**
119 + * Creates a new builder pre-populated with information from the given
120 + * intent.
121 + *
122 + * @param intent initial intent
123 + */
124 + protected Builder(SinglePointToMultiPointIntent intent) {
125 + super(intent);
126 +
127 + this.filteredEgressPoints(intent.filteredEgressPoints())
128 + .filteredIngressPoint(intent.filteredIngressPoint());
129 +
130 + }
131 +
114 @Override 132 @Override
115 public Builder appId(ApplicationId appId) { 133 public Builder appId(ApplicationId appId) {
116 return (Builder) super.appId(appId); 134 return (Builder) super.appId(appId);
...@@ -148,8 +166,13 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent { ...@@ -148,8 +166,13 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent {
148 * @param ingressPoint ingress connect point 166 * @param ingressPoint ingress connect point
149 * @return this builder 167 * @return this builder
150 */ 168 */
169 + @Deprecated
151 public Builder ingressPoint(ConnectPoint ingressPoint) { 170 public Builder ingressPoint(ConnectPoint ingressPoint) {
152 - this.ingressPoint = ingressPoint; 171 + if (this.ingressPoint != null) {
172 + log.warn("Ingress point is already set, " +
173 + "this will override original ingress point.");
174 + }
175 + this.ingressPoint = new FilteredConnectPoint(ingressPoint);
153 return this; 176 return this;
154 } 177 }
155 178
...@@ -160,23 +183,45 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent { ...@@ -160,23 +183,45 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent {
160 * @param egressPoints egress connect points 183 * @param egressPoints egress connect points
161 * @return this builder 184 * @return this builder
162 */ 185 */
186 + @Deprecated
163 public Builder egressPoints(Set<ConnectPoint> egressPoints) { 187 public Builder egressPoints(Set<ConnectPoint> egressPoints) {
164 - this.egressPoints = ImmutableSet.copyOf(egressPoints); 188 + if (this.egressPoints != null) {
189 + log.warn("Egress points are already set, " +
190 + "this will override original egress points.");
191 + }
192 + Set<FilteredConnectPoint> filteredConnectPoints =
193 + egressPoints.stream()
194 + .map(FilteredConnectPoint::new)
195 + .collect(Collectors.toSet());
196 + this.egressPoints = ImmutableSet.copyOf(filteredConnectPoints);
165 return this; 197 return this;
166 } 198 }
167 199
168 /** 200 /**
169 - * Sets the treatments of the single point to multi point intent 201 + * Sets the filtered ingress point of the single point to
170 - * that will be built. 202 + * multi point intent that will be built.
203 + *
204 + * @param ingressPoint ingress connect point
205 + * @return this builder
206 + */
207 + public Builder filteredIngressPoint(FilteredConnectPoint ingressPoint) {
208 + this.ingressPoint = ingressPoint;
209 + return this;
210 + }
211 +
212 + /**
213 + * Sets the filtered egress points of the single point to
214 + * multi point intent that will be built.
171 * 215 *
172 - * @param egressTreatments the multiple treatments 216 + * @param egressPoints egress connect points
173 * @return this builder 217 * @return this builder
174 */ 218 */
175 - public Builder treatments(Map<ConnectPoint, TrafficTreatment> egressTreatments) { 219 + public Builder filteredEgressPoints(Set<FilteredConnectPoint> egressPoints) {
176 - this.egressTreatments = ImmutableMap.copyOf(egressTreatments); 220 + this.egressPoints = ImmutableSet.copyOf(egressPoints);
177 return this; 221 return this;
178 } 222 }
179 223
224 +
180 /** 225 /**
181 * Builds a single point to multi point intent from the 226 * Builds a single point to multi point intent from the
182 * accumulated parameters. 227 * accumulated parameters.
...@@ -185,12 +230,6 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent { ...@@ -185,12 +230,6 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent {
185 */ 230 */
186 public SinglePointToMultiPointIntent build() { 231 public SinglePointToMultiPointIntent build() {
187 232
188 - if (treatment != null && !treatment.allInstructions().isEmpty() &&
189 - !treatment.equals(DefaultTrafficTreatment.emptyTreatment()) &&
190 - egressTreatments != null && !egressTreatments.isEmpty()) {
191 - throw new IllegalArgumentException("Treatment and Multiple Treatments are both set");
192 - }
193 -
194 return new SinglePointToMultiPointIntent( 233 return new SinglePointToMultiPointIntent(
195 appId, 234 appId,
196 key, 235 key,
...@@ -199,8 +238,7 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent { ...@@ -199,8 +238,7 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent {
199 ingressPoint, 238 ingressPoint,
200 egressPoints, 239 egressPoints,
201 constraints, 240 constraints,
202 - priority, 241 + priority
203 - egressTreatments
204 ); 242 );
205 } 243 }
206 } 244 }
...@@ -212,7 +250,6 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent { ...@@ -212,7 +250,6 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent {
212 super(); 250 super();
213 this.ingressPoint = null; 251 this.ingressPoint = null;
214 this.egressPoints = null; 252 this.egressPoints = null;
215 - this.egressTreatments = null;
216 } 253 }
217 254
218 /** 255 /**
...@@ -222,7 +259,7 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent { ...@@ -222,7 +259,7 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent {
222 * @return ingress port 259 * @return ingress port
223 */ 260 */
224 public ConnectPoint ingressPoint() { 261 public ConnectPoint ingressPoint() {
225 - return ingressPoint; 262 + return ingressPoint.connectPoint();
226 } 263 }
227 264
228 /** 265 /**
...@@ -231,17 +268,31 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent { ...@@ -231,17 +268,31 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent {
231 * @return set of egress ports 268 * @return set of egress ports
232 */ 269 */
233 public Set<ConnectPoint> egressPoints() { 270 public Set<ConnectPoint> egressPoints() {
234 - return egressPoints; 271 + return egressPoints.stream()
272 + .map(FilteredConnectPoint::connectPoint)
273 + .collect(Collectors.toSet());
235 } 274 }
236 275
237 /** 276 /**
238 - * Returns the multiple treatments jointly with their connection points. 277 + * Returns the filtered port on which the ingress traffic should be connected to the
239 - * @return multiple treatments 278 + * egress.
279 + *
280 + * @return ingress port
281 + */
282 + public FilteredConnectPoint filteredIngressPoint() {
283 + return ingressPoint;
284 + }
285 +
286 + /**
287 + * Returns the set of filtered ports on which the traffic should egress.
288 + *
289 + * @return set of egress ports
240 */ 290 */
241 - public Map<ConnectPoint, TrafficTreatment> egressTreatments() { 291 + public Set<FilteredConnectPoint> filteredEgressPoints() {
242 - return egressTreatments; 292 + return egressPoints;
243 } 293 }
244 294
295 +
245 @Override 296 @Override
246 public String toString() { 297 public String toString() {
247 return MoreObjects.toStringHelper(getClass()) 298 return MoreObjects.toStringHelper(getClass())
...@@ -254,7 +305,8 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent { ...@@ -254,7 +305,8 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent {
254 .add("treatment", treatment()) 305 .add("treatment", treatment())
255 .add("ingress", ingressPoint) 306 .add("ingress", ingressPoint)
256 .add("egress", egressPoints) 307 .add("egress", egressPoints)
257 - .add("treatments", egressTreatments) 308 + .add("filteredIngressCPs", filteredIngressPoint())
309 + .add("filteredEgressCP", filteredEgressPoints())
258 .add("constraints", constraints()) 310 .add("constraints", constraints())
259 .toString(); 311 .toString();
260 } 312 }
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
15 */ 15 */
16 package org.onosproject.net.intent; 16 package org.onosproject.net.intent;
17 17
18 -import java.util.Collections;
19 import java.util.Map; 18 import java.util.Map;
20 import java.util.Set; 19 import java.util.Set;
21 20
...@@ -25,6 +24,7 @@ import org.onosproject.core.ApplicationId; ...@@ -25,6 +24,7 @@ import org.onosproject.core.ApplicationId;
25 import org.onosproject.TestApplicationId; 24 import org.onosproject.TestApplicationId;
26 import org.onosproject.net.ConnectPoint; 25 import org.onosproject.net.ConnectPoint;
27 import org.onosproject.net.DeviceId; 26 import org.onosproject.net.DeviceId;
27 +import org.onosproject.net.FilteredConnectPoint;
28 import org.onosproject.net.PortNumber; 28 import org.onosproject.net.PortNumber;
29 import org.onosproject.net.flow.DefaultTrafficSelector; 29 import org.onosproject.net.flow.DefaultTrafficSelector;
30 import org.onosproject.net.flow.DefaultTrafficTreatment; 30 import org.onosproject.net.flow.DefaultTrafficTreatment;
...@@ -42,8 +42,6 @@ public abstract class ConnectivityIntentTest extends IntentTest { ...@@ -42,8 +42,6 @@ public abstract class ConnectivityIntentTest extends IntentTest {
42 public static final IntentId IID = new IntentId(123); 42 public static final IntentId IID = new IntentId(123);
43 public static final TrafficSelector MATCH = DefaultTrafficSelector.emptySelector(); 43 public static final TrafficSelector MATCH = DefaultTrafficSelector.emptySelector();
44 public static final TrafficTreatment NOP = DefaultTrafficTreatment.emptyTreatment(); 44 public static final TrafficTreatment NOP = DefaultTrafficTreatment.emptyTreatment();
45 - public static final Map<ConnectPoint, TrafficSelector> MATCHES = Collections.emptyMap();
46 - public static final Map<ConnectPoint, TrafficTreatment> TREATMENTS = Collections.emptyMap();
47 45
48 public static final ConnectPoint P1 = new ConnectPoint(DeviceId.deviceId("111"), PortNumber.portNumber(0x1)); 46 public static final ConnectPoint P1 = new ConnectPoint(DeviceId.deviceId("111"), PortNumber.portNumber(0x1));
49 public static final ConnectPoint P2 = new ConnectPoint(DeviceId.deviceId("222"), PortNumber.portNumber(0x2)); 47 public static final ConnectPoint P2 = new ConnectPoint(DeviceId.deviceId("222"), PortNumber.portNumber(0x2));
...@@ -52,6 +50,7 @@ public abstract class ConnectivityIntentTest extends IntentTest { ...@@ -52,6 +50,7 @@ public abstract class ConnectivityIntentTest extends IntentTest {
52 public static final Set<ConnectPoint> PS1 = itemSet(new ConnectPoint[]{P1, P3}); 50 public static final Set<ConnectPoint> PS1 = itemSet(new ConnectPoint[]{P1, P3});
53 public static final Set<ConnectPoint> PS2 = itemSet(new ConnectPoint[]{P2, P3}); 51 public static final Set<ConnectPoint> PS2 = itemSet(new ConnectPoint[]{P2, P3});
54 52
53 +
55 public static final TrafficSelector VLANMATCH1 = DefaultTrafficSelector.builder() 54 public static final TrafficSelector VLANMATCH1 = DefaultTrafficSelector.builder()
56 .matchVlanId(VlanId.vlanId("2")) 55 .matchVlanId(VlanId.vlanId("2"))
57 .build(); 56 .build();
...@@ -59,6 +58,13 @@ public abstract class ConnectivityIntentTest extends IntentTest { ...@@ -59,6 +58,13 @@ public abstract class ConnectivityIntentTest extends IntentTest {
59 .matchVlanId(VlanId.vlanId("3")) 58 .matchVlanId(VlanId.vlanId("3"))
60 .build(); 59 .build();
61 60
61 + public static final FilteredConnectPoint FP1 = new FilteredConnectPoint(P1, VLANMATCH1);
62 + public static final FilteredConnectPoint FP2 = new FilteredConnectPoint(P2, VLANMATCH1);
63 + public static final FilteredConnectPoint FP3 = new FilteredConnectPoint(P3, VLANMATCH2);
64 +
65 + public static final Set<FilteredConnectPoint> FPS1 = itemSet(new FilteredConnectPoint[]{FP1, FP3});
66 + public static final Set<FilteredConnectPoint> FPS2 = itemSet(new FilteredConnectPoint[]{FP2, FP3});
67 +
62 public static final Map<ConnectPoint, TrafficSelector> VLANMATCHES = Maps.newHashMap(); 68 public static final Map<ConnectPoint, TrafficSelector> VLANMATCHES = Maps.newHashMap();
63 static { 69 static {
64 VLANMATCHES.put(P1, VLANMATCH1); 70 VLANMATCHES.put(P1, VLANMATCH1);
......
...@@ -26,7 +26,7 @@ import org.onosproject.net.Link; ...@@ -26,7 +26,7 @@ import org.onosproject.net.Link;
26 import org.onosproject.net.NetTestTools; 26 import org.onosproject.net.NetTestTools;
27 import org.onosproject.net.NetworkResource; 27 import org.onosproject.net.NetworkResource;
28 import org.onosproject.net.Path; 28 import org.onosproject.net.Path;
29 -import org.onosproject.net.flow.FlowRule.FlowRemoveReason; 29 +import org.onosproject.net.device.DeviceServiceAdapter;
30 import org.onosproject.net.flow.FlowId; 30 import org.onosproject.net.flow.FlowId;
31 import org.onosproject.net.flow.FlowRule; 31 import org.onosproject.net.flow.FlowRule;
32 import org.onosproject.net.flow.FlowRuleExtPayLoad; 32 import org.onosproject.net.flow.FlowRuleExtPayLoad;
...@@ -180,6 +180,67 @@ public class IntentTestsMocks { ...@@ -180,6 +180,67 @@ public class IntentTestsMocks {
180 } 180 }
181 } 181 }
182 182
183 + /**
184 + * Mock path service for creating paths within the test.
185 + *
186 + */
187 + public static class Mp2MpMockPathService
188 + extends PathServiceAdapter {
189 +
190 + final String[] pathHops;
191 + final String[] reversePathHops;
192 +
193 + /**
194 + * Constructor that provides a set of hops to mock.
195 + *
196 + * @param pathHops path hops to mock
197 + */
198 + public Mp2MpMockPathService(String[] pathHops) {
199 + this.pathHops = pathHops;
200 + String[] reversed = pathHops.clone();
201 + Collections.reverse(Arrays.asList(reversed));
202 + reversePathHops = reversed;
203 + }
204 +
205 + @Override
206 + public Set<Path> getPaths(ElementId src, ElementId dst) {
207 + Set<Path> result = new HashSet<>();
208 +
209 + String[] allHops = new String[pathHops.length + 2];
210 + allHops[0] = src.toString();
211 + allHops[allHops.length - 1] = dst.toString();
212 +
213 + if (pathHops.length != 0) {
214 + System.arraycopy(pathHops, 0, allHops, 1, pathHops.length);
215 + }
216 +
217 + result.add(createPath(allHops));
218 +
219 + return result;
220 + }
221 +
222 + @Override
223 + public Set<Path> getPaths(ElementId src, ElementId dst, LinkWeight weight) {
224 + final Set<Path> paths = getPaths(src, dst);
225 +
226 + for (Path path : paths) {
227 + final DeviceId srcDevice = path.src().elementId() instanceof DeviceId ? path.src().deviceId() : null;
228 + final DeviceId dstDevice = path.dst().elementId() instanceof DeviceId ? path.dst().deviceId() : null;
229 + if (srcDevice != null && dstDevice != null) {
230 + final TopologyVertex srcVertex = new DefaultTopologyVertex(srcDevice);
231 + final TopologyVertex dstVertex = new DefaultTopologyVertex(dstDevice);
232 + final Link link = link(src.toString(), 1, dst.toString(), 1);
233 +
234 + final double weightValue = weight.weight(new DefaultTopologyEdge(srcVertex, dstVertex, link));
235 + if (weightValue < 0) {
236 + return new HashSet<>();
237 + }
238 + }
239 + }
240 + return paths;
241 + }
242 + }
243 +
183 public static final class MockResourceService implements ResourceService { 244 public static final class MockResourceService implements ResourceService {
184 245
185 private final double bandwidth; 246 private final double bandwidth;
...@@ -429,4 +490,14 @@ public class IntentTestsMocks { ...@@ -429,4 +490,14 @@ public class IntentTestsMocks {
429 } 490 }
430 } 491 }
431 492
493 + /**
494 + * Mocks the device service so that a device appears available in the test.
495 + */
496 + public static class MockDeviceService extends DeviceServiceAdapter {
497 + @Override
498 + public boolean isAvailable(DeviceId deviceId) {
499 + return true;
500 + }
501 + }
502 +
432 } 503 }
......
...@@ -21,8 +21,10 @@ import java.util.LinkedList; ...@@ -21,8 +21,10 @@ import java.util.LinkedList;
21 import java.util.List; 21 import java.util.List;
22 import java.util.Set; 22 import java.util.Set;
23 23
24 +import com.google.common.collect.Sets;
24 import org.junit.Test; 25 import org.junit.Test;
25 import org.onosproject.net.ConnectPoint; 26 import org.onosproject.net.ConnectPoint;
27 +import org.onosproject.net.FilteredConnectPoint;
26 import org.onosproject.net.Link; 28 import org.onosproject.net.Link;
27 import org.onosproject.net.NetTestTools; 29 import org.onosproject.net.NetTestTools;
28 import org.onosproject.net.flow.TrafficSelector; 30 import org.onosproject.net.flow.TrafficSelector;
...@@ -49,6 +51,8 @@ public class LinkCollectionIntentTest extends IntentTest { ...@@ -49,6 +51,8 @@ public class LinkCollectionIntentTest extends IntentTest {
49 final ConnectPoint egress = NetTestTools.connectPoint("egress", 3); 51 final ConnectPoint egress = NetTestTools.connectPoint("egress", 3);
50 final TrafficSelector selector = new IntentTestsMocks.MockSelector(); 52 final TrafficSelector selector = new IntentTestsMocks.MockSelector();
51 final IntentTestsMocks.MockTreatment treatment = new IntentTestsMocks.MockTreatment(); 53 final IntentTestsMocks.MockTreatment treatment = new IntentTestsMocks.MockTreatment();
54 + final FilteredConnectPoint filteredIngress = new FilteredConnectPoint(ingress);
55 + final FilteredConnectPoint filteredEgress = new FilteredConnectPoint(egress);
52 56
53 /** 57 /**
54 * Checks that the LinkCollectionIntent class is immutable. 58 * Checks that the LinkCollectionIntent class is immutable.
...@@ -179,6 +183,39 @@ public class LinkCollectionIntentTest extends IntentTest { ...@@ -179,6 +183,39 @@ public class LinkCollectionIntentTest extends IntentTest {
179 assertThat(createdConstraints, hasSize(0)); 183 assertThat(createdConstraints, hasSize(0));
180 } 184 }
181 185
186 + /**
187 + * Test filtered connection point for LinkCollection intent.
188 + */
189 + @Test
190 + public void testFilteredConnectedPoint() {
191 + LinkCollectionIntent intent = createFilteredOne();
192 + Set<Link> links = Sets.newHashSet();
193 + links.add(link("A", 1, "B", 1));
194 + links.add(link("A", 2, "C", 1));
195 +
196 + assertThat(intent.appId(), is(APP_ID));
197 + assertThat(intent.treatment(), is(treatment));
198 + assertThat(intent.links(), is(links));
199 + assertThat(intent.applyTreatmentOnEgress(), is(false));
200 + assertThat(intent.filteredIngressPoints(), is(ImmutableSet.of(filteredIngress)));
201 + assertThat(intent.filteredEgressPoints(), is(ImmutableSet.of(filteredEgress)));
202 +
203 + intent = createAnotherFiltered();
204 + links = Sets.newHashSet();
205 + links.add(link("A", 1, "B", 1));
206 + links.add(link("A", 2, "C", 1));
207 + links.add(link("B", 2, "D", 1));
208 + links.add(link("B", 3, "E", 1));
209 +
210 + assertThat(intent.appId(), is(APP_ID));
211 + assertThat(intent.treatment(), is(treatment));
212 + assertThat(intent.links(), is(links));
213 + assertThat(intent.applyTreatmentOnEgress(), is(true));
214 + assertThat(intent.filteredIngressPoints(), is(ImmutableSet.of(filteredIngress)));
215 + assertThat(intent.filteredEgressPoints(), is(ImmutableSet.of(filteredEgress)));
216 +
217 + }
218 +
182 @Override 219 @Override
183 protected Intent createOne() { 220 protected Intent createOne() {
184 HashSet<Link> links1 = new HashSet<>(); 221 HashSet<Link> links1 = new HashSet<>();
...@@ -206,4 +243,33 @@ public class LinkCollectionIntentTest extends IntentTest { ...@@ -206,4 +243,33 @@ public class LinkCollectionIntentTest extends IntentTest {
206 .egressPoints(ImmutableSet.of(egress)) 243 .egressPoints(ImmutableSet.of(egress))
207 .build(); 244 .build();
208 } 245 }
246 +
247 + protected LinkCollectionIntent createFilteredOne() {
248 + Set<Link> links = Sets.newHashSet();
249 + links.add(link("A", 1, "B", 1));
250 + links.add(link("A", 2, "C", 1));
251 + return LinkCollectionIntent.builder()
252 + .appId(APP_ID)
253 + .treatment(treatment)
254 + .links(links)
255 + .filteredIngressPoints(ImmutableSet.of(filteredIngress))
256 + .filteredEgressPoints(ImmutableSet.of(filteredEgress))
257 + .build();
258 + }
259 +
260 + protected LinkCollectionIntent createAnotherFiltered() {
261 + Set<Link> links = Sets.newHashSet();
262 + links.add(link("A", 1, "B", 1));
263 + links.add(link("A", 2, "C", 1));
264 + links.add(link("B", 2, "D", 1));
265 + links.add(link("B", 3, "E", 1));
266 + return LinkCollectionIntent.builder()
267 + .appId(APP_ID)
268 + .treatment(treatment)
269 + .links(links)
270 + .applyTreatmentOnEgress(true)
271 + .filteredIngressPoints(ImmutableSet.of(filteredIngress))
272 + .filteredEgressPoints(ImmutableSet.of(filteredEgress))
273 + .build();
274 + }
209 } 275 }
......
...@@ -16,9 +16,7 @@ ...@@ -16,9 +16,7 @@
16 16
17 package org.onosproject.net.intent; 17 package org.onosproject.net.intent;
18 18
19 -import org.junit.Rule;
20 import org.junit.Test; 19 import org.junit.Test;
21 -import org.junit.rules.ExpectedException;
22 20
23 import static org.junit.Assert.assertEquals; 21 import static org.junit.Assert.assertEquals;
24 import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; 22 import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
...@@ -36,6 +34,9 @@ public class MultiPointToSinglePointIntentTest extends ConnectivityIntentTest { ...@@ -36,6 +34,9 @@ public class MultiPointToSinglePointIntentTest extends ConnectivityIntentTest {
36 assertThatClassIsImmutable(MultiPointToSinglePointIntent.class); 34 assertThatClassIsImmutable(MultiPointToSinglePointIntent.class);
37 } 35 }
38 36
37 + /**
38 + * Create three intents with normal connect points.
39 + */
39 @Test 40 @Test
40 public void basics() { 41 public void basics() {
41 MultiPointToSinglePointIntent intent = createOne(); 42 MultiPointToSinglePointIntent intent = createOne();
...@@ -43,40 +44,38 @@ public class MultiPointToSinglePointIntentTest extends ConnectivityIntentTest { ...@@ -43,40 +44,38 @@ public class MultiPointToSinglePointIntentTest extends ConnectivityIntentTest {
43 assertEquals("incorrect match", MATCH, intent.selector()); 44 assertEquals("incorrect match", MATCH, intent.selector());
44 assertEquals("incorrect ingress", PS1, intent.ingressPoints()); 45 assertEquals("incorrect ingress", PS1, intent.ingressPoints());
45 assertEquals("incorrect egress", P2, intent.egressPoint()); 46 assertEquals("incorrect egress", P2, intent.egressPoint());
46 - }
47 -
48 - @Rule
49 - public ExpectedException wrongMultiple = ExpectedException.none();
50 47
51 - @Test 48 + intent = createAnother();
52 - public void multipleSelectors() {
53 -
54 - MultiPointToSinglePointIntent intent = createFirstMultiple();
55 assertEquals("incorrect id", APPID, intent.appId()); 49 assertEquals("incorrect id", APPID, intent.appId());
56 assertEquals("incorrect match", MATCH, intent.selector()); 50 assertEquals("incorrect match", MATCH, intent.selector());
57 - assertEquals("incorrect ingress", PS1, intent.ingressPoints()); 51 + assertEquals("incorrect ingress", PS2, intent.ingressPoints());
58 - assertEquals("incorrect egress", P2, intent.egressPoint()); 52 + assertEquals("incorrect egress", P1, intent.egressPoint());
59 - assertEquals("incorrect selectors", MATCHES, intent.ingressSelectors());
60 53
61 - intent = createSecondMultiple(); 54 + intent = createVlanMatch();
62 assertEquals("incorrect id", APPID, intent.appId()); 55 assertEquals("incorrect id", APPID, intent.appId());
63 assertEquals("incorrect match", VLANMATCH1, intent.selector()); 56 assertEquals("incorrect match", VLANMATCH1, intent.selector());
64 assertEquals("incorrect ingress", PS1, intent.ingressPoints()); 57 assertEquals("incorrect ingress", PS1, intent.ingressPoints());
65 assertEquals("incorrect egress", P2, intent.egressPoint()); 58 assertEquals("incorrect egress", P2, intent.egressPoint());
66 - assertEquals("incorrect selectors", MATCHES, intent.ingressSelectors()); 59 + }
67 60
68 - intent = createThirdMultiple(); 61 + /**
62 + * Create two intents with filtered connect points.
63 + */
64 + @Test
65 + public void filteredIntent() {
66 + MultiPointToSinglePointIntent intent = createFilteredOne();
69 assertEquals("incorrect id", APPID, intent.appId()); 67 assertEquals("incorrect id", APPID, intent.appId());
70 assertEquals("incorrect match", MATCH, intent.selector()); 68 assertEquals("incorrect match", MATCH, intent.selector());
71 - assertEquals("incorrect ingress", PS1, intent.ingressPoints()); 69 + assertEquals("incorrect filtered ingress", FPS1, intent.filteredIngressPoints());
72 - assertEquals("incorrect egress", P2, intent.egressPoint()); 70 + assertEquals("incorrect filtered egress", FP2, intent.filteredEgressPoint());
73 - assertEquals("incorrect selectors", VLANMATCHES, intent.ingressSelectors());
74 71
75 - wrongMultiple.expect(IllegalArgumentException.class); 72 + intent = createAnotherFiltered();
76 - wrongMultiple.expectMessage("Selector and Multiple Selectors are both set"); 73 + assertEquals("incorrect id", APPID, intent.appId());
77 - intent = createWrongMultiple(); 74 + assertEquals("incorrect match", MATCH, intent.selector());
78 - } 75 + assertEquals("incorrect filtered ingress", FPS2, intent.filteredIngressPoints());
76 + assertEquals("incorrect filtered egress", FP1, intent.filteredEgressPoint());
79 77
78 + }
80 79
81 @Override 80 @Override
82 protected MultiPointToSinglePointIntent createOne() { 81 protected MultiPointToSinglePointIntent createOne() {
...@@ -100,47 +99,42 @@ public class MultiPointToSinglePointIntentTest extends ConnectivityIntentTest { ...@@ -100,47 +99,42 @@ public class MultiPointToSinglePointIntentTest extends ConnectivityIntentTest {
100 .build(); 99 .build();
101 } 100 }
102 101
103 - protected MultiPointToSinglePointIntent createFirstMultiple() { 102 + protected MultiPointToSinglePointIntent createVlanMatch() {
104 return MultiPointToSinglePointIntent.builder() 103 return MultiPointToSinglePointIntent.builder()
105 .appId(APPID) 104 .appId(APPID)
106 - .selector(MATCH) 105 + .selector(VLANMATCH1)
107 .treatment(NOP) 106 .treatment(NOP)
108 .ingressPoints(PS1) 107 .ingressPoints(PS1)
109 .egressPoint(P2) 108 .egressPoint(P2)
110 - .selectors(MATCHES)
111 .build(); 109 .build();
112 } 110 }
113 111
114 - protected MultiPointToSinglePointIntent createSecondMultiple() { 112 +
113 + protected MultiPointToSinglePointIntent createFilteredOne() {
115 return MultiPointToSinglePointIntent.builder() 114 return MultiPointToSinglePointIntent.builder()
116 .appId(APPID) 115 .appId(APPID)
117 - .selector(VLANMATCH1)
118 .treatment(NOP) 116 .treatment(NOP)
119 - .ingressPoints(PS1) 117 + .filteredIngressPoints(FPS1)
120 - .egressPoint(P2) 118 + .filteredEgressPoint(FP2)
121 - .selectors(MATCHES)
122 .build(); 119 .build();
123 } 120 }
124 121
125 - protected MultiPointToSinglePointIntent createThirdMultiple() { 122 + protected MultiPointToSinglePointIntent createAnotherFiltered() {
126 return MultiPointToSinglePointIntent.builder() 123 return MultiPointToSinglePointIntent.builder()
127 .appId(APPID) 124 .appId(APPID)
128 - .selector(MATCH)
129 .treatment(NOP) 125 .treatment(NOP)
130 - .ingressPoints(PS1) 126 + .filteredIngressPoints(FPS2)
131 - .egressPoint(P2) 127 + .filteredEgressPoint(FP1)
132 - .selectors(VLANMATCHES)
133 .build(); 128 .build();
134 } 129 }
135 130
136 - protected MultiPointToSinglePointIntent createWrongMultiple() { 131 + protected MultiPointToSinglePointIntent createWrongIntent() {
137 return MultiPointToSinglePointIntent.builder() 132 return MultiPointToSinglePointIntent.builder()
138 .appId(APPID) 133 .appId(APPID)
139 .selector(VLANMATCH1) 134 .selector(VLANMATCH1)
140 .treatment(NOP) 135 .treatment(NOP)
141 - .ingressPoints(PS1) 136 + .filteredIngressPoints(FPS1)
142 - .egressPoint(P2) 137 + .filteredEgressPoint(FP2)
143 - .selectors(VLANMATCHES)
144 .build(); 138 .build();
145 } 139 }
146 140
......
...@@ -15,9 +15,7 @@ ...@@ -15,9 +15,7 @@
15 */ 15 */
16 package org.onosproject.net.intent; 16 package org.onosproject.net.intent;
17 17
18 -import org.junit.Rule;
19 import org.junit.Test; 18 import org.junit.Test;
20 -import org.junit.rules.ExpectedException;
21 19
22 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertEquals;
23 import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; 21 import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
...@@ -42,41 +40,28 @@ public class SinglePointToMultiPointIntentTest extends ConnectivityIntentTest { ...@@ -42,41 +40,28 @@ public class SinglePointToMultiPointIntentTest extends ConnectivityIntentTest {
42 assertEquals("incorrect match", MATCH, intent.selector()); 40 assertEquals("incorrect match", MATCH, intent.selector());
43 assertEquals("incorrect ingress", P1, intent.ingressPoint()); 41 assertEquals("incorrect ingress", P1, intent.ingressPoint());
44 assertEquals("incorrect egress", PS2, intent.egressPoints()); 42 assertEquals("incorrect egress", PS2, intent.egressPoints());
45 - }
46 -
47 - @Rule
48 - public ExpectedException wrongMultiple = ExpectedException.none();
49 -
50 - @Test
51 - public void multipleTreatments() {
52 43
53 - SinglePointToMultiPointIntent intent = createFirstMultiple(); 44 + intent = createAnother();
54 assertEquals("incorrect id", APPID, intent.appId()); 45 assertEquals("incorrect id", APPID, intent.appId());
55 assertEquals("incorrect match", MATCH, intent.selector()); 46 assertEquals("incorrect match", MATCH, intent.selector());
56 - assertEquals("incorrect ingress", P1, intent.ingressPoint()); 47 + assertEquals("incorrect ingress", P2, intent.ingressPoint());
57 - assertEquals("incorrect egress", PS2, intent.egressPoints()); 48 + assertEquals("incorrect egress", PS1, intent.egressPoints());
58 - assertEquals("incorrect treatment", NOP, intent.treatment()); 49 + }
59 - assertEquals("incorrect treatments", TREATMENTS, intent.egressTreatments());
60 50
61 - intent = createSecondMultiple(); 51 + @Test
52 + public void filteredIntent() {
53 + SinglePointToMultiPointIntent intent = createFilteredOne();
62 assertEquals("incorrect id", APPID, intent.appId()); 54 assertEquals("incorrect id", APPID, intent.appId());
63 assertEquals("incorrect match", MATCH, intent.selector()); 55 assertEquals("incorrect match", MATCH, intent.selector());
64 - assertEquals("incorrect ingress", P1, intent.ingressPoint()); 56 + assertEquals("incorrect filtered ingress", FP2, intent.filteredIngressPoint());
65 - assertEquals("incorrect egress", PS2, intent.egressPoints()); 57 + assertEquals("incorrect filtered egress", FPS1, intent.filteredEgressPoints());
66 - assertEquals("incorrect treatment", VLANACTION1, intent.treatment());
67 - assertEquals("incorrect selectors", TREATMENTS, intent.egressTreatments());
68 58
69 - intent = createThirdMultiple(); 59 + intent = createAnotherFiltered();
70 assertEquals("incorrect id", APPID, intent.appId()); 60 assertEquals("incorrect id", APPID, intent.appId());
71 assertEquals("incorrect match", MATCH, intent.selector()); 61 assertEquals("incorrect match", MATCH, intent.selector());
72 - assertEquals("incorrect ingress", P1, intent.ingressPoint()); 62 + assertEquals("incorrect filtered ingress", FP1, intent.filteredIngressPoint());
73 - assertEquals("incorrect egress", PS2, intent.egressPoints()); 63 + assertEquals("incorrect filtered egress", FPS2, intent.filteredEgressPoints());
74 - assertEquals("incorrect treatment", NOP, intent.treatment());
75 - assertEquals("incorrect selectors", VLANACTIONS, intent.egressTreatments());
76 64
77 - wrongMultiple.expect(IllegalArgumentException.class);
78 - wrongMultiple.expectMessage("Treatment and Multiple Treatments are both set");
79 - intent = createWrongMultiple();
80 } 65 }
81 66
82 @Override 67 @Override
...@@ -101,48 +86,31 @@ public class SinglePointToMultiPointIntentTest extends ConnectivityIntentTest { ...@@ -101,48 +86,31 @@ public class SinglePointToMultiPointIntentTest extends ConnectivityIntentTest {
101 .build(); 86 .build();
102 } 87 }
103 88
104 - 89 + protected SinglePointToMultiPointIntent createFilteredOne() {
105 - protected SinglePointToMultiPointIntent createFirstMultiple() {
106 return SinglePointToMultiPointIntent.builder() 90 return SinglePointToMultiPointIntent.builder()
107 .appId(APPID) 91 .appId(APPID)
108 - .selector(MATCH)
109 .treatment(NOP) 92 .treatment(NOP)
110 - .ingressPoint(P1) 93 + .filteredEgressPoints(FPS1)
111 - .egressPoints(PS2) 94 + .filteredIngressPoint(FP2)
112 - .treatments(TREATMENTS)
113 .build(); 95 .build();
114 } 96 }
115 97
116 - protected SinglePointToMultiPointIntent createSecondMultiple() { 98 + protected SinglePointToMultiPointIntent createAnotherFiltered() {
117 return SinglePointToMultiPointIntent.builder() 99 return SinglePointToMultiPointIntent.builder()
118 .appId(APPID) 100 .appId(APPID)
119 - .selector(MATCH)
120 - .treatment(VLANACTION1)
121 - .ingressPoint(P1)
122 - .egressPoints(PS2)
123 - .treatments(TREATMENTS)
124 - .build();
125 - }
126 -
127 - protected SinglePointToMultiPointIntent createThirdMultiple() {
128 - return SinglePointToMultiPointIntent.builder()
129 - .appId(APPID)
130 - .selector(MATCH)
131 .treatment(NOP) 101 .treatment(NOP)
132 - .ingressPoint(P1) 102 + .filteredEgressPoints(FPS2)
133 - .egressPoints(PS2) 103 + .filteredIngressPoint(FP1)
134 - .treatments(VLANACTIONS)
135 .build(); 104 .build();
136 } 105 }
137 106
138 - protected SinglePointToMultiPointIntent createWrongMultiple() { 107 + protected SinglePointToMultiPointIntent createWrongIntent() {
139 return SinglePointToMultiPointIntent.builder() 108 return SinglePointToMultiPointIntent.builder()
140 .appId(APPID) 109 .appId(APPID)
141 - .selector(MATCH) 110 + .treatment(NOP)
142 - .treatment(VLANACTION1) 111 + .selector(VLANMATCH1)
143 - .ingressPoint(P1) 112 + .filteredEgressPoints(FPS2)
144 - .egressPoints(PS2) 113 + .filteredIngressPoint(FP1)
145 - .treatments(VLANACTIONS)
146 .build(); 114 .build();
147 } 115 }
148 116
......
...@@ -17,32 +17,39 @@ ...@@ -17,32 +17,39 @@
17 package org.onosproject.net.intent.impl.compiler; 17 package org.onosproject.net.intent.impl.compiler;
18 18
19 import com.google.common.collect.SetMultimap; 19 import com.google.common.collect.SetMultimap;
20 +import com.google.common.collect.Sets;
20 import org.onlab.packet.Ip4Address; 21 import org.onlab.packet.Ip4Address;
21 import org.onlab.packet.IpPrefix; 22 import org.onlab.packet.IpPrefix;
22 import org.onosproject.net.ConnectPoint; 23 import org.onosproject.net.ConnectPoint;
23 import org.onosproject.net.DeviceId; 24 import org.onosproject.net.DeviceId;
24 import org.onosproject.net.Link; 25 import org.onosproject.net.Link;
25 import org.onosproject.net.PortNumber; 26 import org.onosproject.net.PortNumber;
27 +import org.onosproject.net.FilteredConnectPoint;
26 import org.onosproject.net.flow.DefaultTrafficSelector; 28 import org.onosproject.net.flow.DefaultTrafficSelector;
27 import org.onosproject.net.flow.DefaultTrafficTreatment; 29 import org.onosproject.net.flow.DefaultTrafficTreatment;
28 import org.onosproject.net.flow.TrafficSelector; 30 import org.onosproject.net.flow.TrafficSelector;
29 import org.onosproject.net.flow.TrafficTreatment; 31 import org.onosproject.net.flow.TrafficTreatment;
32 +import org.onosproject.net.flow.criteria.Criteria;
33 +import org.onosproject.net.flow.criteria.Criterion;
34 +import org.onosproject.net.flow.criteria.MplsCriterion;
35 +import org.onosproject.net.flow.criteria.TunnelIdCriterion;
36 +import org.onosproject.net.flow.criteria.VlanIdCriterion;
30 import org.onosproject.net.flow.instructions.Instruction; 37 import org.onosproject.net.flow.instructions.Instruction;
31 import org.onosproject.net.flow.instructions.L0ModificationInstruction; 38 import org.onosproject.net.flow.instructions.L0ModificationInstruction;
32 import org.onosproject.net.flow.instructions.L1ModificationInstruction; 39 import org.onosproject.net.flow.instructions.L1ModificationInstruction;
33 import org.onosproject.net.flow.instructions.L2ModificationInstruction; 40 import org.onosproject.net.flow.instructions.L2ModificationInstruction;
34 import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction; 41 import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
35 -import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsBosInstruction;
36 -import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsLabelInstruction;
37 -import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModTunnelIdInstruction;
38 import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction; 42 import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
39 import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction; 43 import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
44 +import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsLabelInstruction;
45 +import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsBosInstruction;
46 +import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModTunnelIdInstruction;
40 import org.onosproject.net.flow.instructions.L3ModificationInstruction; 47 import org.onosproject.net.flow.instructions.L3ModificationInstruction;
41 -import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpEthInstruction;
42 -import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpIPInstruction;
43 -import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpOpInstruction;
44 import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction; 48 import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
45 import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPv6FlowLabelInstruction; 49 import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPv6FlowLabelInstruction;
50 +import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpIPInstruction;
51 +import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpEthInstruction;
52 +import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpOpInstruction;
46 import org.onosproject.net.flow.instructions.L4ModificationInstruction; 53 import org.onosproject.net.flow.instructions.L4ModificationInstruction;
47 import org.onosproject.net.flow.instructions.L4ModificationInstruction.ModTransportPortInstruction; 54 import org.onosproject.net.flow.instructions.L4ModificationInstruction.ModTransportPortInstruction;
48 import org.onosproject.net.intent.IntentCompilationException; 55 import org.onosproject.net.intent.IntentCompilationException;
...@@ -53,11 +60,19 @@ import java.util.Optional; ...@@ -53,11 +60,19 @@ import java.util.Optional;
53 import java.util.Set; 60 import java.util.Set;
54 import java.util.stream.Collectors; 61 import java.util.stream.Collectors;
55 62
63 +import static org.onosproject.net.flow.criteria.Criterion.Type.MPLS_LABEL;
64 +import static org.onosproject.net.flow.criteria.Criterion.Type.TUNNEL_ID;
65 +import static org.onosproject.net.flow.criteria.Criterion.Type.VLAN_VID;
66 +
67 +
56 /** 68 /**
57 * Shared APIs and implementations for Link Collection compilers. 69 * Shared APIs and implementations for Link Collection compilers.
58 */ 70 */
59 public class LinkCollectionCompiler<T> { 71 public class LinkCollectionCompiler<T> {
60 72
73 + private static final Set<Criterion.Type> TAG_CRITERION_TYPES =
74 + Sets.immutableEnumSet(VLAN_VID, MPLS_LABEL, TUNNEL_ID);
75 +
61 /** 76 /**
62 * Helper class to encapsulate treatment and selector. 77 * Helper class to encapsulate treatment and selector.
63 */ 78 */
...@@ -107,13 +122,13 @@ public class LinkCollectionCompiler<T> { ...@@ -107,13 +122,13 @@ public class LinkCollectionCompiler<T> {
107 for (ConnectPoint egressPoint : intent.egressPoints()) { 122 for (ConnectPoint egressPoint : intent.egressPoints()) {
108 outputPorts.put(egressPoint.deviceId(), egressPoint.port()); 123 outputPorts.put(egressPoint.deviceId(), egressPoint.port());
109 } 124 }
110 -
111 } 125 }
112 126
113 /** 127 /**
114 - * Helper method to compute ingress and egress ports. 128 + * Gets ingress and egress port number of specific device.
115 * 129 *
116 - * @param intent the related intents 130 + * @param intent the related
131 + * @param deviceId device Id
117 * @param ingressPorts the ingress ports to compute 132 * @param ingressPorts the ingress ports to compute
118 * @param egressPorts the egress ports to compute 133 * @param egressPorts the egress ports to compute
119 */ 134 */
...@@ -156,11 +171,11 @@ public class LinkCollectionCompiler<T> { ...@@ -156,11 +171,11 @@ public class LinkCollectionCompiler<T> {
156 * in the flow representation (Rule, Objective). 171 * in the flow representation (Rule, Objective).
157 * 172 *
158 * @param intent the intent to compile 173 * @param intent the intent to compile
159 - * @param inPort the input port 174 + * @param inPort the input port of this device
160 * @param deviceId the current device 175 * @param deviceId the current device
161 - * @param outPorts the output ports 176 + * @param outPorts the output ports of this device
162 - * @param ingressPorts the ingress ports 177 + * @param ingressPorts intent ingress ports of this device
163 - * @param egressPorts the egress ports 178 + * @param egressPorts intent egress ports of this device
164 * @return the forwarding instruction object which encapsulates treatment and selector 179 * @return the forwarding instruction object which encapsulates treatment and selector
165 */ 180 */
166 protected ForwardingInstructions createForwardingInstructions(LinkCollectionIntent intent, 181 protected ForwardingInstructions createForwardingInstructions(LinkCollectionIntent intent,
...@@ -170,119 +185,214 @@ public class LinkCollectionCompiler<T> { ...@@ -170,119 +185,214 @@ public class LinkCollectionCompiler<T> {
170 Set<PortNumber> ingressPorts, 185 Set<PortNumber> ingressPorts,
171 Set<PortNumber> egressPorts) { 186 Set<PortNumber> egressPorts) {
172 187
173 - TrafficTreatment.Builder defaultTreatmentBuilder = DefaultTrafficTreatment.builder(); 188 + TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
174 - outPorts.forEach(defaultTreatmentBuilder::setOutput); 189 + TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder(intent.selector());
175 - TrafficTreatment outputOnlyTreatment = defaultTreatmentBuilder.build(); 190 + selectorBuilder.matchInPort(inPort);
176 - TrafficSelector.Builder selectorBuilder;
177 - TrafficTreatment treatment;
178 - TrafficTreatment intentTreatment;
179 191
180 if (!intent.applyTreatmentOnEgress()) { 192 if (!intent.applyTreatmentOnEgress()) {
181 - TrafficTreatment.Builder ingressTreatmentBuilder = DefaultTrafficTreatment.builder(intent.treatment()); 193 + // FIXME: currently, we assume this intent is compile from mp2sp intent
182 - outPorts.forEach(ingressTreatmentBuilder::setOutput); 194 + Optional<FilteredConnectPoint> filteredIngressPoint =
183 - intentTreatment = ingressTreatmentBuilder.build(); 195 + getFilteredConnectPointFromIntent(deviceId, inPort, intent);
184 - 196 + Optional<FilteredConnectPoint> filteredEgressPoint =
185 - if (ingressPorts.contains(inPort)) { 197 + intent.filteredEgressPoints().stream().findFirst();
186 - if (intent.ingressSelectors() != null && !intent.ingressSelectors().isEmpty()) { 198 +
187 - /** 199 + if (filteredIngressPoint.isPresent()) {
188 - * We iterate on the ingress points looking for the connect point 200 + // Ingress device
189 - * associated to inPort. 201 + intent.treatment().allInstructions().stream()
190 - */ 202 + .filter(inst -> inst.type() != Instruction.Type.NOACTION)
191 - Optional<ConnectPoint> connectPoint = intent.ingressPoints() 203 + .forEach(treatmentBuilder::add);
192 - .stream() 204 +
193 - .filter(ingressPoint -> ingressPoint.port().equals(inPort) 205 + if (filteredEgressPoint.isPresent()) {
194 - && ingressPoint.deviceId().equals(deviceId)) 206 + // Apply selector from ingress point
195 - .findFirst(); 207 + filteredIngressPoint.get()
196 - if (connectPoint.isPresent()) { 208 + .trafficSelector()
197 - selectorBuilder = DefaultTrafficSelector 209 + .criteria()
198 - .builder(intent.ingressSelectors().get(connectPoint.get())); 210 + .forEach(selectorBuilder::add);
211 +
212 + TrafficTreatment forwardingTreatment =
213 + forwardingTreatment(filteredIngressPoint.get(),
214 + filteredEgressPoint.get());
215 +
216 + forwardingTreatment.allInstructions().stream()
217 + .filter(inst -> inst.type() != Instruction.Type.NOACTION)
218 + .forEach(treatmentBuilder::add);
199 } else { 219 } else {
200 - throw new IntentCompilationException("Looking for connect point associated to the selector." + 220 + throw new IntentCompilationException("Can't find filtered connection point");
201 - "inPort not in IngressPoints");
202 } 221 }
222 +
203 } else { 223 } else {
204 - selectorBuilder = DefaultTrafficSelector.builder(intent.selector()); 224 + // Not ingress device, won't apply treatments.
225 + // Use selector by treatment from intent.
226 + updateBuilder(selectorBuilder, intent.treatment());
227 +
228 + // Selector should be overridden by selector from connect point.
229 + if (filteredEgressPoint.isPresent()) {
230 + filteredEgressPoint.get()
231 + .trafficSelector()
232 + .criteria()
233 + .forEach(selectorBuilder::add);
205 } 234 }
206 - treatment = this.updateBuilder(ingressTreatmentBuilder, selectorBuilder.build()).build(); 235 +
207 - } else {
208 - selectorBuilder = this.createSelectorFromFwdInstructions(
209 - new ForwardingInstructions(intentTreatment, intent.selector())
210 - );
211 - treatment = outputOnlyTreatment;
212 } 236 }
237 +
238 + outPorts.forEach(treatmentBuilder::setOutput);
239 +
213 } else { 240 } else {
214 - if (outPorts.stream().allMatch(egressPorts::contains)) { 241 + // FIXME: currently, we assume this intent is compile from sp2mp intent
215 - TrafficTreatment.Builder egressTreatmentBuilder = DefaultTrafficTreatment.builder(); 242 + Optional<FilteredConnectPoint> filteredIngressPoint =
216 - if (intent.egressTreatments() != null && !intent.egressTreatments().isEmpty()) { 243 + intent.filteredIngressPoints().stream().findFirst();
217 - for (PortNumber outPort : outPorts) { 244 +
218 - Optional<ConnectPoint> connectPoint = intent.egressPoints() 245 + if (filteredIngressPoint.isPresent()) {
219 - .stream() 246 + // Apply selector from ingress point
220 - .filter(egressPoint -> egressPoint.port().equals(outPort) 247 + filteredIngressPoint.get()
221 - && egressPoint.deviceId().equals(deviceId)) 248 + .trafficSelector()
222 - .findFirst(); 249 + .criteria()
223 - if (connectPoint.isPresent()) { 250 + .forEach(selectorBuilder::add);
224 - TrafficTreatment egressTreatment = intent.egressTreatments().get(connectPoint.get());
225 - this.addTreatment(egressTreatmentBuilder, egressTreatment);
226 - egressTreatmentBuilder = this.updateBuilder(egressTreatmentBuilder, intent.selector());
227 - egressTreatmentBuilder.setOutput(outPort);
228 } else { 251 } else {
229 - throw new IntentCompilationException("Looking for connect point associated to " + 252 + throw new IntentCompilationException(
230 - "the treatment. outPort not in egressPoints"); 253 + "Filtered connection point for ingress" +
254 + "point does not exist");
231 } 255 }
256 +
257 + for (PortNumber outPort : outPorts) {
258 + Optional<FilteredConnectPoint> filteredEgressPoint =
259 + getFilteredConnectPointFromIntent(deviceId, outPort, intent);
260 +
261 + if (filteredEgressPoint.isPresent()) {
262 + // Egress port, apply treatment + forwarding treatment
263 + intent.treatment().allInstructions().stream()
264 + .filter(inst -> inst.type() != Instruction.Type.NOACTION)
265 + .forEach(treatmentBuilder::add);
266 +
267 + TrafficTreatment forwardingTreatment =
268 + forwardingTreatment(filteredIngressPoint.get(),
269 + filteredEgressPoint.get());
270 + forwardingTreatment.allInstructions().stream()
271 + .filter(inst -> inst.type() != Instruction.Type.NOACTION)
272 + .forEach(treatmentBuilder::add);
232 } 273 }
233 - } else { 274 +
234 - egressTreatmentBuilder = this 275 + treatmentBuilder.setOutput(outPort);
235 - .updateBuilder(DefaultTrafficTreatment.builder(intent.treatment()), intent.selector()); 276 +
236 - outPorts.forEach(egressTreatmentBuilder::setOutput);
237 - }
238 - selectorBuilder = DefaultTrafficSelector.builder(intent.selector());
239 - treatment = egressTreatmentBuilder.build();
240 - } else {
241 - selectorBuilder = DefaultTrafficSelector.builder(intent.selector());
242 - treatment = outputOnlyTreatment;
243 } 277 }
278 +
244 } 279 }
245 280
246 - TrafficSelector selector = selectorBuilder.matchInPort(inPort).build();
247 281
248 - return new ForwardingInstructions(treatment, selector); 282 + return new ForwardingInstructions(treatmentBuilder.build(), selectorBuilder.build());
249 283
250 } 284 }
251 285
252 /** 286 /**
253 - * Update a builder using a treatment. 287 + * Get FilteredConnectPoint from LinkCollectionIntent.
254 - * @param builder the builder to update 288 + * @param deviceId device Id for connect point
255 - * @param treatment the treatment to add 289 + * @param portNumber port number
256 - * @return the new builder 290 + * @param intent source intent
291 + * @return filtered connetion point
257 */ 292 */
258 - private TrafficTreatment.Builder addTreatment(TrafficTreatment.Builder builder, TrafficTreatment treatment) { 293 + private Optional<FilteredConnectPoint> getFilteredConnectPointFromIntent(DeviceId deviceId,
259 - builder.deferred(); 294 + PortNumber portNumber,
260 - for (Instruction instruction : treatment.deferred()) { 295 + LinkCollectionIntent intent) {
261 - builder.add(instruction); 296 + Set<FilteredConnectPoint> filteredConnectPoints =
262 - } 297 + Sets.union(intent.filteredIngressPoints(), intent.filteredEgressPoints());
263 - builder.immediate(); 298 + return filteredConnectPoints.stream()
264 - for (Instruction instruction : treatment.immediate()) { 299 + .filter(port -> port.connectPoint().deviceId().equals(deviceId))
265 - builder.add(instruction); 300 + .filter(port -> port.connectPoint().port().equals(portNumber))
301 + .findFirst();
266 } 302 }
267 - return builder; 303 +
304 + /**
305 + * Get tag criterion from selector.
306 + * The criterion should be one of type in tagCriterionTypes.
307 + *
308 + * @param selector selector
309 + * @return Criterion that matched, if there is no tag criterion, return null
310 + */
311 + private Criterion getTagCriterion(TrafficSelector selector) {
312 + return selector.criteria().stream()
313 + .filter(criterion -> TAG_CRITERION_TYPES.contains(criterion.type()))
314 + .findFirst()
315 + .orElse(Criteria.dummy());
316 +
268 } 317 }
269 318
270 /** 319 /**
271 - * Update the original builder with the necessary operations 320 + * Compares tag type between ingress and egress point and generate
272 - * to have a correct forwarding given an ingress selector. 321 + * treatment for egress point of intent.
273 - * TODO
274 - * This means that if the ingress selectors match on different vlanids and
275 - * the egress treatment rewrite the vlanid the forwarding works
276 - * but if we need to push for example an mpls label at the egress
277 - * we need to implement properly this method.
278 * 322 *
279 - * @param treatmentBuilder the builder to modify 323 + * @param ingress ingress point for the intent
280 - * @param intentSelector the intent selector to use as input 324 + * @param egress egress point for the intent
281 - * @return the new treatment created 325 + * @return Builder of TrafficTreatment
326 + */
327 + private TrafficTreatment forwardingTreatment(FilteredConnectPoint ingress,
328 + FilteredConnectPoint egress) {
329 +
330 +
331 + if (ingress.trafficSelector().equals(egress.trafficSelector())) {
332 + return DefaultTrafficTreatment.emptyTreatment();
333 + }
334 +
335 + TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder();
336 +
337 + /*
338 + * "null" means there is no tag for the port
339 + * Tag criterion will be null if port is normal connection point
340 + */
341 + Criterion ingressTagCriterion = getTagCriterion(ingress.trafficSelector());
342 + Criterion egressTagCriterion = getTagCriterion(egress.trafficSelector());
343 +
344 + if (ingressTagCriterion.type() != egressTagCriterion.type()) {
345 +
346 + /*
347 + * Tag type of ingress port and egress port are different.
348 + * Need to remove tag from ingress, then add new tag for egress.
349 + * Remove nothing if ingress port use VXLAN or there is no tag
350 + * on ingress port.
351 + */
352 + switch (ingressTagCriterion.type()) {
353 + case VLAN_VID:
354 + builder.popVlan();
355 + break;
356 + case MPLS_LABEL:
357 + builder.popMpls();
358 + break;
359 + default:
360 + break;
361 + }
362 +
363 + /*
364 + * Push new tag for egress port.
282 */ 365 */
283 - private TrafficTreatment.Builder updateBuilder(TrafficTreatment.Builder treatmentBuilder, 366 + switch (egressTagCriterion.type()) {
284 - TrafficSelector intentSelector) { 367 + case VLAN_VID:
285 - return treatmentBuilder; 368 + builder.pushVlan();
369 + break;
370 + case MPLS_LABEL:
371 + builder.pushMpls();
372 + break;
373 + default:
374 + break;
375 + }
376 + }
377 +
378 + switch (egressTagCriterion.type()) {
379 + case VLAN_VID:
380 + VlanIdCriterion vlanIdCriterion = (VlanIdCriterion) egressTagCriterion;
381 + builder.setVlanId(vlanIdCriterion.vlanId());
382 + break;
383 + case MPLS_LABEL:
384 + MplsCriterion mplsCriterion = (MplsCriterion) egressTagCriterion;
385 + builder.setMpls(mplsCriterion.label());
386 + break;
387 + case TUNNEL_ID:
388 + TunnelIdCriterion tunnelIdCriterion = (TunnelIdCriterion) egressTagCriterion;
389 + builder.setTunnelId(tunnelIdCriterion.tunnelId());
390 + break;
391 + default:
392 + break;
393 + }
394 +
395 + return builder.build();
286 } 396 }
287 397
288 /** 398 /**
...@@ -467,30 +577,29 @@ public class LinkCollectionCompiler<T> { ...@@ -467,30 +577,29 @@ public class LinkCollectionCompiler<T> {
467 } 577 }
468 578
469 /** 579 /**
470 - * Computes the new traffic selector using the 580 + * Update selector builder by using treatment.
471 - * forwarding instructions.
472 * 581 *
473 - * @param fwInstructions it encapsulates the instructions to compute the new selector 582 + * @param builder builder to update
474 - * @return the traffic selector builder 583 + * @param treatment traffic treatment
475 */ 584 */
476 - private TrafficSelector.Builder createSelectorFromFwdInstructions(ForwardingInstructions fwInstructions) { 585 + private void updateBuilder(TrafficSelector.Builder builder, TrafficTreatment treatment) {
477 - TrafficSelector.Builder defaultSelectorBuilder = DefaultTrafficSelector.builder(fwInstructions.selector()); 586 +
478 - fwInstructions.treatment().allInstructions().forEach(instruction -> { 587 + treatment.allInstructions().forEach(instruction -> {
479 switch (instruction.type()) { 588 switch (instruction.type()) {
480 case L0MODIFICATION: 589 case L0MODIFICATION:
481 - updateBuilder(defaultSelectorBuilder, (L0ModificationInstruction) instruction); 590 + updateBuilder(builder, (L0ModificationInstruction) instruction);
482 break; 591 break;
483 case L1MODIFICATION: 592 case L1MODIFICATION:
484 - updateBuilder(defaultSelectorBuilder, (L1ModificationInstruction) instruction); 593 + updateBuilder(builder, (L1ModificationInstruction) instruction);
485 break; 594 break;
486 case L2MODIFICATION: 595 case L2MODIFICATION:
487 - updateBuilder(defaultSelectorBuilder, (L2ModificationInstruction) instruction); 596 + updateBuilder(builder, (L2ModificationInstruction) instruction);
488 break; 597 break;
489 case L3MODIFICATION: 598 case L3MODIFICATION:
490 - updateBuilder(defaultSelectorBuilder, (L3ModificationInstruction) instruction); 599 + updateBuilder(builder, (L3ModificationInstruction) instruction);
491 break; 600 break;
492 case L4MODIFICATION: 601 case L4MODIFICATION:
493 - updateBuilder(defaultSelectorBuilder, (L4ModificationInstruction) instruction); 602 + updateBuilder(builder, (L4ModificationInstruction) instruction);
494 break; 603 break;
495 case NOACTION: 604 case NOACTION:
496 case OUTPUT: 605 case OUTPUT:
...@@ -506,7 +615,7 @@ public class LinkCollectionCompiler<T> { ...@@ -506,7 +615,7 @@ public class LinkCollectionCompiler<T> {
506 throw new IntentCompilationException("Unknown instruction type"); 615 throw new IntentCompilationException("Unknown instruction type");
507 } 616 }
508 }); 617 });
509 - return defaultSelectorBuilder; 618 +
510 } 619 }
511 620
512 } 621 }
......
...@@ -119,12 +119,10 @@ public class MultiPointToSinglePointIntentCompiler ...@@ -119,12 +119,10 @@ public class MultiPointToSinglePointIntentCompiler
119 119
120 Intent result = LinkCollectionIntent.builder() 120 Intent result = LinkCollectionIntent.builder()
121 .appId(intent.appId()) 121 .appId(intent.appId())
122 - .selector(intent.selector())
123 .treatment(intent.treatment()) 122 .treatment(intent.treatment())
124 .links(Sets.newHashSet(links.values())) 123 .links(Sets.newHashSet(links.values()))
125 - .ingressPoints(intent.ingressPoints()) 124 + .filteredIngressPoints(intent.filteredIngressPoints())
126 - .egressPoints(ImmutableSet.of(intent.egressPoint())) 125 + .filteredEgressPoints(ImmutableSet.of(intent.filteredEgressPoint()))
127 - .ingressSelectors(intent.ingressSelectors())
128 .priority(intent.priority()) 126 .priority(intent.priority())
129 .constraints(intent.constraints()) 127 .constraints(intent.constraints())
130 .build(); 128 .build();
......
...@@ -69,15 +69,13 @@ public class SinglePointToMultiPointIntentCompiler ...@@ -69,15 +69,13 @@ public class SinglePointToMultiPointIntentCompiler
69 Intent result = LinkCollectionIntent.builder() 69 Intent result = LinkCollectionIntent.builder()
70 .appId(intent.appId()) 70 .appId(intent.appId())
71 .key(intent.key()) 71 .key(intent.key())
72 - .selector(intent.selector())
73 .treatment(intent.treatment()) 72 .treatment(intent.treatment())
74 .links(links) 73 .links(links)
75 - .ingressPoints(ImmutableSet.of(intent.ingressPoint())) 74 + .filteredIngressPoints(ImmutableSet.of(intent.filteredIngressPoint()))
76 - .egressPoints(intent.egressPoints()) 75 + .filteredEgressPoints(intent.filteredEgressPoints())
77 .priority(intent.priority()) 76 .priority(intent.priority())
78 .applyTreatmentOnEgress(true) 77 .applyTreatmentOnEgress(true)
79 .constraints(intent.constraints()) 78 .constraints(intent.constraints())
80 - .egressTreatments(intent.egressTreatments())
81 .build(); 79 .build();
82 80
83 return Collections.singletonList(result); 81 return Collections.singletonList(result);
......
...@@ -16,10 +16,11 @@ ...@@ -16,10 +16,11 @@
16 package org.onosproject.net.intent.impl.compiler; 16 package org.onosproject.net.intent.impl.compiler;
17 17
18 import com.google.common.collect.ImmutableSet; 18 import com.google.common.collect.ImmutableSet;
19 -import com.google.common.collect.Maps;
20 import org.junit.After; 19 import org.junit.After;
21 import org.junit.Before; 20 import org.junit.Before;
22 import org.junit.Test; 21 import org.junit.Test;
22 +import org.onlab.packet.IpPrefix;
23 +import org.onlab.packet.MacAddress;
23 import org.onlab.packet.VlanId; 24 import org.onlab.packet.VlanId;
24 import org.onosproject.TestApplicationId; 25 import org.onosproject.TestApplicationId;
25 import org.onosproject.cfg.ComponentConfigAdapter; 26 import org.onosproject.cfg.ComponentConfigAdapter;
...@@ -28,14 +29,15 @@ import org.onosproject.core.CoreService; ...@@ -28,14 +29,15 @@ import org.onosproject.core.CoreService;
28 import org.onosproject.core.IdGenerator; 29 import org.onosproject.core.IdGenerator;
29 import org.onosproject.net.ConnectPoint; 30 import org.onosproject.net.ConnectPoint;
30 import org.onosproject.net.DefaultLink; 31 import org.onosproject.net.DefaultLink;
32 +import org.onosproject.net.DeviceId;
33 +import org.onosproject.net.FilteredConnectPoint;
31 import org.onosproject.net.Link; 34 import org.onosproject.net.Link;
35 +import org.onosproject.net.PortNumber;
32 import org.onosproject.net.flow.DefaultTrafficSelector; 36 import org.onosproject.net.flow.DefaultTrafficSelector;
33 import org.onosproject.net.flow.DefaultTrafficTreatment; 37 import org.onosproject.net.flow.DefaultTrafficTreatment;
34 import org.onosproject.net.flow.FlowRule; 38 import org.onosproject.net.flow.FlowRule;
35 import org.onosproject.net.flow.TrafficSelector; 39 import org.onosproject.net.flow.TrafficSelector;
36 import org.onosproject.net.flow.TrafficTreatment; 40 import org.onosproject.net.flow.TrafficTreatment;
37 -import org.onosproject.net.flow.criteria.Criteria;
38 -import org.onosproject.net.flow.criteria.Criterion;
39 import org.onosproject.net.intent.FlowRuleIntent; 41 import org.onosproject.net.intent.FlowRuleIntent;
40 import org.onosproject.net.intent.Intent; 42 import org.onosproject.net.intent.Intent;
41 import org.onosproject.net.intent.IntentExtensionService; 43 import org.onosproject.net.intent.IntentExtensionService;
...@@ -45,20 +47,19 @@ import org.onosproject.net.intent.MockIdGenerator; ...@@ -45,20 +47,19 @@ import org.onosproject.net.intent.MockIdGenerator;
45 import java.util.Collection; 47 import java.util.Collection;
46 import java.util.Collections; 48 import java.util.Collections;
47 import java.util.List; 49 import java.util.List;
48 -import java.util.Map;
49 import java.util.Set; 50 import java.util.Set;
50 import java.util.stream.Collectors; 51 import java.util.stream.Collectors;
51 52
52 import static org.easymock.EasyMock.createMock; 53 import static org.easymock.EasyMock.createMock;
53 import static org.easymock.EasyMock.expect; 54 import static org.easymock.EasyMock.expect;
54 import static org.easymock.EasyMock.replay; 55 import static org.easymock.EasyMock.replay;
56 +import static org.hamcrest.CoreMatchers.instanceOf;
57 +import static org.hamcrest.CoreMatchers.notNullValue;
55 import static org.hamcrest.MatcherAssert.assertThat; 58 import static org.hamcrest.MatcherAssert.assertThat;
56 import static org.hamcrest.Matchers.hasSize; 59 import static org.hamcrest.Matchers.hasSize;
57 import static org.hamcrest.Matchers.is; 60 import static org.hamcrest.Matchers.is;
58 import static org.onosproject.net.Link.Type.DIRECT; 61 import static org.onosproject.net.Link.Type.DIRECT;
59 -import static org.onosproject.net.NetTestTools.APP_ID; 62 +import static org.onosproject.net.NetTestTools.*;
60 -import static org.onosproject.net.NetTestTools.PID;
61 -import static org.onosproject.net.NetTestTools.connectPoint;
62 63
63 public class LinkCollectionIntentCompilerTest { 64 public class LinkCollectionIntentCompilerTest {
64 65
...@@ -67,87 +68,66 @@ public class LinkCollectionIntentCompilerTest { ...@@ -67,87 +68,66 @@ public class LinkCollectionIntentCompilerTest {
67 private final ConnectPoint d1p1 = connectPoint("s1", 1); 68 private final ConnectPoint d1p1 = connectPoint("s1", 1);
68 private final ConnectPoint d2p0 = connectPoint("s2", 0); 69 private final ConnectPoint d2p0 = connectPoint("s2", 0);
69 private final ConnectPoint d2p1 = connectPoint("s2", 1); 70 private final ConnectPoint d2p1 = connectPoint("s2", 1);
70 - private final ConnectPoint d2p2 = connectPoint("s2", 2);
71 - private final ConnectPoint d2p3 = connectPoint("s2", 3);
72 private final ConnectPoint d3p1 = connectPoint("s3", 1); 71 private final ConnectPoint d3p1 = connectPoint("s3", 1);
73 - private final ConnectPoint d3p2 = connectPoint("s3", 9);
74 private final ConnectPoint d3p0 = connectPoint("s3", 10); 72 private final ConnectPoint d3p0 = connectPoint("s3", 10);
75 private final ConnectPoint d1p0 = connectPoint("s1", 10); 73 private final ConnectPoint d1p0 = connectPoint("s1", 10);
76 - private final ConnectPoint d4p1 = connectPoint("s4", 1);
77 - private final ConnectPoint d4p0 = connectPoint("s4", 10);
78 74
75 + private final DeviceId of1Id = DeviceId.deviceId("of:of1");
76 + private final DeviceId of2Id = DeviceId.deviceId("of:of2");
77 + private final DeviceId of3Id = DeviceId.deviceId("of:of3");
78 + private final DeviceId of4Id = DeviceId.deviceId("of:of4");
79 +
80 + private final ConnectPoint of1p1 = connectPoint("of1", 1);
81 + private final ConnectPoint of1p2 = connectPoint("of1", 2);
82 + private final ConnectPoint of2p1 = connectPoint("of2", 1);
83 + private final ConnectPoint of2p2 = connectPoint("of2", 2);
84 + private final ConnectPoint of2p3 = connectPoint("of2", 3);
85 + private final ConnectPoint of3p1 = connectPoint("of3", 1);
86 + private final ConnectPoint of3p2 = connectPoint("of3", 2);
87 + private final ConnectPoint of4p1 = connectPoint("of4", 1);
88 + private final ConnectPoint of4p2 = connectPoint("of4", 2);
79 89
80 private final Set<Link> links = ImmutableSet.of( 90 private final Set<Link> links = ImmutableSet.of(
81 DefaultLink.builder().providerId(PID).src(d1p1).dst(d2p0).type(DIRECT).build(), 91 DefaultLink.builder().providerId(PID).src(d1p1).dst(d2p0).type(DIRECT).build(),
82 DefaultLink.builder().providerId(PID).src(d2p1).dst(d3p1).type(DIRECT).build(), 92 DefaultLink.builder().providerId(PID).src(d2p1).dst(d3p1).type(DIRECT).build(),
83 DefaultLink.builder().providerId(PID).src(d1p1).dst(d3p1).type(DIRECT).build()); 93 DefaultLink.builder().providerId(PID).src(d1p1).dst(d3p1).type(DIRECT).build());
84 94
85 - private final Set<Link> linksMultiple = ImmutableSet.of(
86 - DefaultLink.builder().providerId(PID).src(d3p1).dst(d2p0).type(DIRECT).build());
87 -
88 - private final Set<Link> linksMultiple2 = ImmutableSet.of(
89 - DefaultLink.builder().providerId(PID).src(d2p0).dst(d1p1).type(DIRECT).build(),
90 - DefaultLink.builder().providerId(PID).src(d2p1).dst(d3p1).type(DIRECT).build(),
91 - DefaultLink.builder().providerId(PID).src(d2p2).dst(d4p1).type(DIRECT).build());
92 -
93 private final TrafficSelector selector = DefaultTrafficSelector.builder().build(); 95 private final TrafficSelector selector = DefaultTrafficSelector.builder().build();
94 private final TrafficTreatment treatment = DefaultTrafficTreatment.builder().build(); 96 private final TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
95 97
96 - private final VlanId ingressVlan1 = VlanId.vlanId("10"); 98 + private final TrafficSelector vlan100Selector = DefaultTrafficSelector.builder()
97 - private final TrafficSelector selectorVlan1 = DefaultTrafficSelector 99 + .matchVlanId(VlanId.vlanId("100"))
98 - .builder()
99 - .matchVlanId(ingressVlan1)
100 - .build();
101 -
102 - private final VlanId ingressVlan2 = VlanId.vlanId("20");
103 - private final TrafficSelector selectorVlan2 = DefaultTrafficSelector
104 - .builder()
105 - .matchVlanId(ingressVlan2)
106 - .build();
107 -
108 - private final VlanId egressVlan = VlanId.vlanId("666");
109 - private final TrafficTreatment vlanTreatment = DefaultTrafficTreatment
110 - .builder()
111 - .setVlanId(egressVlan)
112 .build(); 100 .build();
113 101
114 -private final VlanId ingressVlan = VlanId.vlanId("10"); 102 + private final TrafficSelector vlan200Selector = DefaultTrafficSelector.builder()
115 - private final TrafficSelector vlanSelector = DefaultTrafficSelector 103 + .matchVlanId(VlanId.vlanId("200"))
116 - .builder()
117 - .matchVlanId(ingressVlan)
118 .build(); 104 .build();
119 105
120 - private final VlanId egressVlan1 = VlanId.vlanId("20"); 106 + private final TrafficSelector ipPrefixSelector = DefaultTrafficSelector.builder()
121 - private final TrafficTreatment vlanTreatment1 = DefaultTrafficTreatment 107 + .matchIPDst(IpPrefix.valueOf("192.168.100.0/24"))
122 - .builder()
123 - .setVlanId(egressVlan1)
124 .build(); 108 .build();
125 109
126 - private final VlanId egressVlan2 = VlanId.vlanId("666"); 110 + private final TrafficTreatment ethDstTreatment = DefaultTrafficTreatment.builder()
127 - private final TrafficTreatment vlanTreatment2 = DefaultTrafficTreatment 111 + .setEthDst(MacAddress.valueOf("C0:FF:EE:C0:FF:EE"))
128 - .builder()
129 - .setVlanId(egressVlan2)
130 .build(); 112 .build();
131 113
132 - private final VlanId egressVlan3 = VlanId.vlanId("69");
133 - private final TrafficTreatment vlanTreatment3 = DefaultTrafficTreatment
134 - .builder()
135 - .setVlanId(egressVlan3)
136 - .build();
137 -
138 -
139 private CoreService coreService; 114 private CoreService coreService;
140 private IntentExtensionService intentExtensionService; 115 private IntentExtensionService intentExtensionService;
141 private IntentConfigurableRegistrator registrator; 116 private IntentConfigurableRegistrator registrator;
142 private IdGenerator idGenerator = new MockIdGenerator(); 117 private IdGenerator idGenerator = new MockIdGenerator();
143 118
144 private LinkCollectionIntent intent; 119 private LinkCollectionIntent intent;
145 - private LinkCollectionIntent intentMultipleSelectors;
146 - private LinkCollectionIntent intentMultipleTreatments;
147 - private LinkCollectionIntent intentMultipleTreatments2;
148 120
149 private LinkCollectionIntentCompiler sut; 121 private LinkCollectionIntentCompiler sut;
150 122
123 +
124 +
125 + private List<FlowRule> getFlowRulesByDevice(DeviceId deviceId, Collection<FlowRule> flowRules) {
126 + return flowRules.stream()
127 + .filter(fr -> fr.deviceId().equals(deviceId))
128 + .collect(Collectors.toList());
129 + }
130 +
151 @Before 131 @Before
152 public void setUp() { 132 public void setUp() {
153 sut = new LinkCollectionIntentCompiler(); 133 sut = new LinkCollectionIntentCompiler();
...@@ -166,32 +146,6 @@ private final VlanId ingressVlan = VlanId.vlanId("10"); ...@@ -166,32 +146,6 @@ private final VlanId ingressVlan = VlanId.vlanId("10");
166 .ingressPoints(ImmutableSet.of(d1p1)) 146 .ingressPoints(ImmutableSet.of(d1p1))
167 .egressPoints(ImmutableSet.of(d3p1)) 147 .egressPoints(ImmutableSet.of(d3p1))
168 .build(); 148 .build();
169 - intentMultipleSelectors = LinkCollectionIntent.builder()
170 - .appId(APP_ID)
171 - .treatment(vlanTreatment)
172 - .links(linksMultiple)
173 - .ingressPoints(ImmutableSet.of(d3p0, d3p2))
174 - .egressPoints(ImmutableSet.of(d2p1))
175 - .ingressSelectors(this.createIngressSelectors())
176 - .build();
177 - intentMultipleTreatments = LinkCollectionIntent.builder()
178 - .appId(APP_ID)
179 - .selector(vlanSelector)
180 - .links(linksMultiple)
181 - .ingressPoints(ImmutableSet.of(d3p0))
182 - .egressPoints(ImmutableSet.of(d2p1, d2p2))
183 - .egressTreatments(this.createEgressTreatments())
184 - .applyTreatmentOnEgress(true)
185 - .build();
186 - intentMultipleTreatments2 = LinkCollectionIntent.builder()
187 - .appId(APP_ID)
188 - .selector(vlanSelector)
189 - .links(linksMultiple2)
190 - .ingressPoints(ImmutableSet.of(d2p3))
191 - .egressPoints(ImmutableSet.of(d1p0, d3p0, d4p0))
192 - .egressTreatments(this.createEgressTreatments2())
193 - .applyTreatmentOnEgress(true)
194 - .build();
195 149
196 intentExtensionService = createMock(IntentExtensionService.class); 150 intentExtensionService = createMock(IntentExtensionService.class);
197 intentExtensionService.registerCompiler(LinkCollectionIntent.class, sut); 151 intentExtensionService.registerCompiler(LinkCollectionIntent.class, sut);
...@@ -205,10 +159,13 @@ private final VlanId ingressVlan = VlanId.vlanId("10"); ...@@ -205,10 +159,13 @@ private final VlanId ingressVlan = VlanId.vlanId("10");
205 sut.registrator = registrator; 159 sut.registrator = registrator;
206 160
207 replay(coreService, intentExtensionService); 161 replay(coreService, intentExtensionService);
162 +
163 +
208 } 164 }
209 165
210 @After 166 @After
211 public void tearDown() { 167 public void tearDown() {
168 +
212 Intent.unbindIdGenerator(idGenerator); 169 Intent.unbindIdGenerator(idGenerator);
213 } 170 }
214 171
...@@ -262,299 +219,486 @@ private final VlanId ingressVlan = VlanId.vlanId("10"); ...@@ -262,299 +219,486 @@ private final VlanId ingressVlan = VlanId.vlanId("10");
262 sut.deactivate(); 219 sut.deactivate();
263 } 220 }
264 221
265 -@Test 222 + /**
266 - public void testCompileMultipleSelectors() { 223 + * Single point to multi point case.
224 + * -1 of1 2-1 of2 2--1 of3 2-
225 + * 3
226 + * `-1 of4 2-
227 + */
228 + @Test
229 + public void testFilteredConnectPoint1() {
267 sut.activate(); 230 sut.activate();
231 + Set<Link> testLinks = ImmutableSet.of(
232 + DefaultLink.builder().providerId(PID).src(of1p2).dst(of2p1).type(DIRECT).build(),
233 + DefaultLink.builder().providerId(PID).src(of2p2).dst(of3p1).type(DIRECT).build(),
234 + DefaultLink.builder().providerId(PID).src(of2p3).dst(of4p1).type(DIRECT).build()
235 + );
236 +
237 + TrafficSelector expectOf1Selector = DefaultTrafficSelector.builder(vlan100Selector)
238 + .matchInPort(PortNumber.portNumber(1))
239 + .build();
268 240
269 - List<Intent> compiled = sut.compile(intentMultipleSelectors, Collections.emptyList()); 241 + TrafficTreatment expectOf1Treatment = DefaultTrafficTreatment.builder()
270 - assertThat(compiled, hasSize(1)); 242 + .setOutput(PortNumber.portNumber(2))
243 + .build();
271 244
245 + TrafficSelector expectOf2Selector = DefaultTrafficSelector.builder(vlan100Selector)
246 + .matchInPort(PortNumber.portNumber(1))
247 + .build();
272 248
273 - Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules(); 249 + TrafficTreatment expectOf2Treatment = DefaultTrafficTreatment.builder()
274 - assertThat(rules, hasSize((linksMultiple.size()) + intentMultipleSelectors.ingressPoints().size())); 250 + .setOutput(PortNumber.portNumber(2))
251 + .setOutput(PortNumber.portNumber(3))
252 + .build();
275 253
276 - Set<FlowRule> d3Rules = rules 254 + TrafficSelector expectOf3Selector = DefaultTrafficSelector.builder(vlan100Selector)
277 - .parallelStream() 255 + .matchInPort(PortNumber.portNumber(1))
278 - .filter(rule -> rule.deviceId().equals(d3p0.deviceId())) 256 + .build();
279 - .collect(Collectors.toSet());
280 - assertThat(d3Rules, hasSize(intentMultipleSelectors.ingressPoints().size()));
281 257
282 - FlowRule rule1 = rules.stream() 258 + TrafficTreatment expectOf3Treatment = DefaultTrafficTreatment.builder()
283 - .filter(rule -> rule.deviceId().equals(d3p0.deviceId()) 259 + .setOutput(PortNumber.portNumber(2))
284 - && 260 + .build();
285 - rule.selector().getCriterion(Criterion.Type.IN_PORT).equals(Criteria.matchInPort(d3p0.port())))
286 - .findFirst()
287 - .get();
288 - assertThat(rule1.selector(), is(
289 - DefaultTrafficSelector
290 - .builder(intentMultipleSelectors.selector())
291 - .matchInPort(d3p0.port())
292 - .matchVlanId(ingressVlan1)
293 - .build()
294 - ));
295 - assertThat(rule1.treatment(), is(
296 - DefaultTrafficTreatment
297 - .builder(intentMultipleSelectors.treatment())
298 - .setOutput(d3p1.port())
299 - .build()
300 - ));
301 - assertThat(rule1.priority(), is(intentMultipleSelectors.priority()));
302 261
303 - FlowRule rule2 = rules.stream() 262 + TrafficSelector expectOf4Selector = DefaultTrafficSelector.builder(vlan100Selector)
304 - .filter(rule -> rule.deviceId().equals(d3p0.deviceId()) 263 + .matchInPort(PortNumber.portNumber(1))
305 - && 264 + .build();
306 - rule.selector().getCriterion(Criterion.Type.IN_PORT).equals(Criteria.matchInPort(d3p2.port())))
307 - .findFirst()
308 - .get();
309 - assertThat(rule2.selector(), is(
310 - DefaultTrafficSelector
311 - .builder(intentMultipleSelectors.selector())
312 - .matchInPort(d3p2.port())
313 - .matchVlanId(ingressVlan2)
314 - .build()
315 - ));
316 - assertThat(rule2.treatment(), is(
317 - DefaultTrafficTreatment
318 - .builder(intentMultipleSelectors.treatment())
319 - .setOutput(d3p1.port())
320 - .build()
321 - ));
322 - assertThat(rule2.priority(), is(intentMultipleSelectors.priority()));
323 265
324 - Set<FlowRule> d2Rules = rules 266 + TrafficTreatment expectOf4Treatment = DefaultTrafficTreatment.builder()
325 - .parallelStream() 267 + .setVlanId(VlanId.vlanId("200"))
326 - .filter(rule -> rule.deviceId().equals(d2p0.deviceId())) 268 + .setOutput(PortNumber.portNumber(2))
327 - .collect(Collectors.toSet()); 269 + .build();
328 - assertThat(d2Rules, hasSize(intentMultipleSelectors.egressPoints().size()));
329 270
330 - // We do not need in_port filter
331 - FlowRule rule3 = rules.stream()
332 - .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
333 - .findFirst()
334 - .get();
335 - assertThat(rule3.selector(), is(
336 - DefaultTrafficSelector
337 - .builder(intentMultipleSelectors.selector())
338 - .matchInPort(d2p0.port())
339 - .matchVlanId(egressVlan)
340 - .build()
341 - ));
342 - assertThat(rule3.treatment(), is(
343 - DefaultTrafficTreatment
344 - .builder()
345 - .setOutput(d2p1.port())
346 - .build()
347 - ));
348 - assertThat(rule3.priority(), is(intentMultipleSelectors.priority()));
349 271
272 +
273 + Set<FilteredConnectPoint> ingress = ImmutableSet.of(
274 + new FilteredConnectPoint(of1p1, vlan100Selector)
275 + );
276 +
277 + Set<FilteredConnectPoint> egress = ImmutableSet.of(
278 + new FilteredConnectPoint(of3p2, vlan100Selector),
279 + new FilteredConnectPoint(of4p2, vlan200Selector)
280 + );
281 +
282 + intent = LinkCollectionIntent.builder()
283 + .appId(APP_ID)
284 + .filteredIngressPoints(ingress)
285 + .filteredEgressPoints(egress)
286 + .treatment(treatment)
287 + .applyTreatmentOnEgress(true)
288 + .links(testLinks)
289 + .build();
290 +
291 + assertThat(sut, is(notNullValue()));
292 +
293 + List<Intent> result = sut.compile(intent, Collections.emptyList());
294 +
295 + assertThat(result, is(notNullValue()));
296 + assertThat(result, hasSize(1));
297 +
298 + Intent resultIntent = result.get(0);
299 + assertThat(resultIntent, instanceOf(FlowRuleIntent.class));
300 +
301 + if (resultIntent instanceof FlowRuleIntent) {
302 + FlowRuleIntent frIntent = (FlowRuleIntent) resultIntent;
303 +
304 + assertThat(frIntent.flowRules(), hasSize(4));
305 +
306 + List<FlowRule> deviceFlowRules;
307 + FlowRule flowRule;
308 +
309 + // Of1
310 + deviceFlowRules = getFlowRulesByDevice(of1Id, frIntent.flowRules());
311 + assertThat(deviceFlowRules, hasSize(1));
312 + flowRule = deviceFlowRules.get(0);
313 + assertThat(flowRule.selector(), is(expectOf1Selector));
314 + assertThat(flowRule.treatment(), is(expectOf1Treatment));
315 +
316 + // Of2
317 + deviceFlowRules = getFlowRulesByDevice(of2Id, frIntent.flowRules());
318 + assertThat(deviceFlowRules, hasSize(1));
319 + flowRule = deviceFlowRules.get(0);
320 + assertThat(flowRule.selector(), is(expectOf2Selector));
321 + assertThat(flowRule.treatment(), is(expectOf2Treatment));
322 +
323 + // Of3
324 + deviceFlowRules = getFlowRulesByDevice(of3Id, frIntent.flowRules());
325 + assertThat(deviceFlowRules, hasSize(1));
326 + flowRule = deviceFlowRules.get(0);
327 + assertThat(flowRule.selector(), is(expectOf3Selector));
328 + assertThat(flowRule.treatment(), is(expectOf3Treatment));
329 +
330 + // Of4
331 + deviceFlowRules = getFlowRulesByDevice(of4Id, frIntent.flowRules());
332 + assertThat(deviceFlowRules, hasSize(1));
333 + flowRule = deviceFlowRules.get(0);
334 + assertThat(flowRule.selector(), is(expectOf4Selector));
335 + assertThat(flowRule.treatment(), is(expectOf4Treatment));
336 +
337 + }
350 sut.deactivate(); 338 sut.deactivate();
351 } 339 }
352 340
341 + /**
342 + * Multi point to single point intent with filtered connect point.
343 + *
344 + * -1 of1 2-1 of2 2-1 of4 2-
345 + * 3
346 + * -1 of3 2---/
347 + */
353 @Test 348 @Test
354 - public void testCompileMultipleTreatments() { 349 + public void testFilteredConnectPoint2() {
355 sut.activate(); 350 sut.activate();
351 + Set<Link> testlinks = ImmutableSet.of(
352 + DefaultLink.builder().providerId(PID).src(of1p2).dst(of2p1).type(DIRECT).build(),
353 + DefaultLink.builder().providerId(PID).src(of3p2).dst(of2p3).type(DIRECT).build(),
354 + DefaultLink.builder().providerId(PID).src(of2p2).dst(of4p1).type(DIRECT).build()
355 + );
356 +
357 + Set<FilteredConnectPoint> ingress = ImmutableSet.of(
358 + new FilteredConnectPoint(of1p1, vlan100Selector),
359 + new FilteredConnectPoint(of3p1, vlan100Selector)
360 + );
361 +
362 + Set<FilteredConnectPoint> egress = ImmutableSet.of(
363 + new FilteredConnectPoint(of4p2, vlan200Selector)
364 + );
365 +
366 + TrafficSelector expectOf1Selector = DefaultTrafficSelector.builder(vlan100Selector)
367 + .matchInPort(PortNumber.portNumber(1))
368 + .build();
356 369
357 - List<Intent> compiled = sut.compile(intentMultipleTreatments, Collections.emptyList()); 370 + TrafficTreatment expectOf1Treatment = DefaultTrafficTreatment.builder()
358 - assertThat(compiled, hasSize(1)); 371 + .setVlanId(VlanId.vlanId("200"))
372 + .setOutput(PortNumber.portNumber(2))
373 + .build();
359 374
360 - Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules(); 375 + TrafficSelector expectOf2Selector1 = DefaultTrafficSelector.builder(vlan200Selector)
361 - assertThat(rules, hasSize(2)); 376 + .matchInPort(PortNumber.portNumber(1))
377 + .build();
362 378
363 - Set<FlowRule> d3Rules = rules 379 + TrafficSelector expectOf2Selector2 = DefaultTrafficSelector.builder(vlan200Selector)
364 - .parallelStream() 380 + .matchInPort(PortNumber.portNumber(3))
365 - .filter(rule -> rule.deviceId().equals(d3p0.deviceId())) 381 + .build();
366 - .collect(Collectors.toSet());
367 - assertThat(d3Rules, hasSize(intentMultipleTreatments.ingressPoints().size()));
368 382
369 - FlowRule rule1 = rules.stream() 383 + TrafficTreatment expectOf2Treatment = DefaultTrafficTreatment.builder()
370 - .filter(rule -> rule.deviceId().equals(d3p0.deviceId())) 384 + .setOutput(PortNumber.portNumber(2))
371 - .findFirst() 385 + .build();
372 - .get();
373 - assertThat(rule1.selector(), is(
374 - DefaultTrafficSelector
375 - .builder(intentMultipleTreatments.selector())
376 - .matchInPort(d3p0.port())
377 - .matchVlanId(ingressVlan)
378 - .build()
379 - ));
380 - assertThat(rule1.treatment(), is(
381 - DefaultTrafficTreatment
382 - .builder(intentMultipleTreatments.treatment())
383 - .setOutput(d3p1.port())
384 - .build()
385 - ));
386 - assertThat(rule1.priority(), is(intentMultipleTreatments.priority()));
387 386
388 - Set<FlowRule> d2Rules = rules 387 + TrafficSelector expectOf3Selector = DefaultTrafficSelector.builder(vlan100Selector)
389 - .parallelStream() 388 + .matchInPort(PortNumber.portNumber(1))
390 - .filter(rule -> rule.deviceId().equals(d2p0.deviceId())) 389 + .build();
391 - .collect(Collectors.toSet());
392 - assertThat(d2Rules, hasSize(1));
393 390
394 - FlowRule rule2 = rules.stream() 391 + TrafficTreatment expectOf3Treatment = DefaultTrafficTreatment.builder()
395 - .filter(rule -> rule.deviceId().equals(d2p0.deviceId())) 392 + .setVlanId(VlanId.vlanId("200"))
396 - .findFirst() 393 + .setOutput(PortNumber.portNumber(2))
397 - .get(); 394 + .build();
398 - assertThat(rule2.selector(), is( 395 +
399 - DefaultTrafficSelector 396 + TrafficSelector expectOf4Selector = DefaultTrafficSelector.builder(vlan100Selector)
400 - .builder(intentMultipleTreatments.selector()) 397 + .matchInPort(PortNumber.portNumber(1))
401 - .matchInPort(d2p0.port()) 398 + .matchVlanId(VlanId.vlanId("200"))
402 - .matchVlanId(ingressVlan) 399 + .build();
403 - .build() 400 +
404 - )); 401 + TrafficTreatment expectOf4Treatment = DefaultTrafficTreatment.builder()
405 - assertThat(rule2.treatment(), is( 402 + .setOutput(PortNumber.portNumber(2))
406 - DefaultTrafficTreatment 403 + .build();
407 - .builder(intentMultipleTreatments.treatment()) 404 +
408 - .setVlanId(egressVlan1) 405 + intent = LinkCollectionIntent.builder()
409 - .setOutput(d2p1.port()) 406 + .appId(APP_ID)
410 - .setVlanId(egressVlan2) 407 + .filteredIngressPoints(ingress)
411 - .setOutput(d2p2.port()) 408 + .filteredEgressPoints(egress)
412 - .build() 409 + .treatment(treatment)
413 - )); 410 + .links(testlinks)
414 - assertThat(rule2.priority(), is(intentMultipleTreatments.priority())); 411 + .build();
415 412
413 + List<Intent> result = sut.compile(intent, Collections.emptyList());
414 +
415 + assertThat(result, is(notNullValue()));
416 + assertThat(result, hasSize(1));
417 +
418 + Intent resultIntent = result.get(0);
419 + assertThat(resultIntent, instanceOf(FlowRuleIntent.class));
420 +
421 + if (resultIntent instanceof FlowRuleIntent) {
422 + FlowRuleIntent frIntent = (FlowRuleIntent) resultIntent;
423 + assertThat(frIntent.flowRules(), hasSize(5));
424 +
425 + List<FlowRule> deviceFlowRules;
426 + FlowRule flowRule;
427 +
428 + // Of1
429 + deviceFlowRules = getFlowRulesByDevice(of1Id, frIntent.flowRules());
430 + assertThat(deviceFlowRules, hasSize(1));
431 + flowRule = deviceFlowRules.get(0);
432 + assertThat(flowRule.selector(), is(expectOf1Selector));
433 + assertThat(flowRule.treatment(), is(expectOf1Treatment));
434 +
435 + // Of2 (has 2 flows)
436 + deviceFlowRules = getFlowRulesByDevice(of2Id, frIntent.flowRules());
437 + assertThat(deviceFlowRules, hasSize(2));
438 + flowRule = deviceFlowRules.get(0);
439 + assertThat(flowRule.selector(), is(expectOf2Selector1));
440 + assertThat(flowRule.treatment(), is(expectOf2Treatment));
441 + flowRule = deviceFlowRules.get(1);
442 + assertThat(flowRule.selector(), is(expectOf2Selector2));
443 + assertThat(flowRule.treatment(), is(expectOf2Treatment));
444 +
445 + // Of3
446 + deviceFlowRules = getFlowRulesByDevice(of3Id, frIntent.flowRules());
447 + assertThat(deviceFlowRules, hasSize(1));
448 + flowRule = deviceFlowRules.get(0);
449 + assertThat(flowRule.selector(), is(expectOf3Selector));
450 + assertThat(flowRule.treatment(), is(expectOf3Treatment));
451 +
452 + // Of4
453 + deviceFlowRules = getFlowRulesByDevice(of4Id, frIntent.flowRules());
454 + assertThat(deviceFlowRules, hasSize(1));
455 + flowRule = deviceFlowRules.get(0);
456 + assertThat(flowRule.selector(), is(expectOf4Selector));
457 + assertThat(flowRule.treatment(), is(expectOf4Treatment));
416 } 458 }
417 459
460 + sut.deactivate();
461 + }
462 +
463 + /**
464 + * Single point to multi point without filtered connect point case.
465 + * -1 of1 2-1 of2 2--1 of3 2-
466 + * 3
467 + * `-1 of4 2-
468 + */
418 @Test 469 @Test
419 - public void testCompileMultipleTreatments2() { 470 + public void nonTrivialTranslation1() {
420 sut.activate(); 471 sut.activate();
472 + Set<Link> testLinks = ImmutableSet.of(
473 + DefaultLink.builder().providerId(PID).src(of1p2).dst(of2p1).type(DIRECT).build(),
474 + DefaultLink.builder().providerId(PID).src(of2p2).dst(of3p1).type(DIRECT).build(),
475 + DefaultLink.builder().providerId(PID).src(of2p3).dst(of4p1).type(DIRECT).build()
476 + );
477 +
478 + TrafficSelector expectOf1Selector = DefaultTrafficSelector.builder(ipPrefixSelector)
479 + .matchInPort(PortNumber.portNumber(1))
480 + .build();
421 481
422 - List<Intent> compiled = sut.compile(intentMultipleTreatments2, Collections.emptyList()); 482 + TrafficTreatment expectOf1Treatment = DefaultTrafficTreatment.builder()
423 - assertThat(compiled, hasSize(1)); 483 + .setOutput(PortNumber.portNumber(2))
484 + .build();
424 485
486 + TrafficSelector expectOf2Selector = DefaultTrafficSelector.builder(ipPrefixSelector)
487 + .matchInPort(PortNumber.portNumber(1))
488 + .build();
425 489
426 - Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules(); 490 + TrafficTreatment expectOf2Treatment = DefaultTrafficTreatment.builder()
427 - assertThat(rules, hasSize(4)); 491 + .setOutput(PortNumber.portNumber(2))
492 + .setOutput(PortNumber.portNumber(3))
493 + .build();
428 494
495 + TrafficSelector expectOf3Selector = DefaultTrafficSelector.builder(ipPrefixSelector)
496 + .matchInPort(PortNumber.portNumber(1))
497 + .build();
429 498
430 - Set<FlowRule> d2Rules = rules 499 + TrafficTreatment expectOf3Treatment = DefaultTrafficTreatment.builder(ethDstTreatment)
431 - .parallelStream() 500 + .setOutput(PortNumber.portNumber(2))
432 - .filter(rule -> rule.deviceId().equals(d2p0.deviceId())) 501 + .build();
433 - .collect(Collectors.toSet());
434 - assertThat(d2Rules, hasSize(1));
435 502
503 + TrafficSelector expectOf4Selector = DefaultTrafficSelector.builder(ipPrefixSelector)
504 + .matchInPort(PortNumber.portNumber(1))
505 + .build();
436 506
437 - FlowRule rule1 = rules.stream() 507 + TrafficTreatment expectOf4Treatment = DefaultTrafficTreatment.builder(ethDstTreatment)
438 - .filter(rule -> rule.deviceId().equals(d2p0.deviceId())) 508 + .setOutput(PortNumber.portNumber(2))
439 - .findFirst() 509 + .build();
440 - .get();
441 - assertThat(rule1.selector(), is(
442 - DefaultTrafficSelector
443 - .builder(intentMultipleTreatments.selector())
444 - .matchInPort(d2p3.port())
445 - .matchVlanId(ingressVlan)
446 - .build()
447 - ));
448 - assertThat(rule1.treatment(), is(
449 - DefaultTrafficTreatment
450 - .builder(intentMultipleTreatments.treatment())
451 - .setOutput(d2p0.port())
452 - .setOutput(d2p1.port())
453 - .setOutput(d2p2.port())
454 - .build()
455 - ));
456 - assertThat(rule1.priority(), is(intentMultipleTreatments.priority()));
457 510
458 - Set<FlowRule> d1Rules = rules
459 - .parallelStream()
460 - .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
461 - .collect(Collectors.toSet());
462 - assertThat(d1Rules, hasSize(1));
463 511
464 - FlowRule rule2 = rules.stream()
465 - .filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
466 - .findFirst()
467 - .get();
468 - assertThat(rule2.selector(), is(
469 - DefaultTrafficSelector
470 - .builder(intentMultipleTreatments2.selector())
471 - .matchInPort(d1p1.port())
472 - .matchVlanId(ingressVlan)
473 - .build()
474 - ));
475 - assertThat(rule2.treatment(), is(
476 - DefaultTrafficTreatment
477 - .builder(intentMultipleTreatments2.treatment())
478 - .setVlanId(egressVlan1)
479 - .setOutput(d1p0.port())
480 - .build()
481 - ));
482 - assertThat(rule2.priority(), is(intentMultipleTreatments.priority()));
483 512
484 - Set<FlowRule> d3Rules = rules 513 + Set<ConnectPoint> ingress = ImmutableSet.of(
485 - .parallelStream() 514 + of1p1
486 - .filter(rule -> rule.deviceId().equals(d3p0.deviceId())) 515 + );
487 - .collect(Collectors.toSet());
488 - assertThat(d3Rules, hasSize(1));
489 516
490 - FlowRule rule3 = rules.stream() 517 + Set<ConnectPoint> egress = ImmutableSet.of(
491 - .filter(rule -> rule.deviceId().equals(d3p0.deviceId())) 518 + of3p2,
492 - .findFirst() 519 + of4p2
493 - .get(); 520 + );
494 - assertThat(rule3.selector(), is(
495 - DefaultTrafficSelector
496 - .builder(intentMultipleTreatments2.selector())
497 - .matchInPort(d3p1.port())
498 - .matchVlanId(ingressVlan)
499 - .build()
500 - ));
501 - assertThat(rule3.treatment(), is(
502 - DefaultTrafficTreatment
503 - .builder(intentMultipleTreatments2.treatment())
504 - .setVlanId(egressVlan2)
505 - .setOutput(d3p0.port())
506 - .build()
507 - ));
508 - assertThat(rule3.priority(), is(intentMultipleTreatments.priority()));
509 521
510 - Set<FlowRule> d4Rules = rules 522 + intent = LinkCollectionIntent.builder()
511 - .parallelStream() 523 + .appId(APP_ID)
512 - .filter(rule -> rule.deviceId().equals(d4p0.deviceId())) 524 + .selector(ipPrefixSelector)
513 - .collect(Collectors.toSet()); 525 + .treatment(ethDstTreatment)
514 - assertThat(d4Rules, hasSize(1)); 526 + .ingressPoints(ingress)
527 + .egressPoints(egress)
528 + .applyTreatmentOnEgress(true)
529 + .links(testLinks)
530 + .build();
515 531
516 - FlowRule rule4 = rules.stream() 532 + assertThat(sut, is(notNullValue()));
517 - .filter(rule -> rule.deviceId().equals(d4p0.deviceId()))
518 - .findFirst()
519 - .get();
520 - assertThat(rule4.selector(), is(
521 - DefaultTrafficSelector
522 - .builder(intentMultipleTreatments2.selector())
523 - .matchInPort(d4p1.port())
524 - .matchVlanId(ingressVlan)
525 - .build()
526 - ));
527 - assertThat(rule4.treatment(), is(
528 - DefaultTrafficTreatment
529 - .builder(intentMultipleTreatments2.treatment())
530 - .setVlanId(egressVlan3)
531 - .setOutput(d4p0.port())
532 - .build()
533 - ));
534 - assertThat(rule4.priority(), is(intentMultipleTreatments.priority()));
535 533
536 - } 534 + List<Intent> result = sut.compile(intent, Collections.emptyList());
537 535
538 - public Map<ConnectPoint, TrafficTreatment> createEgressTreatments() { 536 + assertThat(result, is(notNullValue()));
539 - Map<ConnectPoint, TrafficTreatment> mapToReturn = Maps.newHashMap(); 537 + assertThat(result, hasSize(1));
540 - mapToReturn.put(d2p1, vlanTreatment1); 538 +
541 - mapToReturn.put(d2p2, vlanTreatment2); 539 + Intent resultIntent = result.get(0);
542 - return mapToReturn; 540 + assertThat(resultIntent, instanceOf(FlowRuleIntent.class));
543 - } 541 +
542 + if (resultIntent instanceof FlowRuleIntent) {
543 + FlowRuleIntent frIntent = (FlowRuleIntent) resultIntent;
544 +
545 + assertThat(frIntent.flowRules(), hasSize(4));
546 +
547 + List<FlowRule> deviceFlowRules;
548 + FlowRule flowRule;
549 +
550 + // Of1
551 + deviceFlowRules = getFlowRulesByDevice(of1Id, frIntent.flowRules());
552 + assertThat(deviceFlowRules, hasSize(1));
553 + flowRule = deviceFlowRules.get(0);
554 + assertThat(flowRule.selector(), is(expectOf1Selector));
555 + assertThat(flowRule.treatment(), is(expectOf1Treatment));
556 +
557 + // Of2
558 + deviceFlowRules = getFlowRulesByDevice(of2Id, frIntent.flowRules());
559 + assertThat(deviceFlowRules, hasSize(1));
560 + flowRule = deviceFlowRules.get(0);
561 + assertThat(flowRule.selector(), is(expectOf2Selector));
562 + assertThat(flowRule.treatment(), is(expectOf2Treatment));
544 563
545 - public Map<ConnectPoint, TrafficTreatment> createEgressTreatments2() { 564 + // Of3
546 - Map<ConnectPoint, TrafficTreatment> mapToReturn = Maps.newHashMap(); 565 + deviceFlowRules = getFlowRulesByDevice(of3Id, frIntent.flowRules());
547 - mapToReturn.put(d1p0, vlanTreatment1); 566 + assertThat(deviceFlowRules, hasSize(1));
548 - mapToReturn.put(d3p0, vlanTreatment2); 567 + flowRule = deviceFlowRules.get(0);
549 - mapToReturn.put(d4p0, vlanTreatment3); 568 + assertThat(flowRule.selector(), is(expectOf3Selector));
550 - return mapToReturn; 569 + assertThat(flowRule.treatment(), is(expectOf3Treatment));
570 +
571 + // Of4
572 + deviceFlowRules = getFlowRulesByDevice(of4Id, frIntent.flowRules());
573 + assertThat(deviceFlowRules, hasSize(1));
574 + flowRule = deviceFlowRules.get(0);
575 + assertThat(flowRule.selector(), is(expectOf4Selector));
576 + assertThat(flowRule.treatment(), is(expectOf4Treatment));
577 +
578 + }
579 + sut.deactivate();
551 } 580 }
552 581
553 - public Map<ConnectPoint, TrafficSelector> createIngressSelectors() { 582 + /**
554 - Map<ConnectPoint, TrafficSelector> mapToReturn = Maps.newHashMap(); 583 + * Multi point to single point intent without filtered connect point.
555 - mapToReturn.put(d3p0, selectorVlan1); 584 + *
556 - mapToReturn.put(d3p2, selectorVlan2); 585 + * -1 of1 2-1 of2 2-1 of4 2-
557 - return mapToReturn; 586 + * 3
587 + * -1 of3 2---/
588 + */
589 + @Test
590 + public void nonTrivialTranslation2() {
591 + sut.activate();
592 + Set<Link> testlinks = ImmutableSet.of(
593 + DefaultLink.builder().providerId(PID).src(of1p2).dst(of2p1).type(DIRECT).build(),
594 + DefaultLink.builder().providerId(PID).src(of3p2).dst(of2p3).type(DIRECT).build(),
595 + DefaultLink.builder().providerId(PID).src(of2p2).dst(of4p1).type(DIRECT).build()
596 + );
597 +
598 + Set<ConnectPoint> ingress = ImmutableSet.of(
599 + of1p1,
600 + of3p1
601 + );
602 +
603 + Set<ConnectPoint> egress = ImmutableSet.of(
604 + of4p2
605 + );
606 +
607 + TrafficSelector expectOf1Selector = DefaultTrafficSelector.builder(ipPrefixSelector)
608 + .matchInPort(PortNumber.portNumber(1))
609 + .build();
610 +
611 + TrafficTreatment expectOf1Treatment = DefaultTrafficTreatment.builder(ethDstTreatment)
612 + .setOutput(PortNumber.portNumber(2))
613 + .build();
614 +
615 + TrafficSelector expectOf2Selector1 = DefaultTrafficSelector.builder(ipPrefixSelector)
616 + .matchInPort(PortNumber.portNumber(1))
617 + .matchEthDst(MacAddress.valueOf("C0:FF:EE:C0:FF:EE"))
618 + .build();
619 +
620 + TrafficSelector expectOf2Selector2 = DefaultTrafficSelector.builder(ipPrefixSelector)
621 + .matchEthDst(MacAddress.valueOf("C0:FF:EE:C0:FF:EE"))
622 + .matchInPort(PortNumber.portNumber(3))
623 + .build();
624 +
625 + TrafficTreatment expectOf2Treatment = DefaultTrafficTreatment.builder()
626 + .setOutput(PortNumber.portNumber(2))
627 + .build();
628 +
629 + TrafficSelector expectOf3Selector = DefaultTrafficSelector.builder(ipPrefixSelector)
630 + .matchInPort(PortNumber.portNumber(1))
631 + .build();
632 +
633 + TrafficTreatment expectOf3Treatment = DefaultTrafficTreatment.builder(ethDstTreatment)
634 + .setOutput(PortNumber.portNumber(2))
635 + .build();
636 +
637 + TrafficSelector expectOf4Selector = DefaultTrafficSelector.builder(ipPrefixSelector)
638 + .matchEthDst(MacAddress.valueOf("C0:FF:EE:C0:FF:EE"))
639 + .matchInPort(PortNumber.portNumber(1))
640 + .build();
641 +
642 + TrafficTreatment expectOf4Treatment = DefaultTrafficTreatment.builder()
643 + .setOutput(PortNumber.portNumber(2))
644 + .build();
645 +
646 + intent = LinkCollectionIntent.builder()
647 + .appId(APP_ID)
648 + .selector(ipPrefixSelector)
649 + .ingressPoints(ingress)
650 + .egressPoints(egress)
651 + .treatment(ethDstTreatment)
652 + .links(testlinks)
653 + .build();
654 +
655 + List<Intent> result = sut.compile(intent, Collections.emptyList());
656 +
657 + assertThat(result, is(notNullValue()));
658 + assertThat(result, hasSize(1));
659 +
660 + Intent resultIntent = result.get(0);
661 + assertThat(resultIntent, instanceOf(FlowRuleIntent.class));
662 +
663 + if (resultIntent instanceof FlowRuleIntent) {
664 + FlowRuleIntent frIntent = (FlowRuleIntent) resultIntent;
665 + assertThat(frIntent.flowRules(), hasSize(5));
666 +
667 + List<FlowRule> deviceFlowRules;
668 + FlowRule flowRule;
669 +
670 + // Of1
671 + deviceFlowRules = getFlowRulesByDevice(of1Id, frIntent.flowRules());
672 + assertThat(deviceFlowRules, hasSize(1));
673 + flowRule = deviceFlowRules.get(0);
674 + assertThat(flowRule.selector(), is(expectOf1Selector));
675 + assertThat(flowRule.treatment(), is(expectOf1Treatment));
676 +
677 + // Of2 (has 2 flows)
678 + deviceFlowRules = getFlowRulesByDevice(of2Id, frIntent.flowRules());
679 + assertThat(deviceFlowRules, hasSize(2));
680 + flowRule = deviceFlowRules.get(0);
681 + assertThat(flowRule.selector(), is(expectOf2Selector1));
682 + assertThat(flowRule.treatment(), is(expectOf2Treatment));
683 + flowRule = deviceFlowRules.get(1);
684 + assertThat(flowRule.selector(), is(expectOf2Selector2));
685 + assertThat(flowRule.treatment(), is(expectOf2Treatment));
686 +
687 + // Of3
688 + deviceFlowRules = getFlowRulesByDevice(of3Id, frIntent.flowRules());
689 + assertThat(deviceFlowRules, hasSize(1));
690 + flowRule = deviceFlowRules.get(0);
691 + assertThat(flowRule.selector(), is(expectOf3Selector));
692 + assertThat(flowRule.treatment(), is(expectOf3Treatment));
693 +
694 + // Of4
695 + deviceFlowRules = getFlowRulesByDevice(of4Id, frIntent.flowRules());
696 + assertThat(deviceFlowRules, hasSize(1));
697 + flowRule = deviceFlowRules.get(0);
698 + assertThat(flowRule.selector(), is(expectOf4Selector));
699 + assertThat(flowRule.treatment(), is(expectOf4Treatment));
558 } 700 }
559 701
702 + sut.deactivate();
703 + }
560 } 704 }
......
...@@ -15,15 +15,15 @@ ...@@ -15,15 +15,15 @@
15 */ 15 */
16 package org.onosproject.net.intent.impl.compiler; 16 package org.onosproject.net.intent.impl.compiler;
17 17
18 +import com.google.common.collect.ImmutableSet;
18 import org.hamcrest.Matchers; 19 import org.hamcrest.Matchers;
19 import org.junit.Test; 20 import org.junit.Test;
21 +import org.onlab.packet.VlanId;
20 import org.onosproject.TestApplicationId; 22 import org.onosproject.TestApplicationId;
21 import org.onosproject.core.ApplicationId; 23 import org.onosproject.core.ApplicationId;
22 import org.onosproject.net.ConnectPoint; 24 import org.onosproject.net.ConnectPoint;
23 -import org.onosproject.net.DeviceId; 25 +import org.onosproject.net.FilteredConnectPoint;
24 -import org.onosproject.net.ElementId; 26 +import org.onosproject.net.flow.DefaultTrafficSelector;
25 -import org.onosproject.net.Path;
26 -import org.onosproject.net.device.DeviceServiceAdapter;
27 import org.onosproject.net.flow.TrafficSelector; 27 import org.onosproject.net.flow.TrafficSelector;
28 import org.onosproject.net.flow.TrafficTreatment; 28 import org.onosproject.net.flow.TrafficTreatment;
29 import org.onosproject.net.intent.AbstractIntentTest; 29 import org.onosproject.net.intent.AbstractIntentTest;
...@@ -31,7 +31,6 @@ import org.onosproject.net.intent.Intent; ...@@ -31,7 +31,6 @@ import org.onosproject.net.intent.Intent;
31 import org.onosproject.net.intent.IntentTestsMocks; 31 import org.onosproject.net.intent.IntentTestsMocks;
32 import org.onosproject.net.intent.LinkCollectionIntent; 32 import org.onosproject.net.intent.LinkCollectionIntent;
33 import org.onosproject.net.intent.MultiPointToSinglePointIntent; 33 import org.onosproject.net.intent.MultiPointToSinglePointIntent;
34 -import org.onosproject.net.topology.PathServiceAdapter;
35 34
36 import java.util.HashSet; 35 import java.util.HashSet;
37 import java.util.List; 36 import java.util.List;
...@@ -43,7 +42,6 @@ import static org.hamcrest.MatcherAssert.assertThat; ...@@ -43,7 +42,6 @@ import static org.hamcrest.MatcherAssert.assertThat;
43 import static org.hamcrest.Matchers.hasSize; 42 import static org.hamcrest.Matchers.hasSize;
44 import static org.hamcrest.Matchers.is; 43 import static org.hamcrest.Matchers.is;
45 import static org.onosproject.net.NetTestTools.connectPoint; 44 import static org.onosproject.net.NetTestTools.connectPoint;
46 -import static org.onosproject.net.NetTestTools.createPath;
47 import static org.onosproject.net.intent.LinksHaveEntryWithSourceDestinationPairMatcher.linksHasPath; 45 import static org.onosproject.net.intent.LinksHaveEntryWithSourceDestinationPairMatcher.linksHasPath;
48 46
49 /** 47 /**
...@@ -57,47 +55,6 @@ public class MultiPointToSinglePointIntentCompilerTest extends AbstractIntentTes ...@@ -57,47 +55,6 @@ public class MultiPointToSinglePointIntentCompilerTest extends AbstractIntentTes
57 private TrafficTreatment treatment = new IntentTestsMocks.MockTreatment(); 55 private TrafficTreatment treatment = new IntentTestsMocks.MockTreatment();
58 56
59 /** 57 /**
60 - * Mock path service for creating paths within the test.
61 - */
62 - private static class MockPathService extends PathServiceAdapter {
63 -
64 - final String[] pathHops;
65 -
66 - /**
67 - * Constructor that provides a set of hops to mock.
68 - *
69 - * @param pathHops path hops to mock
70 - */
71 - MockPathService(String[] pathHops) {
72 - this.pathHops = pathHops;
73 - }
74 -
75 - @Override
76 - public Set<Path> getPaths(ElementId src, ElementId dst) {
77 - Set<Path> result = new HashSet<>();
78 -
79 - String[] allHops = new String[pathHops.length + 1];
80 - allHops[0] = src.toString();
81 - if (pathHops.length != 0) {
82 - System.arraycopy(pathHops, 0, allHops, 1, pathHops.length);
83 - }
84 - result.add(createPath(allHops));
85 -
86 - return result;
87 - }
88 - }
89 -
90 - /**
91 - * Mocks the device service so that a device appears available in the test.
92 - */
93 - private static class MockDeviceService extends DeviceServiceAdapter {
94 - @Override
95 - public boolean isAvailable(DeviceId deviceId) {
96 - return true;
97 - }
98 - }
99 -
100 - /**
101 * Creates a MultiPointToSinglePoint intent for a group of ingress points 58 * Creates a MultiPointToSinglePoint intent for a group of ingress points
102 * and an egress point. 59 * and an egress point.
103 * 60 *
...@@ -123,6 +80,23 @@ public class MultiPointToSinglePointIntentCompilerTest extends AbstractIntentTes ...@@ -123,6 +80,23 @@ public class MultiPointToSinglePointIntentCompilerTest extends AbstractIntentTes
123 } 80 }
124 81
125 /** 82 /**
83 + * Generate MultiPointToSinglePointIntent with filtered connection point.
84 + *
85 + * @param ingress filtered ingress points
86 + * @param egress filtered egress point
87 + * @return
88 + */
89 + private MultiPointToSinglePointIntent makeFilteredConnectPointIntent(Set<FilteredConnectPoint> ingress,
90 + FilteredConnectPoint egress) {
91 + return MultiPointToSinglePointIntent.builder()
92 + .appId(APPID)
93 + .treatment(treatment)
94 + .filteredIngressPoints(ingress)
95 + .filteredEgressPoint(egress)
96 + .build();
97 + }
98 +
99 + /**
126 * Creates a compiler for MultiPointToSinglePoint intents. 100 * Creates a compiler for MultiPointToSinglePoint intents.
127 * 101 *
128 * @param hops hops to use while computing paths for this intent 102 * @param hops hops to use while computing paths for this intent
...@@ -131,8 +105,8 @@ public class MultiPointToSinglePointIntentCompilerTest extends AbstractIntentTes ...@@ -131,8 +105,8 @@ public class MultiPointToSinglePointIntentCompilerTest extends AbstractIntentTes
131 private MultiPointToSinglePointIntentCompiler makeCompiler(String[] hops) { 105 private MultiPointToSinglePointIntentCompiler makeCompiler(String[] hops) {
132 MultiPointToSinglePointIntentCompiler compiler = 106 MultiPointToSinglePointIntentCompiler compiler =
133 new MultiPointToSinglePointIntentCompiler(); 107 new MultiPointToSinglePointIntentCompiler();
134 - compiler.pathService = new MockPathService(hops); 108 + compiler.pathService = new IntentTestsMocks.Mp2MpMockPathService(hops);
135 - compiler.deviceService = new MockDeviceService(); 109 + compiler.deviceService = new IntentTestsMocks.MockDeviceService();
136 return compiler; 110 return compiler;
137 } 111 }
138 112
...@@ -148,8 +122,7 @@ public class MultiPointToSinglePointIntentCompilerTest extends AbstractIntentTes ...@@ -148,8 +122,7 @@ public class MultiPointToSinglePointIntentCompilerTest extends AbstractIntentTes
148 MultiPointToSinglePointIntent intent = makeIntent(ingress, egress); 122 MultiPointToSinglePointIntent intent = makeIntent(ingress, egress);
149 assertThat(intent, is(notNullValue())); 123 assertThat(intent, is(notNullValue()));
150 124
151 - String[] hops = {"h1", "h2", "h3", "h4", "h5", "h6", "h7", "h8", 125 + String[] hops = {"h1", "h2", "h3", "h4", "h5", "h6", "h7", "h8"};
152 - egress};
153 MultiPointToSinglePointIntentCompiler compiler = makeCompiler(hops); 126 MultiPointToSinglePointIntentCompiler compiler = makeCompiler(hops);
154 assertThat(compiler, is(notNullValue())); 127 assertThat(compiler, is(notNullValue()));
155 128
...@@ -184,7 +157,7 @@ public class MultiPointToSinglePointIntentCompilerTest extends AbstractIntentTes ...@@ -184,7 +157,7 @@ public class MultiPointToSinglePointIntentCompilerTest extends AbstractIntentTes
184 MultiPointToSinglePointIntent intent = makeIntent(ingress, egress); 157 MultiPointToSinglePointIntent intent = makeIntent(ingress, egress);
185 assertThat(intent, is(notNullValue())); 158 assertThat(intent, is(notNullValue()));
186 159
187 - final String[] hops = {"inner1", "inner2", egress}; 160 + final String[] hops = {"inner1", "inner2"};
188 MultiPointToSinglePointIntentCompiler compiler = makeCompiler(hops); 161 MultiPointToSinglePointIntentCompiler compiler = makeCompiler(hops);
189 assertThat(compiler, is(notNullValue())); 162 assertThat(compiler, is(notNullValue()));
190 163
...@@ -217,7 +190,7 @@ public class MultiPointToSinglePointIntentCompilerTest extends AbstractIntentTes ...@@ -217,7 +190,7 @@ public class MultiPointToSinglePointIntentCompilerTest extends AbstractIntentTes
217 MultiPointToSinglePointIntent intent = makeIntent(ingress, egress); 190 MultiPointToSinglePointIntent intent = makeIntent(ingress, egress);
218 assertThat(intent, is(notNullValue())); 191 assertThat(intent, is(notNullValue()));
219 192
220 - final String[] hops = {"n1", egress}; 193 + final String[] hops = {"n1"};
221 MultiPointToSinglePointIntentCompiler compiler = makeCompiler(hops); 194 MultiPointToSinglePointIntentCompiler compiler = makeCompiler(hops);
222 assertThat(compiler, is(notNullValue())); 195 assertThat(compiler, is(notNullValue()));
223 196
...@@ -245,12 +218,12 @@ public class MultiPointToSinglePointIntentCompilerTest extends AbstractIntentTes ...@@ -245,12 +218,12 @@ public class MultiPointToSinglePointIntentCompilerTest extends AbstractIntentTes
245 @Test 218 @Test
246 public void testSameDeviceCompilation() { 219 public void testSameDeviceCompilation() {
247 String[] ingress = {"i1", "i2"}; 220 String[] ingress = {"i1", "i2"};
248 - String egress = "i1"; 221 + String egress = "i3";
249 222
250 MultiPointToSinglePointIntent intent = makeIntent(ingress, egress); 223 MultiPointToSinglePointIntent intent = makeIntent(ingress, egress);
251 assertThat(intent, is(notNullValue())); 224 assertThat(intent, is(notNullValue()));
252 225
253 - final String[] hops = {"i1", "i2"}; 226 + final String[] hops = {};
254 MultiPointToSinglePointIntentCompiler compiler = makeCompiler(hops); 227 MultiPointToSinglePointIntentCompiler compiler = makeCompiler(hops);
255 assertThat(compiler, is(notNullValue())); 228 assertThat(compiler, is(notNullValue()));
256 229
...@@ -264,7 +237,48 @@ public class MultiPointToSinglePointIntentCompilerTest extends AbstractIntentTes ...@@ -264,7 +237,48 @@ public class MultiPointToSinglePointIntentCompilerTest extends AbstractIntentTes
264 LinkCollectionIntent linkIntent = (LinkCollectionIntent) resultIntent; 237 LinkCollectionIntent linkIntent = (LinkCollectionIntent) resultIntent;
265 assertThat(linkIntent.links(), hasSize(ingress.length)); 238 assertThat(linkIntent.links(), hasSize(ingress.length));
266 239
267 - assertThat(linkIntent.links(), linksHasPath("i2", "i1")); 240 + assertThat(linkIntent.links(), linksHasPath("i1", "i3"));
241 + assertThat(linkIntent.links(), linksHasPath("i2", "i3"));
268 } 242 }
269 } 243 }
244 +
245 + /**
246 + * Tests filtered ingress and egress.
247 + */
248 + @Test
249 + public void testFilteredConnectPointIntent() {
250 +
251 + Set<FilteredConnectPoint> ingress = ImmutableSet.of(
252 + new FilteredConnectPoint(connectPoint("of1", 1),
253 + DefaultTrafficSelector.builder().matchVlanId(VlanId.vlanId("100")).build()),
254 + new FilteredConnectPoint(connectPoint("of2", 1),
255 + DefaultTrafficSelector.builder().matchVlanId(VlanId.vlanId("200")).build())
256 + );
257 +
258 + FilteredConnectPoint egress = new FilteredConnectPoint(connectPoint("of4", 1));
259 +
260 + MultiPointToSinglePointIntent intent = makeFilteredConnectPointIntent(ingress, egress);
261 + String[] hops = {"of3"};
262 +
263 + MultiPointToSinglePointIntentCompiler compiler = makeCompiler(hops);
264 + assertThat(compiler, is(notNullValue()));
265 +
266 + List<Intent> result = compiler.compile(intent, null);
267 + assertThat(result, is(notNullValue()));
268 + assertThat(result, hasSize(1));
269 +
270 + Intent resultIntent = result.get(0);
271 + assertThat(resultIntent, instanceOf(LinkCollectionIntent.class));
272 +
273 + if (resultIntent instanceof LinkCollectionIntent) {
274 + LinkCollectionIntent linkIntent = (LinkCollectionIntent) resultIntent;
275 + assertThat(linkIntent.links(), hasSize(3));
276 + assertThat(linkIntent.links(), linksHasPath("of1", "of3"));
277 + assertThat(linkIntent.links(), linksHasPath("of2", "of3"));
278 + assertThat(linkIntent.links(), linksHasPath("of3", "of4"));
279 + }
280 +
281 + }
282 +
283 +
270 } 284 }
......
1 +/*
2 + * Copyright 2016-present Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.net.intent.impl.compiler;
18 +
19 +import com.google.common.collect.ImmutableSet;
20 +import org.hamcrest.Matchers;
21 +import org.junit.Test;
22 +import org.onlab.packet.VlanId;
23 +import org.onosproject.TestApplicationId;
24 +import org.onosproject.core.ApplicationId;
25 +import org.onosproject.net.ConnectPoint;
26 +import org.onosproject.net.FilteredConnectPoint;
27 +import org.onosproject.net.flow.DefaultTrafficSelector;
28 +import org.onosproject.net.flow.TrafficSelector;
29 +import org.onosproject.net.flow.TrafficTreatment;
30 +import org.onosproject.net.intent.AbstractIntentTest;
31 +import org.onosproject.net.intent.Intent;
32 +import org.onosproject.net.intent.IntentTestsMocks;
33 +import org.onosproject.net.intent.LinkCollectionIntent;
34 +import org.onosproject.net.intent.SinglePointToMultiPointIntent;
35 +
36 +import java.util.HashSet;
37 +import java.util.List;
38 +import java.util.Set;
39 +
40 +import static org.hamcrest.CoreMatchers.instanceOf;
41 +import static org.hamcrest.CoreMatchers.notNullValue;
42 +import static org.hamcrest.MatcherAssert.assertThat;
43 +import static org.hamcrest.Matchers.hasSize;
44 +import static org.hamcrest.Matchers.is;
45 +import static org.onosproject.net.NetTestTools.connectPoint;
46 +import static org.onosproject.net.intent.LinksHaveEntryWithSourceDestinationPairMatcher.linksHasPath;
47 +
48 +/**
49 + * Unit tests for SinglePointToMultiPointIntentCompiler.
50 + */
51 +public class SinglePointToMultiPointIntentCompilerTest extends AbstractIntentTest {
52 +
53 + private static final ApplicationId APPID = new TestApplicationId("foo");
54 +
55 + private TrafficSelector selector = new IntentTestsMocks.MockSelector();
56 + private TrafficTreatment treatment = new IntentTestsMocks.MockTreatment();
57 +
58 +
59 +
60 + /**
61 + * Creates a SinglePointToMultiPoint intent for an ingress point
62 + * and a group of egress points.
63 + *
64 + * @param ingressId device id of the ingress point
65 + * @param egressIds array of egress device ids
66 + * @return MultiPointToSinglePoint intent
67 + */
68 + private SinglePointToMultiPointIntent makeIntent(String ingressId, String[] egressIds) {
69 + ConnectPoint ingressPoint = connectPoint(ingressId, 2);
70 + Set<ConnectPoint> egressPoints = new HashSet<>();
71 +
72 +
73 + for (String egressId : egressIds) {
74 + egressPoints.add(connectPoint(egressId, 1));
75 + }
76 +
77 + return SinglePointToMultiPointIntent.builder()
78 + .appId(APPID)
79 + .selector(selector)
80 + .treatment(treatment)
81 + .ingressPoint(ingressPoint)
82 + .egressPoints(egressPoints)
83 + .build();
84 + }
85 +
86 + /**
87 + * Generate SinglePointToMultiPointIntent with filtered connection point.
88 + *
89 + * @param ingress filtered ingress point
90 + * @param egress filtered egress point
91 + * @return
92 + */
93 + private SinglePointToMultiPointIntent makeFilteredConnectPointIntent(FilteredConnectPoint ingress,
94 + Set<FilteredConnectPoint> egress) {
95 + return SinglePointToMultiPointIntent.builder()
96 + .appId(APPID)
97 + .treatment(treatment)
98 + .filteredIngressPoint(ingress)
99 + .filteredEgressPoints(egress)
100 + .build();
101 + }
102 +
103 + /**
104 + * Creates a compiler for SinglePointToMultiPoint intents.
105 + *
106 + * @param hops hops to use while computing paths for this intent
107 + * @return SinglePointToMultiPoint intent
108 + */
109 + private SinglePointToMultiPointIntentCompiler makeCompiler(String[] hops) {
110 + SinglePointToMultiPointIntentCompiler compiler =
111 + new SinglePointToMultiPointIntentCompiler();
112 +
113 + compiler.pathService = new IntentTestsMocks.Mp2MpMockPathService(hops);
114 + return compiler;
115 + }
116 +
117 + /**
118 + * Tests a single ingress point with 8 hops to its egress point.
119 + */
120 + @Test
121 + public void testSingleLongPathCompilation() {
122 +
123 + String ingress = "ingress";
124 + String[] egress = {"egress"};
125 +
126 + SinglePointToMultiPointIntent intent = makeIntent(ingress, egress);
127 + assertThat(intent, is(notNullValue()));
128 +
129 + String[] hops = {"h1", "h2", "h3", "h4", "h5", "h6", "h7", "h8"};
130 + SinglePointToMultiPointIntentCompiler compiler = makeCompiler(hops);
131 + assertThat(compiler, is(notNullValue()));
132 +
133 + List<Intent> result = compiler.compile(intent, null);
134 + assertThat(result, is(Matchers.notNullValue()));
135 + assertThat(result, hasSize(1));
136 + Intent resultIntent = result.get(0);
137 + assertThat(resultIntent instanceof LinkCollectionIntent, is(true));
138 +
139 + if (resultIntent instanceof LinkCollectionIntent) {
140 + LinkCollectionIntent linkIntent = (LinkCollectionIntent) resultIntent;
141 + assertThat(linkIntent.links(), hasSize(9));
142 + assertThat(linkIntent.links(), linksHasPath("ingress", "h1"));
143 + assertThat(linkIntent.links(), linksHasPath("h1", "h2"));
144 + assertThat(linkIntent.links(), linksHasPath("h2", "h3"));
145 + assertThat(linkIntent.links(), linksHasPath("h4", "h5"));
146 + assertThat(linkIntent.links(), linksHasPath("h5", "h6"));
147 + assertThat(linkIntent.links(), linksHasPath("h7", "h8"));
148 + assertThat(linkIntent.links(), linksHasPath("h8", "egress"));
149 + }
150 + }
151 +
152 + /**
153 + * Tests a simple topology where two egress points share some path segments
154 + * and some path segments are not shared.
155 + */
156 + @Test
157 + public void testTwoIngressCompilation() {
158 + String ingress = "ingress";
159 + String[] egress = {"egress1", "egress2"};
160 +
161 + SinglePointToMultiPointIntent intent = makeIntent(ingress, egress);
162 + assertThat(intent, is(notNullValue()));
163 +
164 + final String[] hops = {"inner1", "inner2"};
165 + SinglePointToMultiPointIntentCompiler compiler = makeCompiler(hops);
166 + assertThat(compiler, is(notNullValue()));
167 +
168 + List<Intent> result = compiler.compile(intent, null);
169 + assertThat(result, is(notNullValue()));
170 + assertThat(result, hasSize(1));
171 + Intent resultIntent = result.get(0);
172 + assertThat(resultIntent instanceof LinkCollectionIntent, is(true));
173 +
174 + if (resultIntent instanceof LinkCollectionIntent) {
175 + LinkCollectionIntent linkIntent = (LinkCollectionIntent) resultIntent;
176 + assertThat(linkIntent.links(), hasSize(4));
177 + assertThat(linkIntent.links(), linksHasPath("ingress", "inner1"));
178 + assertThat(linkIntent.links(), linksHasPath("inner1", "inner2"));
179 + assertThat(linkIntent.links(), linksHasPath("inner2", "egress1"));
180 + assertThat(linkIntent.links(), linksHasPath("inner2", "egress2"));
181 + }
182 + }
183 +
184 + /**
185 + * Tests a large number of ingress points that share a common path to the
186 + * egress point.
187 + */
188 + @Test
189 + public void testMultiIngressCompilation() {
190 + String ingress = "i";
191 + String[] egress = {"e1", "e2", "e3", "e4", "e5",
192 + "e6", "e7", "e8", "e9", "e10"};
193 +
194 + SinglePointToMultiPointIntent intent = makeIntent(ingress, egress);
195 + assertThat(intent, is(notNullValue()));
196 +
197 + final String[] hops = {"n1"};
198 + SinglePointToMultiPointIntentCompiler compiler = makeCompiler(hops);
199 + assertThat(compiler, is(notNullValue()));
200 +
201 + List<Intent> result = compiler.compile(intent, null);
202 + assertThat(result, is(notNullValue()));
203 + assertThat(result, hasSize(1));
204 + Intent resultIntent = result.get(0);
205 + assertThat(resultIntent instanceof LinkCollectionIntent, is(true));
206 +
207 + if (resultIntent instanceof LinkCollectionIntent) {
208 + LinkCollectionIntent linkIntent = (LinkCollectionIntent) resultIntent;
209 + assertThat(linkIntent.links(), hasSize(egress.length + 1));
210 + for (String egressToCheck : egress) {
211 + assertThat(linkIntent.links(), linksHasPath("n1", egressToCheck));
212 + }
213 + assertThat(linkIntent.links(), linksHasPath(ingress, "n1"));
214 + }
215 + }
216 +
217 + /**
218 + * Tests ingress and egress on the same device.
219 + */
220 + @Test
221 + public void testSameDeviceCompilation() {
222 + String ingress = "i1";
223 + String[] egress = {"i2", "i3"};
224 +
225 + SinglePointToMultiPointIntent intent = makeIntent(ingress, egress);
226 + assertThat(intent, is(notNullValue()));
227 +
228 + final String[] hops = {};
229 + SinglePointToMultiPointIntentCompiler compiler = makeCompiler(hops);
230 + assertThat(compiler, is(notNullValue()));
231 +
232 + List<Intent> result = compiler.compile(intent, null);
233 + assertThat(result, is(notNullValue()));
234 + assertThat(result, hasSize(1));
235 + Intent resultIntent = result.get(0);
236 + assertThat(resultIntent, instanceOf(LinkCollectionIntent.class));
237 +
238 + if (resultIntent instanceof LinkCollectionIntent) {
239 + LinkCollectionIntent linkIntent = (LinkCollectionIntent) resultIntent;
240 + assertThat(linkIntent.links(), hasSize(egress.length));
241 +
242 + assertThat(linkIntent.links(), linksHasPath("i1", "i2"));
243 + assertThat(linkIntent.links(), linksHasPath("i1", "i3"));
244 + }
245 + }
246 +
247 + /**
248 + * Tests filtered ingress and egress.
249 + */
250 + @Test
251 + public void testFilteredConnectPointIntent() {
252 +
253 + FilteredConnectPoint ingress = new FilteredConnectPoint(connectPoint("of1", 1));
254 +
255 + Set<FilteredConnectPoint> egress = ImmutableSet.of(
256 + new FilteredConnectPoint(connectPoint("of3", 1),
257 + DefaultTrafficSelector.builder().matchVlanId(VlanId.vlanId("100")).build()),
258 + new FilteredConnectPoint(connectPoint("of4", 1),
259 + DefaultTrafficSelector.builder().matchVlanId(VlanId.vlanId("200")).build())
260 + );
261 +
262 +
263 + SinglePointToMultiPointIntent intent = makeFilteredConnectPointIntent(ingress, egress);
264 + String[] hops = {"of2"};
265 +
266 + SinglePointToMultiPointIntentCompiler compiler = makeCompiler(hops);
267 + assertThat(compiler, is(notNullValue()));
268 +
269 + List<Intent> result = compiler.compile(intent, null);
270 + assertThat(result, is(notNullValue()));
271 + assertThat(result, hasSize(1));
272 +
273 + Intent resultIntent = result.get(0);
274 + assertThat(resultIntent, instanceOf(LinkCollectionIntent.class));
275 +
276 + if (resultIntent instanceof LinkCollectionIntent) {
277 + LinkCollectionIntent linkIntent = (LinkCollectionIntent) resultIntent;
278 + assertThat(linkIntent.links(), hasSize(3));
279 +
280 + assertThat(linkIntent.links(), linksHasPath("of1", "of2"));
281 + assertThat(linkIntent.links(), linksHasPath("of2", "of3"));
282 + assertThat(linkIntent.links(), linksHasPath("of2", "of4"));
283 +
284 + Set<FilteredConnectPoint> ingressPoints = linkIntent.filteredIngressPoints();
285 + assertThat("Link collection ingress points do not match base intent",
286 + ingressPoints.size() == 1 && ingressPoints.contains(intent.filteredIngressPoint()));
287 +
288 + assertThat("Link collection egress points do not match base intent",
289 + linkIntent.filteredEgressPoints().equals(intent.filteredEgressPoints()));
290 + }
291 +
292 + }
293 +}