Committed by
Gerrit Code Review
Support [ONOS-4593] and implement [ONOS-4594]
Changes: - Adds extension to sp2mp intents; - Adds extension to linkcollection intents; - Adds extension to sp2mp compiler; - Adds extension to linkcollection compiler; - Adds re-ordering of the actions; - Adds unit tests for both sp2mp intents and linkcollection intents; Change-Id: Ib925e9066682e077a0bb4bbfd20a4382623b7541
Showing
8 changed files
with
245 additions
and
26 deletions
| ... | @@ -16,19 +16,20 @@ | ... | @@ -16,19 +16,20 @@ |
| 16 | 16 | ||
| 17 | package org.onosproject.net.intent; | 17 | package org.onosproject.net.intent; |
| 18 | 18 | ||
| 19 | +import java.util.List; | ||
| 20 | +import java.util.Map; | ||
| 21 | +import java.util.Set; | ||
| 22 | + | ||
| 19 | import com.google.common.annotations.Beta; | 23 | import com.google.common.annotations.Beta; |
| 20 | -import com.google.common.base.MoreObjects; | ||
| 21 | import com.google.common.collect.ImmutableMap; | 24 | import com.google.common.collect.ImmutableMap; |
| 22 | -import com.google.common.collect.ImmutableSet; | ||
| 23 | import org.onosproject.core.ApplicationId; | 25 | import org.onosproject.core.ApplicationId; |
| 24 | import org.onosproject.net.ConnectPoint; | 26 | import org.onosproject.net.ConnectPoint; |
| 25 | import org.onosproject.net.Link; | 27 | import org.onosproject.net.Link; |
| 26 | import org.onosproject.net.flow.TrafficSelector; | 28 | import org.onosproject.net.flow.TrafficSelector; |
| 27 | import org.onosproject.net.flow.TrafficTreatment; | 29 | import org.onosproject.net.flow.TrafficTreatment; |
| 28 | 30 | ||
| 29 | -import java.util.List; | 31 | +import com.google.common.base.MoreObjects; |
| 30 | -import java.util.Map; | 32 | +import com.google.common.collect.ImmutableSet; |
| 31 | -import java.util.Set; | ||
| 32 | 33 | ||
| 33 | /** | 34 | /** |
| 34 | * Abstraction of a connectivity intent that is implemented by a set of path | 35 | * Abstraction of a connectivity intent that is implemented by a set of path |
| ... | @@ -41,12 +42,15 @@ public final class LinkCollectionIntent extends ConnectivityIntent { | ... | @@ -41,12 +42,15 @@ public final class LinkCollectionIntent extends ConnectivityIntent { |
| 41 | 42 | ||
| 42 | private final Set<ConnectPoint> ingressPoints; | 43 | private final Set<ConnectPoint> ingressPoints; |
| 43 | private final Set<ConnectPoint> egressPoints; | 44 | private final Set<ConnectPoint> egressPoints; |
| 45 | + private final boolean egressTreatmentFlag; | ||
| 44 | /** | 46 | /** |
| 45 | * To manage multiple selectors use case. | 47 | * To manage multiple selectors use case. |
| 46 | */ | 48 | */ |
| 47 | private final Map<ConnectPoint, TrafficSelector> ingressSelectors; | 49 | private final Map<ConnectPoint, TrafficSelector> ingressSelectors; |
| 48 | - | 50 | + /** |
| 49 | - private final boolean egressTreatmentFlag; | 51 | + * To manage multiple treatments use case. |
| 52 | + */ | ||
| 53 | + private final Map<ConnectPoint, TrafficTreatment> egressTreatments; | ||
| 50 | 54 | ||
| 51 | /** | 55 | /** |
| 52 | * Creates a new actionable intent capable of funneling the selected | 56 | * Creates a new actionable intent capable of funneling the selected |
| ... | @@ -64,6 +68,7 @@ public final class LinkCollectionIntent extends ConnectivityIntent { | ... | @@ -64,6 +68,7 @@ public final class LinkCollectionIntent extends ConnectivityIntent { |
| 64 | * @param priority priority to use for the flows generated by this intent | 68 | * @param priority priority to use for the flows generated by this intent |
| 65 | * @param egressTreatment true if treatment should be applied by the egress device | 69 | * @param egressTreatment true if treatment should be applied by the egress device |
| 66 | * @param ingressSelectors map to store the association ingress to selector | 70 | * @param ingressSelectors map to store the association ingress to selector |
| 71 | + * @param egressTreatments map to store the association egress to treatment | ||
| 67 | * @throws NullPointerException {@code path} is null | 72 | * @throws NullPointerException {@code path} is null |
| 68 | */ | 73 | */ |
| 69 | private LinkCollectionIntent(ApplicationId appId, | 74 | private LinkCollectionIntent(ApplicationId appId, |
| ... | @@ -76,13 +81,15 @@ public final class LinkCollectionIntent extends ConnectivityIntent { | ... | @@ -76,13 +81,15 @@ public final class LinkCollectionIntent extends ConnectivityIntent { |
| 76 | List<Constraint> constraints, | 81 | List<Constraint> constraints, |
| 77 | int priority, | 82 | int priority, |
| 78 | boolean egressTreatment, | 83 | boolean egressTreatment, |
| 79 | - Map<ConnectPoint, TrafficSelector> ingressSelectors) { | 84 | + Map<ConnectPoint, TrafficSelector> ingressSelectors, |
| 85 | + Map<ConnectPoint, TrafficTreatment> egressTreatments) { | ||
| 80 | super(appId, key, resources(links), selector, treatment, constraints, priority); | 86 | super(appId, key, resources(links), selector, treatment, constraints, priority); |
| 81 | this.links = links; | 87 | this.links = links; |
| 82 | this.ingressPoints = ingressPoints; | 88 | this.ingressPoints = ingressPoints; |
| 83 | this.egressPoints = egressPoints; | 89 | this.egressPoints = egressPoints; |
| 84 | this.egressTreatmentFlag = egressTreatment; | 90 | this.egressTreatmentFlag = egressTreatment; |
| 85 | this.ingressSelectors = ingressSelectors; | 91 | this.ingressSelectors = ingressSelectors; |
| 92 | + this.egressTreatments = egressTreatments; | ||
| 86 | } | 93 | } |
| 87 | 94 | ||
| 88 | /** | 95 | /** |
| ... | @@ -95,6 +102,7 @@ public final class LinkCollectionIntent extends ConnectivityIntent { | ... | @@ -95,6 +102,7 @@ public final class LinkCollectionIntent extends ConnectivityIntent { |
| 95 | this.egressPoints = null; | 102 | this.egressPoints = null; |
| 96 | this.egressTreatmentFlag = false; | 103 | this.egressTreatmentFlag = false; |
| 97 | this.ingressSelectors = null; | 104 | this.ingressSelectors = null; |
| 105 | + this.egressTreatments = null; | ||
| 98 | } | 106 | } |
| 99 | 107 | ||
| 100 | /** | 108 | /** |
| ... | @@ -117,6 +125,7 @@ public final class LinkCollectionIntent extends ConnectivityIntent { | ... | @@ -117,6 +125,7 @@ public final class LinkCollectionIntent extends ConnectivityIntent { |
| 117 | Set<ConnectPoint> ingressPoints; | 125 | Set<ConnectPoint> ingressPoints; |
| 118 | Set<ConnectPoint> egressPoints; | 126 | Set<ConnectPoint> egressPoints; |
| 119 | Map<ConnectPoint, TrafficSelector> ingressSelectors = ImmutableMap.of(); | 127 | Map<ConnectPoint, TrafficSelector> ingressSelectors = ImmutableMap.of(); |
| 128 | + Map<ConnectPoint, TrafficTreatment> egressTreatments = ImmutableMap.of(); | ||
| 120 | boolean egressTreatmentFlag; | 129 | boolean egressTreatmentFlag; |
| 121 | 130 | ||
| 122 | private Builder() { | 131 | private Builder() { |
| ... | @@ -189,6 +198,17 @@ public final class LinkCollectionIntent extends ConnectivityIntent { | ... | @@ -189,6 +198,17 @@ public final class LinkCollectionIntent extends ConnectivityIntent { |
| 189 | } | 198 | } |
| 190 | 199 | ||
| 191 | /** | 200 | /** |
| 201 | + * Sets the map egress treatments to connection points of the intent. | ||
| 202 | + * | ||
| 203 | + * @param egressTreatments maps connection point to traffic treatment | ||
| 204 | + * @return this builder | ||
| 205 | + */ | ||
| 206 | + public Builder egressTreatments(Map<ConnectPoint, TrafficTreatment> egressTreatments) { | ||
| 207 | + this.egressTreatments = ImmutableMap.copyOf(egressTreatments); | ||
| 208 | + return this; | ||
| 209 | + } | ||
| 210 | + | ||
| 211 | + /** | ||
| 192 | * Sets the links of the link collection intent | 212 | * Sets the links of the link collection intent |
| 193 | * that will be built. | 213 | * that will be built. |
| 194 | * | 214 | * |
| ... | @@ -231,12 +251,12 @@ public final class LinkCollectionIntent extends ConnectivityIntent { | ... | @@ -231,12 +251,12 @@ public final class LinkCollectionIntent extends ConnectivityIntent { |
| 231 | constraints, | 251 | constraints, |
| 232 | priority, | 252 | priority, |
| 233 | egressTreatmentFlag, | 253 | egressTreatmentFlag, |
| 234 | - ingressSelectors | 254 | + ingressSelectors, |
| 255 | + egressTreatments | ||
| 235 | ); | 256 | ); |
| 236 | } | 257 | } |
| 237 | } | 258 | } |
| 238 | 259 | ||
| 239 | - | ||
| 240 | /** | 260 | /** |
| 241 | * Returns the set of links that represent the network connections needed | 261 | * Returns the set of links that represent the network connections needed |
| 242 | * by this intent. | 262 | * by this intent. |
| ... | @@ -274,6 +294,14 @@ public final class LinkCollectionIntent extends ConnectivityIntent { | ... | @@ -274,6 +294,14 @@ public final class LinkCollectionIntent extends ConnectivityIntent { |
| 274 | } | 294 | } |
| 275 | 295 | ||
| 276 | /** | 296 | /** |
| 297 | + * Returns the multiple treatments jointly with their connection points. | ||
| 298 | + * @return multiple treatments | ||
| 299 | + */ | ||
| 300 | + public Map<ConnectPoint, TrafficTreatment> egressTreatments() { | ||
| 301 | + return egressTreatments; | ||
| 302 | + } | ||
| 303 | + | ||
| 304 | + /** | ||
| 277 | * Returns whether treatment should be applied on egress. | 305 | * Returns whether treatment should be applied on egress. |
| 278 | * | 306 | * |
| 279 | * @return the egress treatment flag | 307 | * @return the egress treatment flag |
| ... | @@ -296,7 +324,8 @@ public final class LinkCollectionIntent extends ConnectivityIntent { | ... | @@ -296,7 +324,8 @@ public final class LinkCollectionIntent extends ConnectivityIntent { |
| 296 | .add("ingress", ingressPoints()) | 324 | .add("ingress", ingressPoints()) |
| 297 | .add("egress", egressPoints()) | 325 | .add("egress", egressPoints()) |
| 298 | .add("selectors", ingressSelectors()) | 326 | .add("selectors", ingressSelectors()) |
| 299 | - .add("treatmentOnEgress", applyTreatmentOnEgress()) | 327 | + .add("treatments", egressTreatments()) |
| 328 | + .add("treatementOnEgress", applyTreatmentOnEgress()) | ||
| 300 | .toString(); | 329 | .toString(); |
| 301 | } | 330 | } |
| 302 | } | 331 | } | ... | ... |
| ... | @@ -17,14 +17,18 @@ package org.onosproject.net.intent; | ... | @@ -17,14 +17,18 @@ 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.ImmutableList; | ||
| 21 | +import com.google.common.collect.ImmutableMap; | ||
| 20 | import com.google.common.collect.ImmutableSet; | 22 | import com.google.common.collect.ImmutableSet; |
| 21 | 23 | ||
| 24 | +import com.google.common.collect.Sets; | ||
| 22 | import org.onosproject.core.ApplicationId; | 25 | import org.onosproject.core.ApplicationId; |
| 23 | import org.onosproject.net.ConnectPoint; | 26 | import org.onosproject.net.ConnectPoint; |
| 27 | +import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
| 24 | import org.onosproject.net.flow.TrafficSelector; | 28 | import org.onosproject.net.flow.TrafficSelector; |
| 25 | import org.onosproject.net.flow.TrafficTreatment; | 29 | import org.onosproject.net.flow.TrafficTreatment; |
| 26 | 30 | ||
| 27 | -import java.util.Collections; | 31 | +import java.util.Map; |
| 28 | import java.util.Set; | 32 | import java.util.Set; |
| 29 | import java.util.List; | 33 | import java.util.List; |
| 30 | 34 | ||
| ... | @@ -39,6 +43,10 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent { | ... | @@ -39,6 +43,10 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent { |
| 39 | 43 | ||
| 40 | private final ConnectPoint ingressPoint; | 44 | private final ConnectPoint ingressPoint; |
| 41 | private final Set<ConnectPoint> egressPoints; | 45 | private final Set<ConnectPoint> egressPoints; |
| 46 | + /** | ||
| 47 | + * To manage multiple treatments use case. | ||
| 48 | + */ | ||
| 49 | + private final Map<ConnectPoint, TrafficTreatment> egressTreatments; | ||
| 42 | 50 | ||
| 43 | /** | 51 | /** |
| 44 | * Creates a new single-to-multi point connectivity intent. | 52 | * Creates a new single-to-multi point connectivity intent. |
| ... | @@ -51,27 +59,32 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent { | ... | @@ -51,27 +59,32 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent { |
| 51 | * @param egressPoints set of ports on which traffic will egress | 59 | * @param egressPoints set of ports on which traffic will egress |
| 52 | * @param constraints constraints to apply to the intent | 60 | * @param constraints constraints to apply to the intent |
| 53 | * @param priority priority to use for flows generated by this intent | 61 | * @param priority priority to use for flows generated by this intent |
| 62 | + * @param egressTreatments map to store the association egress to treatment | ||
| 54 | * @throws NullPointerException if {@code ingressPoint} or | 63 | * @throws NullPointerException if {@code ingressPoint} or |
| 55 | * {@code egressPoints} is null | 64 | * {@code egressPoints} is null |
| 56 | * @throws IllegalArgumentException if the size of {@code egressPoints} is | 65 | * @throws IllegalArgumentException if the size of {@code egressPoints} is |
| 57 | * not more than 1 | 66 | * not more than 1 |
| 58 | */ | 67 | */ |
| 59 | private SinglePointToMultiPointIntent(ApplicationId appId, | 68 | private SinglePointToMultiPointIntent(ApplicationId appId, |
| 60 | - Key key, | 69 | + Key key, |
| 61 | - TrafficSelector selector, TrafficTreatment treatment, | 70 | + TrafficSelector selector, |
| 62 | - ConnectPoint ingressPoint, Set<ConnectPoint> egressPoints, | 71 | + TrafficTreatment treatment, |
| 63 | - List<Constraint> constraints, | 72 | + ConnectPoint ingressPoint, |
| 64 | - int priority) { | 73 | + Set<ConnectPoint> egressPoints, |
| 65 | - super(appId, key, Collections.emptyList(), selector, treatment, constraints, | 74 | + List<Constraint> constraints, |
| 66 | - priority); | 75 | + int priority, |
| 76 | + Map<ConnectPoint, TrafficTreatment> egressTreatments) { | ||
| 77 | + super(appId, key, ImmutableList.of(), selector, treatment, constraints, | ||
| 78 | + priority); | ||
| 67 | checkNotNull(egressPoints); | 79 | checkNotNull(egressPoints); |
| 68 | checkNotNull(ingressPoint); | 80 | checkNotNull(ingressPoint); |
| 69 | checkArgument(!egressPoints.isEmpty(), "Egress point set cannot be empty"); | 81 | checkArgument(!egressPoints.isEmpty(), "Egress point set cannot be empty"); |
| 70 | checkArgument(!egressPoints.contains(ingressPoint), | 82 | checkArgument(!egressPoints.contains(ingressPoint), |
| 71 | "Set of egresses should not contain ingress (ingress: %s)", ingressPoint); | 83 | "Set of egresses should not contain ingress (ingress: %s)", ingressPoint); |
| 72 | 84 | ||
| 73 | - this.ingressPoint = checkNotNull(ingressPoint); | 85 | + this.ingressPoint = ingressPoint; |
| 74 | - this.egressPoints = egressPoints; | 86 | + this.egressPoints = Sets.newHashSet(egressPoints); |
| 87 | + this.egressTreatments = egressTreatments; | ||
| 75 | } | 88 | } |
| 76 | 89 | ||
| 77 | /** | 90 | /** |
| ... | @@ -92,6 +105,7 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent { | ... | @@ -92,6 +105,7 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent { |
| 92 | public static final class Builder extends ConnectivityIntent.Builder { | 105 | public static final class Builder extends ConnectivityIntent.Builder { |
| 93 | ConnectPoint ingressPoint; | 106 | ConnectPoint ingressPoint; |
| 94 | Set<ConnectPoint> egressPoints; | 107 | Set<ConnectPoint> egressPoints; |
| 108 | + Map<ConnectPoint, TrafficTreatment> egressTreatments = ImmutableMap.of(); | ||
| 95 | 109 | ||
| 96 | private Builder() { | 110 | private Builder() { |
| 97 | // Hide constructor | 111 | // Hide constructor |
| ... | @@ -152,6 +166,18 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent { | ... | @@ -152,6 +166,18 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent { |
| 152 | } | 166 | } |
| 153 | 167 | ||
| 154 | /** | 168 | /** |
| 169 | + * Sets the treatments of the single point to multi point intent | ||
| 170 | + * that will be built. | ||
| 171 | + * | ||
| 172 | + * @param egressTreatments the multiple treatments | ||
| 173 | + * @return this builder | ||
| 174 | + */ | ||
| 175 | + public Builder treatments(Map<ConnectPoint, TrafficTreatment> egressTreatments) { | ||
| 176 | + this.egressTreatments = ImmutableMap.copyOf(egressTreatments); | ||
| 177 | + return this; | ||
| 178 | + } | ||
| 179 | + | ||
| 180 | + /** | ||
| 155 | * Builds a single point to multi point intent from the | 181 | * Builds a single point to multi point intent from the |
| 156 | * accumulated parameters. | 182 | * accumulated parameters. |
| 157 | * | 183 | * |
| ... | @@ -159,6 +185,12 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent { | ... | @@ -159,6 +185,12 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent { |
| 159 | */ | 185 | */ |
| 160 | public SinglePointToMultiPointIntent build() { | 186 | public SinglePointToMultiPointIntent build() { |
| 161 | 187 | ||
| 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 | + | ||
| 162 | return new SinglePointToMultiPointIntent( | 194 | return new SinglePointToMultiPointIntent( |
| 163 | appId, | 195 | appId, |
| 164 | key, | 196 | key, |
| ... | @@ -167,7 +199,8 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent { | ... | @@ -167,7 +199,8 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent { |
| 167 | ingressPoint, | 199 | ingressPoint, |
| 168 | egressPoints, | 200 | egressPoints, |
| 169 | constraints, | 201 | constraints, |
| 170 | - priority | 202 | + priority, |
| 203 | + egressTreatments | ||
| 171 | ); | 204 | ); |
| 172 | } | 205 | } |
| 173 | } | 206 | } |
| ... | @@ -179,6 +212,7 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent { | ... | @@ -179,6 +212,7 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent { |
| 179 | super(); | 212 | super(); |
| 180 | this.ingressPoint = null; | 213 | this.ingressPoint = null; |
| 181 | this.egressPoints = null; | 214 | this.egressPoints = null; |
| 215 | + this.egressTreatments = null; | ||
| 182 | } | 216 | } |
| 183 | 217 | ||
| 184 | /** | 218 | /** |
| ... | @@ -200,6 +234,14 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent { | ... | @@ -200,6 +234,14 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent { |
| 200 | return egressPoints; | 234 | return egressPoints; |
| 201 | } | 235 | } |
| 202 | 236 | ||
| 237 | + /** | ||
| 238 | + * Returns the multiple treatments jointly with their connection points. | ||
| 239 | + * @return multiple treatments | ||
| 240 | + */ | ||
| 241 | + public Map<ConnectPoint, TrafficTreatment> egressTreatments() { | ||
| 242 | + return egressTreatments; | ||
| 243 | + } | ||
| 244 | + | ||
| 203 | @Override | 245 | @Override |
| 204 | public String toString() { | 246 | public String toString() { |
| 205 | return MoreObjects.toStringHelper(getClass()) | 247 | return MoreObjects.toStringHelper(getClass()) |
| ... | @@ -212,6 +254,7 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent { | ... | @@ -212,6 +254,7 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent { |
| 212 | .add("treatment", treatment()) | 254 | .add("treatment", treatment()) |
| 213 | .add("ingress", ingressPoint) | 255 | .add("ingress", ingressPoint) |
| 214 | .add("egress", egressPoints) | 256 | .add("egress", egressPoints) |
| 257 | + .add("treatments", egressTreatments) | ||
| 215 | .add("constraints", constraints()) | 258 | .add("constraints", constraints()) |
| 216 | .toString(); | 259 | .toString(); |
| 217 | } | 260 | } | ... | ... |
| ... | @@ -43,6 +43,7 @@ public abstract class ConnectivityIntentTest extends IntentTest { | ... | @@ -43,6 +43,7 @@ public abstract class ConnectivityIntentTest extends IntentTest { |
| 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(); | 45 | public static final Map<ConnectPoint, TrafficSelector> MATCHES = Collections.emptyMap(); |
| 46 | + public static final Map<ConnectPoint, TrafficTreatment> TREATMENTS = Collections.emptyMap(); | ||
| 46 | 47 | ||
| 47 | public static final ConnectPoint P1 = new ConnectPoint(DeviceId.deviceId("111"), PortNumber.portNumber(0x1)); | 48 | public static final ConnectPoint P1 = new ConnectPoint(DeviceId.deviceId("111"), PortNumber.portNumber(0x1)); |
| 48 | public static final ConnectPoint P2 = new ConnectPoint(DeviceId.deviceId("222"), PortNumber.portNumber(0x2)); | 49 | public static final ConnectPoint P2 = new ConnectPoint(DeviceId.deviceId("222"), PortNumber.portNumber(0x2)); |
| ... | @@ -64,4 +65,17 @@ public abstract class ConnectivityIntentTest extends IntentTest { | ... | @@ -64,4 +65,17 @@ public abstract class ConnectivityIntentTest extends IntentTest { |
| 64 | VLANMATCHES.put(P2, VLANMATCH2); | 65 | VLANMATCHES.put(P2, VLANMATCH2); |
| 65 | } | 66 | } |
| 66 | 67 | ||
| 68 | + public static final TrafficTreatment VLANACTION1 = DefaultTrafficTreatment.builder() | ||
| 69 | + .setVlanId(VlanId.vlanId("2")) | ||
| 70 | + .build(); | ||
| 71 | + public static final TrafficTreatment VLANACTION2 = DefaultTrafficTreatment.builder() | ||
| 72 | + .setVlanId(VlanId.vlanId("3")) | ||
| 73 | + .build(); | ||
| 74 | + | ||
| 75 | + public static final Map<ConnectPoint, TrafficTreatment> VLANACTIONS = Maps.newHashMap(); | ||
| 76 | + static { | ||
| 77 | + VLANACTIONS.put(P1, VLANACTION1); | ||
| 78 | + VLANACTIONS.put(P2, VLANACTION2); | ||
| 79 | + } | ||
| 80 | + | ||
| 67 | } | 81 | } | ... | ... |
| ... | @@ -15,7 +15,9 @@ | ... | @@ -15,7 +15,9 @@ |
| 15 | */ | 15 | */ |
| 16 | package org.onosproject.net.intent; | 16 | package org.onosproject.net.intent; |
| 17 | 17 | ||
| 18 | +import org.junit.Rule; | ||
| 18 | import org.junit.Test; | 19 | import org.junit.Test; |
| 20 | +import org.junit.rules.ExpectedException; | ||
| 19 | 21 | ||
| 20 | import static org.junit.Assert.assertEquals; | 22 | import static org.junit.Assert.assertEquals; |
| 21 | import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; | 23 | import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; |
| ... | @@ -42,6 +44,41 @@ public class SinglePointToMultiPointIntentTest extends ConnectivityIntentTest { | ... | @@ -42,6 +44,41 @@ public class SinglePointToMultiPointIntentTest extends ConnectivityIntentTest { |
| 42 | assertEquals("incorrect egress", PS2, intent.egressPoints()); | 44 | assertEquals("incorrect egress", PS2, intent.egressPoints()); |
| 43 | } | 45 | } |
| 44 | 46 | ||
| 47 | + @Rule | ||
| 48 | + public ExpectedException wrongMultiple = ExpectedException.none(); | ||
| 49 | + | ||
| 50 | + @Test | ||
| 51 | + public void multipleTreatments() { | ||
| 52 | + | ||
| 53 | + SinglePointToMultiPointIntent intent = createFirstMultiple(); | ||
| 54 | + assertEquals("incorrect id", APPID, intent.appId()); | ||
| 55 | + assertEquals("incorrect match", MATCH, intent.selector()); | ||
| 56 | + assertEquals("incorrect ingress", P1, intent.ingressPoint()); | ||
| 57 | + assertEquals("incorrect egress", PS2, intent.egressPoints()); | ||
| 58 | + assertEquals("incorrect treatment", NOP, intent.treatment()); | ||
| 59 | + assertEquals("incorrect treatments", TREATMENTS, intent.egressTreatments()); | ||
| 60 | + | ||
| 61 | + intent = createSecondMultiple(); | ||
| 62 | + assertEquals("incorrect id", APPID, intent.appId()); | ||
| 63 | + assertEquals("incorrect match", MATCH, intent.selector()); | ||
| 64 | + assertEquals("incorrect ingress", P1, intent.ingressPoint()); | ||
| 65 | + assertEquals("incorrect egress", PS2, intent.egressPoints()); | ||
| 66 | + assertEquals("incorrect treatment", VLANACTION1, intent.treatment()); | ||
| 67 | + assertEquals("incorrect selectors", TREATMENTS, intent.egressTreatments()); | ||
| 68 | + | ||
| 69 | + intent = createThirdMultiple(); | ||
| 70 | + assertEquals("incorrect id", APPID, intent.appId()); | ||
| 71 | + assertEquals("incorrect match", MATCH, intent.selector()); | ||
| 72 | + assertEquals("incorrect ingress", P1, intent.ingressPoint()); | ||
| 73 | + assertEquals("incorrect egress", PS2, intent.egressPoints()); | ||
| 74 | + assertEquals("incorrect treatment", NOP, intent.treatment()); | ||
| 75 | + assertEquals("incorrect selectors", VLANACTIONS, intent.egressTreatments()); | ||
| 76 | + | ||
| 77 | + wrongMultiple.expect(IllegalArgumentException.class); | ||
| 78 | + wrongMultiple.expectMessage("Treatment and Multiple Treatments are both set"); | ||
| 79 | + intent = createWrongMultiple(); | ||
| 80 | + } | ||
| 81 | + | ||
| 45 | @Override | 82 | @Override |
| 46 | protected SinglePointToMultiPointIntent createOne() { | 83 | protected SinglePointToMultiPointIntent createOne() { |
| 47 | return SinglePointToMultiPointIntent.builder() | 84 | return SinglePointToMultiPointIntent.builder() |
| ... | @@ -63,4 +100,50 @@ public class SinglePointToMultiPointIntentTest extends ConnectivityIntentTest { | ... | @@ -63,4 +100,50 @@ public class SinglePointToMultiPointIntentTest extends ConnectivityIntentTest { |
| 63 | .egressPoints(PS1) | 100 | .egressPoints(PS1) |
| 64 | .build(); | 101 | .build(); |
| 65 | } | 102 | } |
| 103 | + | ||
| 104 | + | ||
| 105 | + protected SinglePointToMultiPointIntent createFirstMultiple() { | ||
| 106 | + return SinglePointToMultiPointIntent.builder() | ||
| 107 | + .appId(APPID) | ||
| 108 | + .selector(MATCH) | ||
| 109 | + .treatment(NOP) | ||
| 110 | + .ingressPoint(P1) | ||
| 111 | + .egressPoints(PS2) | ||
| 112 | + .treatments(TREATMENTS) | ||
| 113 | + .build(); | ||
| 114 | + } | ||
| 115 | + | ||
| 116 | + protected SinglePointToMultiPointIntent createSecondMultiple() { | ||
| 117 | + return SinglePointToMultiPointIntent.builder() | ||
| 118 | + .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) | ||
| 132 | + .ingressPoint(P1) | ||
| 133 | + .egressPoints(PS2) | ||
| 134 | + .treatments(VLANACTIONS) | ||
| 135 | + .build(); | ||
| 136 | + } | ||
| 137 | + | ||
| 138 | + protected SinglePointToMultiPointIntent createWrongMultiple() { | ||
| 139 | + return SinglePointToMultiPointIntent.builder() | ||
| 140 | + .appId(APPID) | ||
| 141 | + .selector(MATCH) | ||
| 142 | + .treatment(VLANACTION1) | ||
| 143 | + .ingressPoint(P1) | ||
| 144 | + .egressPoints(PS2) | ||
| 145 | + .treatments(VLANACTIONS) | ||
| 146 | + .build(); | ||
| 147 | + } | ||
| 148 | + | ||
| 66 | } | 149 | } | ... | ... |
| ... | @@ -27,6 +27,7 @@ import org.onosproject.net.flow.DefaultTrafficSelector; | ... | @@ -27,6 +27,7 @@ import org.onosproject.net.flow.DefaultTrafficSelector; |
| 27 | import org.onosproject.net.flow.DefaultTrafficTreatment; | 27 | import org.onosproject.net.flow.DefaultTrafficTreatment; |
| 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 | +import org.onosproject.net.flow.instructions.Instruction; | ||
| 30 | import org.onosproject.net.flow.instructions.L0ModificationInstruction; | 31 | import org.onosproject.net.flow.instructions.L0ModificationInstruction; |
| 31 | import org.onosproject.net.flow.instructions.L1ModificationInstruction; | 32 | import org.onosproject.net.flow.instructions.L1ModificationInstruction; |
| 32 | import org.onosproject.net.flow.instructions.L2ModificationInstruction; | 33 | import org.onosproject.net.flow.instructions.L2ModificationInstruction; |
| ... | @@ -211,10 +212,29 @@ public class LinkCollectionCompiler<T> { | ... | @@ -211,10 +212,29 @@ public class LinkCollectionCompiler<T> { |
| 211 | } | 212 | } |
| 212 | } else { | 213 | } else { |
| 213 | if (outPorts.stream().allMatch(egressPorts::contains)) { | 214 | if (outPorts.stream().allMatch(egressPorts::contains)) { |
| 214 | - TrafficTreatment.Builder egressTreatmentBuilder = | 215 | + TrafficTreatment.Builder egressTreatmentBuilder = DefaultTrafficTreatment.builder(); |
| 215 | - DefaultTrafficTreatment.builder(intent.treatment()); | 216 | + if (intent.egressTreatments() != null && !intent.egressTreatments().isEmpty()) { |
| 216 | - outPorts.forEach(egressTreatmentBuilder::setOutput); | 217 | + for (PortNumber outPort : outPorts) { |
| 217 | - | 218 | + Optional<ConnectPoint> connectPoint = intent.egressPoints() |
| 219 | + .stream() | ||
| 220 | + .filter(egressPoint -> egressPoint.port().equals(outPort) | ||
| 221 | + && egressPoint.deviceId().equals(deviceId)) | ||
| 222 | + .findFirst(); | ||
| 223 | + if (connectPoint.isPresent()) { | ||
| 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 { | ||
| 229 | + throw new IntentCompilationException("Looking for connect point associated to " + | ||
| 230 | + "the treatment. outPort not in egressPoints"); | ||
| 231 | + } | ||
| 232 | + } | ||
| 233 | + } else { | ||
| 234 | + egressTreatmentBuilder = this | ||
| 235 | + .updateBuilder(DefaultTrafficTreatment.builder(intent.treatment()), intent.selector()); | ||
| 236 | + outPorts.forEach(egressTreatmentBuilder::setOutput); | ||
| 237 | + } | ||
| 218 | selectorBuilder = DefaultTrafficSelector.builder(intent.selector()); | 238 | selectorBuilder = DefaultTrafficSelector.builder(intent.selector()); |
| 219 | treatment = egressTreatmentBuilder.build(); | 239 | treatment = egressTreatmentBuilder.build(); |
| 220 | } else { | 240 | } else { |
| ... | @@ -230,10 +250,34 @@ public class LinkCollectionCompiler<T> { | ... | @@ -230,10 +250,34 @@ public class LinkCollectionCompiler<T> { |
| 230 | } | 250 | } |
| 231 | 251 | ||
| 232 | /** | 252 | /** |
| 253 | + * Update a builder using a treatment. | ||
| 254 | + * @param builder the builder to update | ||
| 255 | + * @param treatment the treatment to add | ||
| 256 | + * @return the new builder | ||
| 257 | + */ | ||
| 258 | + private TrafficTreatment.Builder addTreatment(TrafficTreatment.Builder builder, TrafficTreatment treatment) { | ||
| 259 | + builder.deferred(); | ||
| 260 | + for (Instruction instruction : treatment.deferred()) { | ||
| 261 | + builder.add(instruction); | ||
| 262 | + } | ||
| 263 | + builder.immediate(); | ||
| 264 | + for (Instruction instruction : treatment.immediate()) { | ||
| 265 | + builder.add(instruction); | ||
| 266 | + } | ||
| 267 | + return builder; | ||
| 268 | + } | ||
| 269 | + | ||
| 270 | + /** | ||
| 233 | * Update the original builder with the necessary operations | 271 | * Update the original builder with the necessary operations |
| 234 | * to have a correct forwarding given an ingress selector. | 272 | * to have a correct forwarding given an ingress selector. |
| 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. | ||
| 235 | * | 278 | * |
| 236 | * @param treatmentBuilder the builder to modify | 279 | * @param treatmentBuilder the builder to modify |
| 280 | + * @param intentSelector the intent selector to use as input | ||
| 237 | * @return the new treatment created | 281 | * @return the new treatment created |
| 238 | */ | 282 | */ |
| 239 | private TrafficTreatment.Builder updateBuilder(TrafficTreatment.Builder treatmentBuilder, | 283 | private TrafficTreatment.Builder updateBuilder(TrafficTreatment.Builder treatmentBuilder, | ... | ... |
| ... | @@ -34,6 +34,8 @@ import org.onosproject.net.intent.FlowRuleIntent; | ... | @@ -34,6 +34,8 @@ import org.onosproject.net.intent.FlowRuleIntent; |
| 34 | import org.onosproject.net.intent.Intent; | 34 | import org.onosproject.net.intent.Intent; |
| 35 | import org.onosproject.net.intent.IntentCompiler; | 35 | import org.onosproject.net.intent.IntentCompiler; |
| 36 | import org.onosproject.net.intent.LinkCollectionIntent; | 36 | import org.onosproject.net.intent.LinkCollectionIntent; |
| 37 | +import org.slf4j.Logger; | ||
| 38 | +import org.slf4j.LoggerFactory; | ||
| 37 | 39 | ||
| 38 | import java.util.ArrayList; | 40 | import java.util.ArrayList; |
| 39 | import java.util.Collections; | 41 | import java.util.Collections; |
| ... | @@ -48,6 +50,9 @@ public class LinkCollectionIntentCompiler | ... | @@ -48,6 +50,9 @@ public class LinkCollectionIntentCompiler |
| 48 | extends LinkCollectionCompiler<FlowRule> | 50 | extends LinkCollectionCompiler<FlowRule> |
| 49 | implements IntentCompiler<LinkCollectionIntent> { | 51 | implements IntentCompiler<LinkCollectionIntent> { |
| 50 | 52 | ||
| 53 | + private static Logger log = LoggerFactory.getLogger(LinkCollectionIntentCompiler.class); | ||
| 54 | + | ||
| 55 | + | ||
| 51 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 56 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| 52 | protected IntentConfigurableRegistrator registrator; | 57 | protected IntentConfigurableRegistrator registrator; |
| 53 | 58 | ... | ... |
| ... | @@ -77,6 +77,7 @@ public class SinglePointToMultiPointIntentCompiler | ... | @@ -77,6 +77,7 @@ public class SinglePointToMultiPointIntentCompiler |
| 77 | .priority(intent.priority()) | 77 | .priority(intent.priority()) |
| 78 | .applyTreatmentOnEgress(true) | 78 | .applyTreatmentOnEgress(true) |
| 79 | .constraints(intent.constraints()) | 79 | .constraints(intent.constraints()) |
| 80 | + .egressTreatments(intent.egressTreatments()) | ||
| 80 | .build(); | 81 | .build(); |
| 81 | 82 | ||
| 82 | return Collections.singletonList(result); | 83 | return Collections.singletonList(result); | ... | ... |
This diff is collapsed. Click to expand it.
-
Please register or login to post a comment