[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