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