Pier Ventre
Committed by Gerrit Code Review

[ONOS-4387] Support for multiple selectors in mp2sp intents

Changes:
- Adds extension to mp2sp intents;
- Adds extension to linkcollection intents;
- Adds extension to mp2sp compiler;
- Adds extension to linkcollection compiler;
- Adds unit tests for both mp2sp and linkcollection intents;

Change-Id: I673c2b660d2364c510b1b3050ed3626ad2f37bda
...@@ -13,12 +13,16 @@ ...@@ -13,12 +13,16 @@
13 * See the License for the specific language governing permissions and 13 * See the License for the specific language governing permissions and
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 +
16 package org.onosproject.net.intent; 17 package org.onosproject.net.intent;
17 18
19 +import java.util.Collections;
18 import java.util.List; 20 import java.util.List;
21 +import java.util.Map;
19 import java.util.Set; 22 import java.util.Set;
20 23
21 import com.google.common.annotations.Beta; 24 import com.google.common.annotations.Beta;
25 +import com.google.common.collect.ImmutableMap;
22 import org.onosproject.core.ApplicationId; 26 import org.onosproject.core.ApplicationId;
23 import org.onosproject.net.ConnectPoint; 27 import org.onosproject.net.ConnectPoint;
24 import org.onosproject.net.Link; 28 import org.onosproject.net.Link;
...@@ -39,6 +43,11 @@ public final class LinkCollectionIntent extends ConnectivityIntent { ...@@ -39,6 +43,11 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
39 43
40 private final Set<ConnectPoint> ingressPoints; 44 private final Set<ConnectPoint> ingressPoints;
41 private final Set<ConnectPoint> egressPoints; 45 private final Set<ConnectPoint> egressPoints;
46 + /**
47 + * To manage multiple selectors use case.
48 + */
49 + private final Map<ConnectPoint, TrafficSelector> ingressSelectors;
50 +
42 private final boolean egressTreatmentFlag; 51 private final boolean egressTreatmentFlag;
43 52
44 /** 53 /**
...@@ -56,6 +65,7 @@ public final class LinkCollectionIntent extends ConnectivityIntent { ...@@ -56,6 +65,7 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
56 * @param constraints optional list of constraints 65 * @param constraints optional list of constraints
57 * @param priority priority to use for the flows generated by this intent 66 * @param priority priority to use for the flows generated by this intent
58 * @param egressTreatment true if treatment should be applied by the egress device 67 * @param egressTreatment true if treatment should be applied by the egress device
68 + * @param ingressSelectors map to store the association ingress to selector
59 * @throws NullPointerException {@code path} is null 69 * @throws NullPointerException {@code path} is null
60 */ 70 */
61 private LinkCollectionIntent(ApplicationId appId, 71 private LinkCollectionIntent(ApplicationId appId,
...@@ -66,12 +76,15 @@ public final class LinkCollectionIntent extends ConnectivityIntent { ...@@ -66,12 +76,15 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
66 Set<ConnectPoint> ingressPoints, 76 Set<ConnectPoint> ingressPoints,
67 Set<ConnectPoint> egressPoints, 77 Set<ConnectPoint> egressPoints,
68 List<Constraint> constraints, 78 List<Constraint> constraints,
69 - int priority, boolean egressTreatment) { 79 + int priority,
80 + boolean egressTreatment,
81 + Map<ConnectPoint, TrafficSelector> ingressSelectors) {
70 super(appId, key, resources(links), selector, treatment, constraints, priority); 82 super(appId, key, resources(links), selector, treatment, constraints, priority);
71 this.links = links; 83 this.links = links;
72 this.ingressPoints = ingressPoints; 84 this.ingressPoints = ingressPoints;
73 this.egressPoints = egressPoints; 85 this.egressPoints = egressPoints;
74 this.egressTreatmentFlag = egressTreatment; 86 this.egressTreatmentFlag = egressTreatment;
87 + this.ingressSelectors = ingressSelectors;
75 } 88 }
76 89
77 /** 90 /**
...@@ -83,6 +96,7 @@ public final class LinkCollectionIntent extends ConnectivityIntent { ...@@ -83,6 +96,7 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
83 this.ingressPoints = null; 96 this.ingressPoints = null;
84 this.egressPoints = null; 97 this.egressPoints = null;
85 this.egressTreatmentFlag = false; 98 this.egressTreatmentFlag = false;
99 + this.ingressSelectors = null;
86 } 100 }
87 101
88 /** 102 /**
...@@ -104,6 +118,7 @@ public final class LinkCollectionIntent extends ConnectivityIntent { ...@@ -104,6 +118,7 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
104 Set<Link> links; 118 Set<Link> links;
105 Set<ConnectPoint> ingressPoints; 119 Set<ConnectPoint> ingressPoints;
106 Set<ConnectPoint> egressPoints; 120 Set<ConnectPoint> egressPoints;
121 + Map<ConnectPoint, TrafficSelector> ingressSelectors = Collections.emptyMap();
107 boolean egressTreatmentFlag; 122 boolean egressTreatmentFlag;
108 123
109 private Builder() { 124 private Builder() {
...@@ -165,6 +180,17 @@ public final class LinkCollectionIntent extends ConnectivityIntent { ...@@ -165,6 +180,17 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
165 } 180 }
166 181
167 /** 182 /**
183 + * Sets the map ingress selectors to connection points of the intent.
184 + *
185 + * @param ingressSelectors maps connection point to traffic selector
186 + * @return this builder
187 + */
188 + public Builder ingressSelectors(Map<ConnectPoint, TrafficSelector> ingressSelectors) {
189 + this.ingressSelectors = ImmutableMap.copyOf(ingressSelectors);
190 + return this;
191 + }
192 +
193 + /**
168 * Sets the links of the link collection intent 194 * Sets the links of the link collection intent
169 * that will be built. 195 * that will be built.
170 * 196 *
...@@ -206,7 +232,8 @@ public final class LinkCollectionIntent extends ConnectivityIntent { ...@@ -206,7 +232,8 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
206 egressPoints, 232 egressPoints,
207 constraints, 233 constraints,
208 priority, 234 priority,
209 - egressTreatmentFlag 235 + egressTreatmentFlag,
236 + ingressSelectors
210 ); 237 );
211 } 238 }
212 } 239 }
...@@ -241,6 +268,14 @@ public final class LinkCollectionIntent extends ConnectivityIntent { ...@@ -241,6 +268,14 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
241 } 268 }
242 269
243 /** 270 /**
271 + * Returns the multiple selectors jointly with their connection points.
272 + * @return multiple selectors
273 + */
274 + public Map<ConnectPoint, TrafficSelector> ingressSelectors() {
275 + return ingressSelectors;
276 + }
277 +
278 + /**
244 * Returns whether treatment should be applied on egress. 279 * Returns whether treatment should be applied on egress.
245 * 280 *
246 * @return the egress treatment flag 281 * @return the egress treatment flag
...@@ -262,7 +297,8 @@ public final class LinkCollectionIntent extends ConnectivityIntent { ...@@ -262,7 +297,8 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
262 .add("links", links()) 297 .add("links", links())
263 .add("ingress", ingressPoints()) 298 .add("ingress", ingressPoints())
264 .add("egress", egressPoints()) 299 .add("egress", egressPoints())
265 - .add("treatementOnEgress", applyTreatmentOnEgress()) 300 + .add("selectors", ingressSelectors())
301 + .add("treatmentOnEgress", applyTreatmentOnEgress())
266 .toString(); 302 .toString();
267 } 303 }
268 } 304 }
......
...@@ -17,6 +17,7 @@ package org.onosproject.net.intent; ...@@ -17,6 +17,7 @@ package org.onosproject.net.intent;
17 17
18 import com.google.common.annotations.Beta; 18 import com.google.common.annotations.Beta;
19 import com.google.common.base.MoreObjects; 19 import com.google.common.base.MoreObjects;
20 +import com.google.common.collect.ImmutableMap;
20 import com.google.common.collect.ImmutableSet; 21 import com.google.common.collect.ImmutableSet;
21 import com.google.common.collect.Sets; 22 import com.google.common.collect.Sets;
22 import org.onosproject.core.ApplicationId; 23 import org.onosproject.core.ApplicationId;
...@@ -26,6 +27,7 @@ import org.onosproject.net.flow.TrafficTreatment; ...@@ -26,6 +27,7 @@ import org.onosproject.net.flow.TrafficTreatment;
26 27
27 import java.util.Collections; 28 import java.util.Collections;
28 import java.util.List; 29 import java.util.List;
30 +import java.util.Map;
29 import java.util.Set; 31 import java.util.Set;
30 32
31 import static com.google.common.base.Preconditions.checkArgument; 33 import static com.google.common.base.Preconditions.checkArgument;
...@@ -39,6 +41,10 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent { ...@@ -39,6 +41,10 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent {
39 41
40 private final Set<ConnectPoint> ingressPoints; 42 private final Set<ConnectPoint> ingressPoints;
41 private final ConnectPoint egressPoint; 43 private final ConnectPoint egressPoint;
44 + /**
45 + * To manage multiple selectors use case.
46 + */
47 + private final Map<ConnectPoint, TrafficSelector> ingressSelectors;
42 48
43 /** 49 /**
44 * Creates a new multi-to-single point connectivity intent for the specified 50 * Creates a new multi-to-single point connectivity intent for the specified
...@@ -52,6 +58,7 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent { ...@@ -52,6 +58,7 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent {
52 * @param egressPoint port to which traffic will egress 58 * @param egressPoint port to which traffic will egress
53 * @param constraints constraints to apply to the intent 59 * @param constraints constraints to apply to the intent
54 * @param priority priority to use for flows generated by this intent 60 * @param priority priority to use for flows generated by this intent
61 + * @param ingressSelectors map to store the association ingress to selector
55 * @throws NullPointerException if {@code ingressPoints} or 62 * @throws NullPointerException if {@code ingressPoints} or
56 * {@code egressPoint} is null. 63 * {@code egressPoint} is null.
57 * @throws IllegalArgumentException if the size of {@code ingressPoints} is 64 * @throws IllegalArgumentException if the size of {@code ingressPoints} is
...@@ -64,7 +71,9 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent { ...@@ -64,7 +71,9 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent {
64 Set<ConnectPoint> ingressPoints, 71 Set<ConnectPoint> ingressPoints,
65 ConnectPoint egressPoint, 72 ConnectPoint egressPoint,
66 List<Constraint> constraints, 73 List<Constraint> constraints,
67 - int priority) { 74 + int priority,
75 + Map<ConnectPoint, TrafficSelector> ingressSelectors
76 + ) {
68 super(appId, key, Collections.emptyList(), selector, treatment, constraints, 77 super(appId, key, Collections.emptyList(), selector, treatment, constraints,
69 priority); 78 priority);
70 79
...@@ -76,6 +85,7 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent { ...@@ -76,6 +85,7 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent {
76 85
77 this.ingressPoints = Sets.newHashSet(ingressPoints); 86 this.ingressPoints = Sets.newHashSet(ingressPoints);
78 this.egressPoint = egressPoint; 87 this.egressPoint = egressPoint;
88 + this.ingressSelectors = ingressSelectors;
79 } 89 }
80 90
81 /** 91 /**
...@@ -85,6 +95,7 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent { ...@@ -85,6 +95,7 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent {
85 super(); 95 super();
86 this.ingressPoints = null; 96 this.ingressPoints = null;
87 this.egressPoint = null; 97 this.egressPoint = null;
98 + this.ingressSelectors = null;
88 } 99 }
89 100
90 /** 101 /**
...@@ -116,6 +127,7 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent { ...@@ -116,6 +127,7 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent {
116 public static final class Builder extends ConnectivityIntent.Builder { 127 public static final class Builder extends ConnectivityIntent.Builder {
117 Set<ConnectPoint> ingressPoints; 128 Set<ConnectPoint> ingressPoints;
118 ConnectPoint egressPoint; 129 ConnectPoint egressPoint;
130 + Map<ConnectPoint, TrafficSelector> ingressSelectors = Collections.emptyMap();
119 131
120 private Builder() { 132 private Builder() {
121 // Hide constructor 133 // Hide constructor
...@@ -189,13 +201,30 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent { ...@@ -189,13 +201,30 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent {
189 } 201 }
190 202
191 /** 203 /**
204 + * Sets the selectors of the multi point to single point intent
205 + * that will be built.
206 + *
207 + * @param ingressSelectors the multiple selectos
208 + * @return this builder
209 + */
210 + public Builder selectors(Map<ConnectPoint, TrafficSelector> ingressSelectors) {
211 + this.ingressSelectors = ImmutableMap.copyOf(ingressSelectors);
212 + return this;
213 + }
214 +
215 + /**
192 * Builds a multi point to single point intent from the 216 * Builds a multi point to single point intent from the
193 * accumulated parameters. 217 * accumulated parameters.
194 * 218 *
195 - * @return point to point intent 219 + * @return multi point to single point intent
196 */ 220 */
197 public MultiPointToSinglePointIntent build() { 221 public MultiPointToSinglePointIntent build() {
198 222
223 + if (selector != null && !selector.criteria().isEmpty() &&
224 + ingressSelectors != null && !ingressSelectors.isEmpty()) {
225 + throw new IllegalArgumentException("Selector and Multiple Selectors are both set");
226 + }
227 +
199 return new MultiPointToSinglePointIntent( 228 return new MultiPointToSinglePointIntent(
200 appId, 229 appId,
201 key, 230 key,
...@@ -204,7 +233,8 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent { ...@@ -204,7 +233,8 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent {
204 ingressPoints, 233 ingressPoints,
205 egressPoint, 234 egressPoint,
206 constraints, 235 constraints,
207 - priority 236 + priority,
237 + ingressSelectors
208 ); 238 );
209 } 239 }
210 } 240 }
...@@ -229,6 +259,14 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent { ...@@ -229,6 +259,14 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent {
229 return egressPoint; 259 return egressPoint;
230 } 260 }
231 261
262 + /**
263 + * Returns the multiple selectors jointly with their connection points.
264 + * @return multiple selectors
265 + */
266 + public Map<ConnectPoint, TrafficSelector> ingressSelectors() {
267 + return ingressSelectors;
268 + }
269 +
232 @Override 270 @Override
233 public String toString() { 271 public String toString() {
234 return MoreObjects.toStringHelper(getClass()) 272 return MoreObjects.toStringHelper(getClass())
...@@ -241,6 +279,7 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent { ...@@ -241,6 +279,7 @@ public final class MultiPointToSinglePointIntent extends ConnectivityIntent {
241 .add("treatment", treatment()) 279 .add("treatment", treatment())
242 .add("ingress", ingressPoints()) 280 .add("ingress", ingressPoints())
243 .add("egress", egressPoint()) 281 .add("egress", egressPoint())
282 + .add("selectors", ingressSelectors())
244 .add("constraints", constraints()) 283 .add("constraints", constraints())
245 .toString(); 284 .toString();
246 } 285 }
......
...@@ -15,8 +15,12 @@ ...@@ -15,8 +15,12 @@
15 */ 15 */
16 package org.onosproject.net.intent; 16 package org.onosproject.net.intent;
17 17
18 +import java.util.Collections;
19 +import java.util.Map;
18 import java.util.Set; 20 import java.util.Set;
19 21
22 +import com.google.common.collect.Maps;
23 +import org.onlab.packet.VlanId;
20 import org.onosproject.core.ApplicationId; 24 import org.onosproject.core.ApplicationId;
21 import org.onosproject.TestApplicationId; 25 import org.onosproject.TestApplicationId;
22 import org.onosproject.net.ConnectPoint; 26 import org.onosproject.net.ConnectPoint;
...@@ -38,6 +42,7 @@ public abstract class ConnectivityIntentTest extends IntentTest { ...@@ -38,6 +42,7 @@ public abstract class ConnectivityIntentTest extends IntentTest {
38 public static final IntentId IID = new IntentId(123); 42 public static final IntentId IID = new IntentId(123);
39 public static final TrafficSelector MATCH = DefaultTrafficSelector.emptySelector(); 43 public static final TrafficSelector MATCH = DefaultTrafficSelector.emptySelector();
40 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();
41 46
42 public static final ConnectPoint P1 = new ConnectPoint(DeviceId.deviceId("111"), PortNumber.portNumber(0x1)); 47 public static final ConnectPoint P1 = new ConnectPoint(DeviceId.deviceId("111"), PortNumber.portNumber(0x1));
43 public static final ConnectPoint P2 = new ConnectPoint(DeviceId.deviceId("222"), PortNumber.portNumber(0x2)); 48 public static final ConnectPoint P2 = new ConnectPoint(DeviceId.deviceId("222"), PortNumber.portNumber(0x2));
...@@ -45,4 +50,18 @@ public abstract class ConnectivityIntentTest extends IntentTest { ...@@ -45,4 +50,18 @@ public abstract class ConnectivityIntentTest extends IntentTest {
45 50
46 public static final Set<ConnectPoint> PS1 = itemSet(new ConnectPoint[]{P1, P3}); 51 public static final Set<ConnectPoint> PS1 = itemSet(new ConnectPoint[]{P1, P3});
47 public static final Set<ConnectPoint> PS2 = itemSet(new ConnectPoint[]{P2, P3}); 52 public static final Set<ConnectPoint> PS2 = itemSet(new ConnectPoint[]{P2, P3});
53 +
54 + public static final TrafficSelector VLANMATCH1 = DefaultTrafficSelector.builder()
55 + .matchVlanId(VlanId.vlanId("2"))
56 + .build();
57 + public static final TrafficSelector VLANMATCH2 = DefaultTrafficSelector.builder()
58 + .matchVlanId(VlanId.vlanId("3"))
59 + .build();
60 +
61 + public static final Map<ConnectPoint, TrafficSelector> VLANMATCHES = Maps.newHashMap();
62 + static {
63 + VLANMATCHES.put(P1, VLANMATCH1);
64 + VLANMATCHES.put(P2, VLANMATCH2);
65 + }
66 +
48 } 67 }
......
...@@ -13,9 +13,12 @@ ...@@ -13,9 +13,12 @@
13 * See the License for the specific language governing permissions and 13 * See the License for the specific language governing permissions and
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 +
16 package org.onosproject.net.intent; 17 package org.onosproject.net.intent;
17 18
19 +import org.junit.Rule;
18 import org.junit.Test; 20 import org.junit.Test;
21 +import org.junit.rules.ExpectedException;
19 22
20 import static org.junit.Assert.assertEquals; 23 import static org.junit.Assert.assertEquals;
21 import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; 24 import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
...@@ -42,6 +45,39 @@ public class MultiPointToSinglePointIntentTest extends ConnectivityIntentTest { ...@@ -42,6 +45,39 @@ public class MultiPointToSinglePointIntentTest extends ConnectivityIntentTest {
42 assertEquals("incorrect egress", P2, intent.egressPoint()); 45 assertEquals("incorrect egress", P2, intent.egressPoint());
43 } 46 }
44 47
48 + @Rule
49 + public ExpectedException wrongMultiple = ExpectedException.none();
50 +
51 + @Test
52 + public void multipleSelectors() {
53 +
54 + MultiPointToSinglePointIntent intent = createFirstMultiple();
55 + assertEquals("incorrect id", APPID, intent.appId());
56 + assertEquals("incorrect match", MATCH, intent.selector());
57 + assertEquals("incorrect ingress", PS1, intent.ingressPoints());
58 + assertEquals("incorrect egress", P2, intent.egressPoint());
59 + assertEquals("incorrect selectors", MATCHES, intent.ingressSelectors());
60 +
61 + intent = createSecondMultiple();
62 + assertEquals("incorrect id", APPID, intent.appId());
63 + assertEquals("incorrect match", VLANMATCH1, intent.selector());
64 + assertEquals("incorrect ingress", PS1, intent.ingressPoints());
65 + assertEquals("incorrect egress", P2, intent.egressPoint());
66 + assertEquals("incorrect selectors", MATCHES, intent.ingressSelectors());
67 +
68 + intent = createThirdMultiple();
69 + assertEquals("incorrect id", APPID, intent.appId());
70 + assertEquals("incorrect match", MATCH, intent.selector());
71 + assertEquals("incorrect ingress", PS1, intent.ingressPoints());
72 + assertEquals("incorrect egress", P2, intent.egressPoint());
73 + assertEquals("incorrect selectors", VLANMATCHES, intent.ingressSelectors());
74 +
75 + wrongMultiple.expect(IllegalArgumentException.class);
76 + wrongMultiple.expectMessage("Selector and Multiple Selectors are both set");
77 + intent = createWrongMultiple();
78 + }
79 +
80 +
45 @Override 81 @Override
46 protected MultiPointToSinglePointIntent createOne() { 82 protected MultiPointToSinglePointIntent createOne() {
47 return MultiPointToSinglePointIntent.builder() 83 return MultiPointToSinglePointIntent.builder()
...@@ -63,4 +99,49 @@ public class MultiPointToSinglePointIntentTest extends ConnectivityIntentTest { ...@@ -63,4 +99,49 @@ public class MultiPointToSinglePointIntentTest extends ConnectivityIntentTest {
63 .egressPoint(P1) 99 .egressPoint(P1)
64 .build(); 100 .build();
65 } 101 }
102 +
103 + protected MultiPointToSinglePointIntent createFirstMultiple() {
104 + return MultiPointToSinglePointIntent.builder()
105 + .appId(APPID)
106 + .selector(MATCH)
107 + .treatment(NOP)
108 + .ingressPoints(PS1)
109 + .egressPoint(P2)
110 + .selectors(MATCHES)
111 + .build();
112 + }
113 +
114 + protected MultiPointToSinglePointIntent createSecondMultiple() {
115 + return MultiPointToSinglePointIntent.builder()
116 + .appId(APPID)
117 + .selector(VLANMATCH1)
118 + .treatment(NOP)
119 + .ingressPoints(PS1)
120 + .egressPoint(P2)
121 + .selectors(MATCHES)
122 + .build();
123 + }
124 +
125 + protected MultiPointToSinglePointIntent createThirdMultiple() {
126 + return MultiPointToSinglePointIntent.builder()
127 + .appId(APPID)
128 + .selector(MATCH)
129 + .treatment(NOP)
130 + .ingressPoints(PS1)
131 + .egressPoint(P2)
132 + .selectors(VLANMATCHES)
133 + .build();
134 + }
135 +
136 + protected MultiPointToSinglePointIntent createWrongMultiple() {
137 + return MultiPointToSinglePointIntent.builder()
138 + .appId(APPID)
139 + .selector(VLANMATCH1)
140 + .treatment(NOP)
141 + .ingressPoints(PS1)
142 + .egressPoint(P2)
143 + .selectors(VLANMATCHES)
144 + .build();
145 + }
146 +
66 } 147 }
......
...@@ -48,6 +48,7 @@ import org.onosproject.net.intent.IntentCompilationException; ...@@ -48,6 +48,7 @@ import org.onosproject.net.intent.IntentCompilationException;
48 import org.onosproject.net.intent.LinkCollectionIntent; 48 import org.onosproject.net.intent.LinkCollectionIntent;
49 49
50 import java.util.List; 50 import java.util.List;
51 +import java.util.Optional;
51 import java.util.Set; 52 import java.util.Set;
52 import java.util.stream.Collectors; 53 import java.util.stream.Collectors;
53 54
...@@ -155,12 +156,15 @@ public class LinkCollectionCompiler<T> { ...@@ -155,12 +156,15 @@ public class LinkCollectionCompiler<T> {
155 * 156 *
156 * @param intent the intent to compile 157 * @param intent the intent to compile
157 * @param inPort the input port 158 * @param inPort the input port
159 + * @param deviceId the current device
158 * @param outPorts the output ports 160 * @param outPorts the output ports
159 * @param ingressPorts the ingress ports 161 * @param ingressPorts the ingress ports
160 * @param egressPorts the egress ports 162 * @param egressPorts the egress ports
161 * @return the forwarding instruction object which encapsulates treatment and selector 163 * @return the forwarding instruction object which encapsulates treatment and selector
162 */ 164 */
163 - protected ForwardingInstructions createForwardingInstructions(LinkCollectionIntent intent, PortNumber inPort, 165 + protected ForwardingInstructions createForwardingInstructions(LinkCollectionIntent intent,
166 + PortNumber inPort,
167 + DeviceId deviceId,
164 Set<PortNumber> outPorts, 168 Set<PortNumber> outPorts,
165 Set<PortNumber> ingressPorts, 169 Set<PortNumber> ingressPorts,
166 Set<PortNumber> egressPorts) { 170 Set<PortNumber> egressPorts) {
...@@ -178,8 +182,27 @@ public class LinkCollectionCompiler<T> { ...@@ -178,8 +182,27 @@ public class LinkCollectionCompiler<T> {
178 intentTreatment = ingressTreatmentBuilder.build(); 182 intentTreatment = ingressTreatmentBuilder.build();
179 183
180 if (ingressPorts.contains(inPort)) { 184 if (ingressPorts.contains(inPort)) {
185 + if (intent.ingressSelectors() != null && !intent.ingressSelectors().isEmpty()) {
186 + /**
187 + * We iterate on the ingress points looking for the connect point
188 + * associated to inPort.
189 + */
190 + Optional<ConnectPoint> connectPoint = intent.ingressPoints()
191 + .stream()
192 + .filter(ingressPoint -> ingressPoint.port().equals(inPort)
193 + && ingressPoint.deviceId().equals(deviceId))
194 + .findFirst();
195 + if (connectPoint.isPresent()) {
196 + selectorBuilder = DefaultTrafficSelector
197 + .builder(intent.ingressSelectors().get(connectPoint.get()));
198 + } else {
199 + throw new IntentCompilationException("Looking for connect point associated to the selector." +
200 + "inPort not in IngressPoints");
201 + }
202 + } else {
181 selectorBuilder = DefaultTrafficSelector.builder(intent.selector()); 203 selectorBuilder = DefaultTrafficSelector.builder(intent.selector());
182 - treatment = intentTreatment; 204 + }
205 + treatment = this.updateBuilder(ingressTreatmentBuilder, selectorBuilder.build()).build();
183 } else { 206 } else {
184 selectorBuilder = this.createSelectorFromFwdInstructions( 207 selectorBuilder = this.createSelectorFromFwdInstructions(
185 new ForwardingInstructions(intentTreatment, intent.selector()) 208 new ForwardingInstructions(intentTreatment, intent.selector())
...@@ -207,6 +230,18 @@ public class LinkCollectionCompiler<T> { ...@@ -207,6 +230,18 @@ public class LinkCollectionCompiler<T> {
207 } 230 }
208 231
209 /** 232 /**
233 + * Update the original builder with the necessary operations
234 + * to have a correct forwarding given an ingress selector.
235 + *
236 + * @param treatmentBuilder the builder to modify
237 + * @return the new treatment created
238 + */
239 + private TrafficTreatment.Builder updateBuilder(TrafficTreatment.Builder treatmentBuilder,
240 + TrafficSelector intentSelector) {
241 + return treatmentBuilder;
242 + }
243 +
244 + /**
210 * Update the selector builder using a L0 instruction. 245 * Update the selector builder using a L0 instruction.
211 * 246 *
212 * @param builder the builder to update 247 * @param builder the builder to update
......
...@@ -98,6 +98,7 @@ public class LinkCollectionIntentCompiler ...@@ -98,6 +98,7 @@ public class LinkCollectionIntentCompiler
98 inPorts.forEach(inport -> { 98 inPorts.forEach(inport -> {
99 ForwardingInstructions instructions = this.createForwardingInstructions(intent, 99 ForwardingInstructions instructions = this.createForwardingInstructions(intent,
100 inport, 100 inport,
101 + deviceId,
101 outPorts, 102 outPorts,
102 copyIngressPorts, 103 copyIngressPorts,
103 copyEgressPorts); 104 copyEgressPorts);
......
...@@ -115,6 +115,7 @@ public class LinkCollectionIntentFlowObjectiveCompiler ...@@ -115,6 +115,7 @@ public class LinkCollectionIntentFlowObjectiveCompiler
115 inPorts.forEach(inport -> { 115 inPorts.forEach(inport -> {
116 ForwardingInstructions instructions = this.createForwardingInstructions(intent, 116 ForwardingInstructions instructions = this.createForwardingInstructions(intent,
117 inport, 117 inport,
118 + deviceId,
118 outPorts, 119 outPorts,
119 copyIngressPorts, 120 copyIngressPorts,
120 copyEgressPorts); 121 copyEgressPorts);
......
...@@ -124,6 +124,7 @@ public class MultiPointToSinglePointIntentCompiler ...@@ -124,6 +124,7 @@ public class MultiPointToSinglePointIntentCompiler
124 .links(Sets.newHashSet(links.values())) 124 .links(Sets.newHashSet(links.values()))
125 .ingressPoints(intent.ingressPoints()) 125 .ingressPoints(intent.ingressPoints())
126 .egressPoints(ImmutableSet.of(intent.egressPoint())) 126 .egressPoints(ImmutableSet.of(intent.egressPoint()))
127 + .ingressSelectors(intent.ingressSelectors())
127 .priority(intent.priority()) 128 .priority(intent.priority())
128 .constraints(intent.constraints()) 129 .constraints(intent.constraints())
129 .build(); 130 .build();
......
...@@ -16,9 +16,11 @@ ...@@ -16,9 +16,11 @@
16 package org.onosproject.net.intent.impl.compiler; 16 package org.onosproject.net.intent.impl.compiler;
17 17
18 import com.google.common.collect.ImmutableSet; 18 import com.google.common.collect.ImmutableSet;
19 +import com.google.common.collect.Maps;
19 import org.junit.After; 20 import org.junit.After;
20 import org.junit.Before; 21 import org.junit.Before;
21 import org.junit.Test; 22 import org.junit.Test;
23 +import org.onlab.packet.VlanId;
22 import org.onosproject.TestApplicationId; 24 import org.onosproject.TestApplicationId;
23 import org.onosproject.cfg.ComponentConfigAdapter; 25 import org.onosproject.cfg.ComponentConfigAdapter;
24 import org.onosproject.core.ApplicationId; 26 import org.onosproject.core.ApplicationId;
...@@ -32,6 +34,8 @@ import org.onosproject.net.flow.DefaultTrafficTreatment; ...@@ -32,6 +34,8 @@ import org.onosproject.net.flow.DefaultTrafficTreatment;
32 import org.onosproject.net.flow.FlowRule; 34 import org.onosproject.net.flow.FlowRule;
33 import org.onosproject.net.flow.TrafficSelector; 35 import org.onosproject.net.flow.TrafficSelector;
34 import org.onosproject.net.flow.TrafficTreatment; 36 import org.onosproject.net.flow.TrafficTreatment;
37 +import org.onosproject.net.flow.criteria.Criteria;
38 +import org.onosproject.net.flow.criteria.Criterion;
35 import org.onosproject.net.intent.FlowRuleIntent; 39 import org.onosproject.net.intent.FlowRuleIntent;
36 import org.onosproject.net.intent.Intent; 40 import org.onosproject.net.intent.Intent;
37 import org.onosproject.net.intent.IntentExtensionService; 41 import org.onosproject.net.intent.IntentExtensionService;
...@@ -41,7 +45,9 @@ import org.onosproject.net.intent.MockIdGenerator; ...@@ -41,7 +45,9 @@ import org.onosproject.net.intent.MockIdGenerator;
41 import java.util.Collection; 45 import java.util.Collection;
42 import java.util.Collections; 46 import java.util.Collections;
43 import java.util.List; 47 import java.util.List;
48 +import java.util.Map;
44 import java.util.Set; 49 import java.util.Set;
50 +import java.util.stream.Collectors;
45 51
46 import static org.easymock.EasyMock.createMock; 52 import static org.easymock.EasyMock.createMock;
47 import static org.easymock.EasyMock.expect; 53 import static org.easymock.EasyMock.expect;
...@@ -62,6 +68,7 @@ public class LinkCollectionIntentCompilerTest { ...@@ -62,6 +68,7 @@ public class LinkCollectionIntentCompilerTest {
62 private final ConnectPoint d2p0 = connectPoint("s2", 0); 68 private final ConnectPoint d2p0 = connectPoint("s2", 0);
63 private final ConnectPoint d2p1 = connectPoint("s2", 1); 69 private final ConnectPoint d2p1 = connectPoint("s2", 1);
64 private final ConnectPoint d3p1 = connectPoint("s3", 1); 70 private final ConnectPoint d3p1 = connectPoint("s3", 1);
71 + private final ConnectPoint d3p2 = connectPoint("s3", 9);
65 private final ConnectPoint d3p0 = connectPoint("s3", 10); 72 private final ConnectPoint d3p0 = connectPoint("s3", 10);
66 private final ConnectPoint d1p0 = connectPoint("s1", 10); 73 private final ConnectPoint d1p0 = connectPoint("s1", 10);
67 74
...@@ -70,15 +77,38 @@ public class LinkCollectionIntentCompilerTest { ...@@ -70,15 +77,38 @@ public class LinkCollectionIntentCompilerTest {
70 DefaultLink.builder().providerId(PID).src(d2p1).dst(d3p1).type(DIRECT).build(), 77 DefaultLink.builder().providerId(PID).src(d2p1).dst(d3p1).type(DIRECT).build(),
71 DefaultLink.builder().providerId(PID).src(d1p1).dst(d3p1).type(DIRECT).build()); 78 DefaultLink.builder().providerId(PID).src(d1p1).dst(d3p1).type(DIRECT).build());
72 79
80 + private final Set<Link> linksMultiple = ImmutableSet.of(
81 + DefaultLink.builder().providerId(PID).src(d3p1).dst(d2p0).type(DIRECT).build());
82 +
73 private final TrafficSelector selector = DefaultTrafficSelector.builder().build(); 83 private final TrafficSelector selector = DefaultTrafficSelector.builder().build();
74 private final TrafficTreatment treatment = DefaultTrafficTreatment.builder().build(); 84 private final TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
75 85
86 + private final VlanId ingressVlan1 = VlanId.vlanId("10");
87 + private final TrafficSelector selectorVlan1 = DefaultTrafficSelector
88 + .builder()
89 + .matchVlanId(ingressVlan1)
90 + .build();
91 +
92 + private final VlanId ingressVlan2 = VlanId.vlanId("20");
93 + private final TrafficSelector selectorVlan2 = DefaultTrafficSelector
94 + .builder()
95 + .matchVlanId(ingressVlan2)
96 + .build();
97 +
98 + private final VlanId egressVlan = VlanId.vlanId("666");
99 + private final TrafficTreatment vlanTreatment = DefaultTrafficTreatment
100 + .builder()
101 + .setVlanId(egressVlan)
102 + .build();
103 +
76 private CoreService coreService; 104 private CoreService coreService;
77 private IntentExtensionService intentExtensionService; 105 private IntentExtensionService intentExtensionService;
78 private IntentConfigurableRegistrator registrator; 106 private IntentConfigurableRegistrator registrator;
79 private IdGenerator idGenerator = new MockIdGenerator(); 107 private IdGenerator idGenerator = new MockIdGenerator();
80 108
81 private LinkCollectionIntent intent; 109 private LinkCollectionIntent intent;
110 + private LinkCollectionIntent intentMultiple;
111 +
82 112
83 private LinkCollectionIntentCompiler sut; 113 private LinkCollectionIntentCompiler sut;
84 114
...@@ -100,6 +130,15 @@ public class LinkCollectionIntentCompilerTest { ...@@ -100,6 +130,15 @@ public class LinkCollectionIntentCompilerTest {
100 .ingressPoints(ImmutableSet.of(d1p1)) 130 .ingressPoints(ImmutableSet.of(d1p1))
101 .egressPoints(ImmutableSet.of(d3p1)) 131 .egressPoints(ImmutableSet.of(d3p1))
102 .build(); 132 .build();
133 + intentMultiple = LinkCollectionIntent.builder()
134 + .appId(APP_ID)
135 + .treatment(vlanTreatment)
136 + .links(linksMultiple)
137 + .ingressPoints(ImmutableSet.of(d3p0, d3p2))
138 + .egressPoints(ImmutableSet.of(d2p1))
139 + .ingressSelectors(this.createIngressSelectors())
140 + .build();
141 +
103 intentExtensionService = createMock(IntentExtensionService.class); 142 intentExtensionService = createMock(IntentExtensionService.class);
104 intentExtensionService.registerCompiler(LinkCollectionIntent.class, sut); 143 intentExtensionService.registerCompiler(LinkCollectionIntent.class, sut);
105 intentExtensionService.unregisterCompiler(LinkCollectionIntent.class); 144 intentExtensionService.unregisterCompiler(LinkCollectionIntent.class);
...@@ -168,4 +207,99 @@ public class LinkCollectionIntentCompilerTest { ...@@ -168,4 +207,99 @@ public class LinkCollectionIntentCompilerTest {
168 207
169 sut.deactivate(); 208 sut.deactivate();
170 } 209 }
210 +
211 + @Test
212 + public void testCompileMultipleSelectors() {
213 + sut.activate();
214 +
215 + List<Intent> compiled = sut.compile(intentMultiple, Collections.emptyList());
216 + assertThat(compiled, hasSize(1));
217 +
218 +
219 + Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
220 + assertThat(rules, hasSize((linksMultiple.size()) + intentMultiple.ingressPoints().size()));
221 +
222 + Set<FlowRule> d3Rules = rules
223 + .parallelStream()
224 + .filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
225 + .collect(Collectors.toSet());
226 + assertThat(d3Rules, hasSize(intentMultiple.ingressPoints().size()));
227 +
228 + FlowRule rule1 = rules.stream()
229 + .filter(rule -> rule.deviceId().equals(d3p0.deviceId())
230 + &&
231 + rule.selector().getCriterion(Criterion.Type.IN_PORT).equals(Criteria.matchInPort(d3p0.port())))
232 + .findFirst()
233 + .get();
234 + assertThat(rule1.selector(), is(
235 + DefaultTrafficSelector
236 + .builder(intentMultiple.selector())
237 + .matchInPort(d3p0.port())
238 + .matchVlanId(ingressVlan1)
239 + .build()
240 + ));
241 + assertThat(rule1.treatment(), is(
242 + DefaultTrafficTreatment
243 + .builder(intentMultiple.treatment())
244 + .setOutput(d3p1.port())
245 + .build()
246 + ));
247 + assertThat(rule1.priority(), is(intentMultiple.priority()));
248 +
249 + FlowRule rule2 = rules.stream()
250 + .filter(rule -> rule.deviceId().equals(d3p0.deviceId())
251 + &&
252 + rule.selector().getCriterion(Criterion.Type.IN_PORT).equals(Criteria.matchInPort(d3p2.port())))
253 + .findFirst()
254 + .get();
255 + assertThat(rule2.selector(), is(
256 + DefaultTrafficSelector
257 + .builder(intentMultiple.selector())
258 + .matchInPort(d3p2.port())
259 + .matchVlanId(ingressVlan2)
260 + .build()
261 + ));
262 + assertThat(rule2.treatment(), is(
263 + DefaultTrafficTreatment
264 + .builder(intentMultiple.treatment())
265 + .setOutput(d3p1.port())
266 + .build()
267 + ));
268 + assertThat(rule1.priority(), is(intentMultiple.priority()));
269 +
270 + Set<FlowRule> d2Rules = rules
271 + .parallelStream()
272 + .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
273 + .collect(Collectors.toSet());
274 + assertThat(d2Rules, hasSize(intentMultiple.egressPoints().size()));
275 +
276 + // We do not need in_port filter
277 + FlowRule rule3 = rules.stream()
278 + .filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
279 + .findFirst()
280 + .get();
281 + assertThat(rule3.selector(), is(
282 + DefaultTrafficSelector
283 + .builder(intentMultiple.selector())
284 + .matchInPort(d2p0.port())
285 + .matchVlanId(egressVlan)
286 + .build()
287 + ));
288 + assertThat(rule3.treatment(), is(
289 + DefaultTrafficTreatment
290 + .builder()
291 + .setOutput(d2p1.port())
292 + .build()
293 + ));
294 + assertThat(rule3.priority(), is(intentMultiple.priority()));
295 +
296 + sut.deactivate();
297 + }
298 +
299 + public Map<ConnectPoint, TrafficSelector> createIngressSelectors() {
300 + Map<ConnectPoint, TrafficSelector> mapToReturn = Maps.newHashMap();
301 + mapToReturn.put(d3p0, selectorVlan1);
302 + mapToReturn.put(d3p2, selectorVlan2);
303 + return mapToReturn;
304 + }
171 } 305 }
......