[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 | +} |
-
Please register or login to post a comment