Pier Ventre
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
...@@ -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,6 +59,7 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent { ...@@ -51,6 +59,7 @@ 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
...@@ -58,11 +67,14 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent { ...@@ -58,11 +67,14 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent {
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,
72 + ConnectPoint ingressPoint,
73 + Set<ConnectPoint> egressPoints,
63 List<Constraint> constraints, 74 List<Constraint> constraints,
64 - int priority) { 75 + int priority,
65 - super(appId, key, Collections.emptyList(), selector, treatment, constraints, 76 + Map<ConnectPoint, TrafficTreatment> egressTreatments) {
77 + super(appId, key, ImmutableList.of(), selector, treatment, constraints,
66 priority); 78 priority);
67 checkNotNull(egressPoints); 79 checkNotNull(egressPoints);
68 checkNotNull(ingressPoint); 80 checkNotNull(ingressPoint);
...@@ -70,8 +82,9 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent { ...@@ -70,8 +82,9 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent {
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()) {
217 + for (PortNumber outPort : outPorts) {
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());
216 outPorts.forEach(egressTreatmentBuilder::setOutput); 236 outPorts.forEach(egressTreatmentBuilder::setOutput);
217 - 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);
......
...@@ -64,13 +64,18 @@ public class LinkCollectionIntentCompilerTest { ...@@ -64,13 +64,18 @@ public class LinkCollectionIntentCompilerTest {
64 64
65 private final ApplicationId appId = new TestApplicationId("test"); 65 private final ApplicationId appId = new TestApplicationId("test");
66 66
67 - private final ConnectPoint d1p1 = connectPoint("s1", 0); 67 + private final ConnectPoint d1p1 = connectPoint("s1", 1);
68 private final ConnectPoint d2p0 = connectPoint("s2", 0); 68 private final ConnectPoint d2p0 = connectPoint("s2", 0);
69 private final ConnectPoint d2p1 = connectPoint("s2", 1); 69 private final ConnectPoint d2p1 = connectPoint("s2", 1);
70 + private final ConnectPoint d2p2 = connectPoint("s2", 2);
71 + private final ConnectPoint d2p3 = connectPoint("s2", 3);
70 private final ConnectPoint d3p1 = connectPoint("s3", 1); 72 private final ConnectPoint d3p1 = connectPoint("s3", 1);
71 private final ConnectPoint d3p2 = connectPoint("s3", 9); 73 private final ConnectPoint d3p2 = connectPoint("s3", 9);
72 private final ConnectPoint d3p0 = connectPoint("s3", 10); 74 private final ConnectPoint d3p0 = connectPoint("s3", 10);
73 private final ConnectPoint d1p0 = connectPoint("s1", 10); 75 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 79
75 private final Set<Link> links = ImmutableSet.of( 80 private final Set<Link> links = ImmutableSet.of(
76 DefaultLink.builder().providerId(PID).src(d1p1).dst(d2p0).type(DIRECT).build(), 81 DefaultLink.builder().providerId(PID).src(d1p1).dst(d2p0).type(DIRECT).build(),
...@@ -80,6 +85,11 @@ public class LinkCollectionIntentCompilerTest { ...@@ -80,6 +85,11 @@ public class LinkCollectionIntentCompilerTest {
80 private final Set<Link> linksMultiple = ImmutableSet.of( 85 private final Set<Link> linksMultiple = ImmutableSet.of(
81 DefaultLink.builder().providerId(PID).src(d3p1).dst(d2p0).type(DIRECT).build()); 86 DefaultLink.builder().providerId(PID).src(d3p1).dst(d2p0).type(DIRECT).build());
82 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 +
83 private final TrafficSelector selector = DefaultTrafficSelector.builder().build(); 93 private final TrafficSelector selector = DefaultTrafficSelector.builder().build();
84 private final TrafficTreatment treatment = DefaultTrafficTreatment.builder().build(); 94 private final TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
85 95
...@@ -101,14 +111,40 @@ public class LinkCollectionIntentCompilerTest { ...@@ -101,14 +111,40 @@ public class LinkCollectionIntentCompilerTest {
101 .setVlanId(egressVlan) 111 .setVlanId(egressVlan)
102 .build(); 112 .build();
103 113
114 +private final VlanId ingressVlan = VlanId.vlanId("10");
115 + private final TrafficSelector vlanSelector = DefaultTrafficSelector
116 + .builder()
117 + .matchVlanId(ingressVlan)
118 + .build();
119 +
120 + private final VlanId egressVlan1 = VlanId.vlanId("20");
121 + private final TrafficTreatment vlanTreatment1 = DefaultTrafficTreatment
122 + .builder()
123 + .setVlanId(egressVlan1)
124 + .build();
125 +
126 + private final VlanId egressVlan2 = VlanId.vlanId("666");
127 + private final TrafficTreatment vlanTreatment2 = DefaultTrafficTreatment
128 + .builder()
129 + .setVlanId(egressVlan2)
130 + .build();
131 +
132 + private final VlanId egressVlan3 = VlanId.vlanId("69");
133 + private final TrafficTreatment vlanTreatment3 = DefaultTrafficTreatment
134 + .builder()
135 + .setVlanId(egressVlan3)
136 + .build();
137 +
138 +
104 private CoreService coreService; 139 private CoreService coreService;
105 private IntentExtensionService intentExtensionService; 140 private IntentExtensionService intentExtensionService;
106 private IntentConfigurableRegistrator registrator; 141 private IntentConfigurableRegistrator registrator;
107 private IdGenerator idGenerator = new MockIdGenerator(); 142 private IdGenerator idGenerator = new MockIdGenerator();
108 143
109 private LinkCollectionIntent intent; 144 private LinkCollectionIntent intent;
110 - private LinkCollectionIntent intentMultiple; 145 + private LinkCollectionIntent intentMultipleSelectors;
111 - 146 + private LinkCollectionIntent intentMultipleTreatments;
147 + private LinkCollectionIntent intentMultipleTreatments2;
112 148
113 private LinkCollectionIntentCompiler sut; 149 private LinkCollectionIntentCompiler sut;
114 150
...@@ -130,7 +166,7 @@ public class LinkCollectionIntentCompilerTest { ...@@ -130,7 +166,7 @@ public class LinkCollectionIntentCompilerTest {
130 .ingressPoints(ImmutableSet.of(d1p1)) 166 .ingressPoints(ImmutableSet.of(d1p1))
131 .egressPoints(ImmutableSet.of(d3p1)) 167 .egressPoints(ImmutableSet.of(d3p1))
132 .build(); 168 .build();
133 - intentMultiple = LinkCollectionIntent.builder() 169 + intentMultipleSelectors = LinkCollectionIntent.builder()
134 .appId(APP_ID) 170 .appId(APP_ID)
135 .treatment(vlanTreatment) 171 .treatment(vlanTreatment)
136 .links(linksMultiple) 172 .links(linksMultiple)
...@@ -138,6 +174,24 @@ public class LinkCollectionIntentCompilerTest { ...@@ -138,6 +174,24 @@ public class LinkCollectionIntentCompilerTest {
138 .egressPoints(ImmutableSet.of(d2p1)) 174 .egressPoints(ImmutableSet.of(d2p1))
139 .ingressSelectors(this.createIngressSelectors()) 175 .ingressSelectors(this.createIngressSelectors())
140 .build(); 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();
141 195
142 intentExtensionService = createMock(IntentExtensionService.class); 196 intentExtensionService = createMock(IntentExtensionService.class);
143 intentExtensionService.registerCompiler(LinkCollectionIntent.class, sut); 197 intentExtensionService.registerCompiler(LinkCollectionIntent.class, sut);
...@@ -208,22 +262,22 @@ public class LinkCollectionIntentCompilerTest { ...@@ -208,22 +262,22 @@ public class LinkCollectionIntentCompilerTest {
208 sut.deactivate(); 262 sut.deactivate();
209 } 263 }
210 264
211 - @Test 265 +@Test
212 public void testCompileMultipleSelectors() { 266 public void testCompileMultipleSelectors() {
213 sut.activate(); 267 sut.activate();
214 268
215 - List<Intent> compiled = sut.compile(intentMultiple, Collections.emptyList()); 269 + List<Intent> compiled = sut.compile(intentMultipleSelectors, Collections.emptyList());
216 assertThat(compiled, hasSize(1)); 270 assertThat(compiled, hasSize(1));
217 271
218 272
219 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules(); 273 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
220 - assertThat(rules, hasSize((linksMultiple.size()) + intentMultiple.ingressPoints().size())); 274 + assertThat(rules, hasSize((linksMultiple.size()) + intentMultipleSelectors.ingressPoints().size()));
221 275
222 Set<FlowRule> d3Rules = rules 276 Set<FlowRule> d3Rules = rules
223 .parallelStream() 277 .parallelStream()
224 .filter(rule -> rule.deviceId().equals(d3p0.deviceId())) 278 .filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
225 .collect(Collectors.toSet()); 279 .collect(Collectors.toSet());
226 - assertThat(d3Rules, hasSize(intentMultiple.ingressPoints().size())); 280 + assertThat(d3Rules, hasSize(intentMultipleSelectors.ingressPoints().size()));
227 281
228 FlowRule rule1 = rules.stream() 282 FlowRule rule1 = rules.stream()
229 .filter(rule -> rule.deviceId().equals(d3p0.deviceId()) 283 .filter(rule -> rule.deviceId().equals(d3p0.deviceId())
...@@ -233,18 +287,18 @@ public class LinkCollectionIntentCompilerTest { ...@@ -233,18 +287,18 @@ public class LinkCollectionIntentCompilerTest {
233 .get(); 287 .get();
234 assertThat(rule1.selector(), is( 288 assertThat(rule1.selector(), is(
235 DefaultTrafficSelector 289 DefaultTrafficSelector
236 - .builder(intentMultiple.selector()) 290 + .builder(intentMultipleSelectors.selector())
237 .matchInPort(d3p0.port()) 291 .matchInPort(d3p0.port())
238 .matchVlanId(ingressVlan1) 292 .matchVlanId(ingressVlan1)
239 .build() 293 .build()
240 )); 294 ));
241 assertThat(rule1.treatment(), is( 295 assertThat(rule1.treatment(), is(
242 DefaultTrafficTreatment 296 DefaultTrafficTreatment
243 - .builder(intentMultiple.treatment()) 297 + .builder(intentMultipleSelectors.treatment())
244 .setOutput(d3p1.port()) 298 .setOutput(d3p1.port())
245 .build() 299 .build()
246 )); 300 ));
247 - assertThat(rule1.priority(), is(intentMultiple.priority())); 301 + assertThat(rule1.priority(), is(intentMultipleSelectors.priority()));
248 302
249 FlowRule rule2 = rules.stream() 303 FlowRule rule2 = rules.stream()
250 .filter(rule -> rule.deviceId().equals(d3p0.deviceId()) 304 .filter(rule -> rule.deviceId().equals(d3p0.deviceId())
...@@ -254,24 +308,24 @@ public class LinkCollectionIntentCompilerTest { ...@@ -254,24 +308,24 @@ public class LinkCollectionIntentCompilerTest {
254 .get(); 308 .get();
255 assertThat(rule2.selector(), is( 309 assertThat(rule2.selector(), is(
256 DefaultTrafficSelector 310 DefaultTrafficSelector
257 - .builder(intentMultiple.selector()) 311 + .builder(intentMultipleSelectors.selector())
258 .matchInPort(d3p2.port()) 312 .matchInPort(d3p2.port())
259 .matchVlanId(ingressVlan2) 313 .matchVlanId(ingressVlan2)
260 .build() 314 .build()
261 )); 315 ));
262 assertThat(rule2.treatment(), is( 316 assertThat(rule2.treatment(), is(
263 DefaultTrafficTreatment 317 DefaultTrafficTreatment
264 - .builder(intentMultiple.treatment()) 318 + .builder(intentMultipleSelectors.treatment())
265 .setOutput(d3p1.port()) 319 .setOutput(d3p1.port())
266 .build() 320 .build()
267 )); 321 ));
268 - assertThat(rule1.priority(), is(intentMultiple.priority())); 322 + assertThat(rule2.priority(), is(intentMultipleSelectors.priority()));
269 323
270 Set<FlowRule> d2Rules = rules 324 Set<FlowRule> d2Rules = rules
271 .parallelStream() 325 .parallelStream()
272 .filter(rule -> rule.deviceId().equals(d2p0.deviceId())) 326 .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
273 .collect(Collectors.toSet()); 327 .collect(Collectors.toSet());
274 - assertThat(d2Rules, hasSize(intentMultiple.egressPoints().size())); 328 + assertThat(d2Rules, hasSize(intentMultipleSelectors.egressPoints().size()));
275 329
276 // We do not need in_port filter 330 // We do not need in_port filter
277 FlowRule rule3 = rules.stream() 331 FlowRule rule3 = rules.stream()
...@@ -280,7 +334,7 @@ public class LinkCollectionIntentCompilerTest { ...@@ -280,7 +334,7 @@ public class LinkCollectionIntentCompilerTest {
280 .get(); 334 .get();
281 assertThat(rule3.selector(), is( 335 assertThat(rule3.selector(), is(
282 DefaultTrafficSelector 336 DefaultTrafficSelector
283 - .builder(intentMultiple.selector()) 337 + .builder(intentMultipleSelectors.selector())
284 .matchInPort(d2p0.port()) 338 .matchInPort(d2p0.port())
285 .matchVlanId(egressVlan) 339 .matchVlanId(egressVlan)
286 .build() 340 .build()
...@@ -291,15 +345,216 @@ public class LinkCollectionIntentCompilerTest { ...@@ -291,15 +345,216 @@ public class LinkCollectionIntentCompilerTest {
291 .setOutput(d2p1.port()) 345 .setOutput(d2p1.port())
292 .build() 346 .build()
293 )); 347 ));
294 - assertThat(rule3.priority(), is(intentMultiple.priority())); 348 + assertThat(rule3.priority(), is(intentMultipleSelectors.priority()));
295 349
296 sut.deactivate(); 350 sut.deactivate();
297 } 351 }
298 352
353 + @Test
354 + public void testCompileMultipleTreatments() {
355 + sut.activate();
356 +
357 + List<Intent> compiled = sut.compile(intentMultipleTreatments, Collections.emptyList());
358 + assertThat(compiled, hasSize(1));
359 +
360 + Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
361 + assertThat(rules, hasSize((linksMultiple.size() + intentMultipleTreatments.egressPoints().size())));
362 +
363 + Set<FlowRule> d3Rules = rules
364 + .parallelStream()
365 + .filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
366 + .collect(Collectors.toSet());
367 + assertThat(d3Rules, hasSize(intentMultipleTreatments.ingressPoints().size()));
368 +
369 + FlowRule rule1 = rules.stream()
370 + .filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
371 + .findFirst()
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 +
388 + Set<FlowRule> d2Rules = rules
389 + .parallelStream()
390 + .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
391 + .collect(Collectors.toSet());
392 + assertThat(d2Rules, hasSize(1));
393 +
394 + FlowRule rule2 = rules.stream()
395 + .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
396 + .findFirst()
397 + .get();
398 + assertThat(rule2.selector(), is(
399 + DefaultTrafficSelector
400 + .builder(intentMultipleTreatments.selector())
401 + .matchInPort(d2p0.port())
402 + .matchVlanId(ingressVlan)
403 + .build()
404 + ));
405 + assertThat(rule2.treatment(), is(
406 + DefaultTrafficTreatment
407 + .builder(intentMultipleTreatments.treatment())
408 + .setVlanId(egressVlan1)
409 + .setOutput(d2p1.port())
410 + .setVlanId(egressVlan2)
411 + .setOutput(d2p2.port())
412 + .build()
413 + ));
414 + assertThat(rule2.priority(), is(intentMultipleTreatments.priority()));
415 +
416 + }
417 +
418 + @Test
419 + public void testCompileMultipleTreatments2() {
420 + sut.activate();
421 +
422 + List<Intent> compiled = sut.compile(intentMultipleTreatments2, Collections.emptyList());
423 + assertThat(compiled, hasSize(1));
424 +
425 +
426 + Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
427 + assertThat(rules, hasSize((linksMultiple2.size() + intentMultipleTreatments2.egressPoints().size())));
428 +
429 +
430 + Set<FlowRule> d2Rules = rules
431 + .parallelStream()
432 + .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
433 + .collect(Collectors.toSet());
434 + assertThat(d2Rules, hasSize(1));
435 +
436 +
437 + FlowRule rule1 = rules.stream()
438 + .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
439 + .findFirst()
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 +
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 +
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 +
484 + Set<FlowRule> d3Rules = rules
485 + .parallelStream()
486 + .filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
487 + .collect(Collectors.toSet());
488 + assertThat(d3Rules, hasSize(1));
489 +
490 + FlowRule rule3 = rules.stream()
491 + .filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
492 + .findFirst()
493 + .get();
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 +
510 + Set<FlowRule> d4Rules = rules
511 + .parallelStream()
512 + .filter(rule -> rule.deviceId().equals(d4p0.deviceId()))
513 + .collect(Collectors.toSet());
514 + assertThat(d4Rules, hasSize(1));
515 +
516 + FlowRule rule4 = rules.stream()
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 +
536 + }
537 +
538 + public Map<ConnectPoint, TrafficTreatment> createEgressTreatments() {
539 + Map<ConnectPoint, TrafficTreatment> mapToReturn = Maps.newHashMap();
540 + mapToReturn.put(d2p1, vlanTreatment1);
541 + mapToReturn.put(d2p2, vlanTreatment2);
542 + return mapToReturn;
543 + }
544 +
545 + public Map<ConnectPoint, TrafficTreatment> createEgressTreatments2() {
546 + Map<ConnectPoint, TrafficTreatment> mapToReturn = Maps.newHashMap();
547 + mapToReturn.put(d1p0, vlanTreatment1);
548 + mapToReturn.put(d3p0, vlanTreatment2);
549 + mapToReturn.put(d4p0, vlanTreatment3);
550 + return mapToReturn;
551 + }
552 +
299 public Map<ConnectPoint, TrafficSelector> createIngressSelectors() { 553 public Map<ConnectPoint, TrafficSelector> createIngressSelectors() {
300 Map<ConnectPoint, TrafficSelector> mapToReturn = Maps.newHashMap(); 554 Map<ConnectPoint, TrafficSelector> mapToReturn = Maps.newHashMap();
301 mapToReturn.put(d3p0, selectorVlan1); 555 mapToReturn.put(d3p0, selectorVlan1);
302 mapToReturn.put(d3p2, selectorVlan2); 556 mapToReturn.put(d3p2, selectorVlan2);
303 return mapToReturn; 557 return mapToReturn;
304 } 558 }
559 +
305 } 560 }
......