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 @@
package org.onosproject.net.intent;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.google.common.annotations.Beta;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.Link;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableSet;
/**
* Abstraction of a connectivity intent that is implemented by a set of path
......@@ -41,12 +42,15 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
private final Set<ConnectPoint> ingressPoints;
private final Set<ConnectPoint> egressPoints;
private final boolean egressTreatmentFlag;
/**
* To manage multiple selectors use case.
*/
private final Map<ConnectPoint, TrafficSelector> ingressSelectors;
private final boolean egressTreatmentFlag;
/**
* To manage multiple treatments use case.
*/
private final Map<ConnectPoint, TrafficTreatment> egressTreatments;
/**
* Creates a new actionable intent capable of funneling the selected
......@@ -64,6 +68,7 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
* @param priority priority to use for the flows generated by this intent
* @param egressTreatment true if treatment should be applied by the egress device
* @param ingressSelectors map to store the association ingress to selector
* @param egressTreatments map to store the association egress to treatment
* @throws NullPointerException {@code path} is null
*/
private LinkCollectionIntent(ApplicationId appId,
......@@ -76,13 +81,15 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
List<Constraint> constraints,
int priority,
boolean egressTreatment,
Map<ConnectPoint, TrafficSelector> ingressSelectors) {
Map<ConnectPoint, TrafficSelector> ingressSelectors,
Map<ConnectPoint, TrafficTreatment> egressTreatments) {
super(appId, key, resources(links), selector, treatment, constraints, priority);
this.links = links;
this.ingressPoints = ingressPoints;
this.egressPoints = egressPoints;
this.egressTreatmentFlag = egressTreatment;
this.ingressSelectors = ingressSelectors;
this.egressTreatments = egressTreatments;
}
/**
......@@ -95,6 +102,7 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
this.egressPoints = null;
this.egressTreatmentFlag = false;
this.ingressSelectors = null;
this.egressTreatments = null;
}
/**
......@@ -117,6 +125,7 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
Set<ConnectPoint> ingressPoints;
Set<ConnectPoint> egressPoints;
Map<ConnectPoint, TrafficSelector> ingressSelectors = ImmutableMap.of();
Map<ConnectPoint, TrafficTreatment> egressTreatments = ImmutableMap.of();
boolean egressTreatmentFlag;
private Builder() {
......@@ -189,6 +198,17 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
}
/**
* Sets the map egress treatments to connection points of the intent.
*
* @param egressTreatments maps connection point to traffic treatment
* @return this builder
*/
public Builder egressTreatments(Map<ConnectPoint, TrafficTreatment> egressTreatments) {
this.egressTreatments = ImmutableMap.copyOf(egressTreatments);
return this;
}
/**
* Sets the links of the link collection intent
* that will be built.
*
......@@ -231,12 +251,12 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
constraints,
priority,
egressTreatmentFlag,
ingressSelectors
ingressSelectors,
egressTreatments
);
}
}
/**
* Returns the set of links that represent the network connections needed
* by this intent.
......@@ -274,6 +294,14 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
}
/**
* Returns the multiple treatments jointly with their connection points.
* @return multiple treatments
*/
public Map<ConnectPoint, TrafficTreatment> egressTreatments() {
return egressTreatments;
}
/**
* Returns whether treatment should be applied on egress.
*
* @return the egress treatment flag
......@@ -296,7 +324,8 @@ public final class LinkCollectionIntent extends ConnectivityIntent {
.add("ingress", ingressPoints())
.add("egress", egressPoints())
.add("selectors", ingressSelectors())
.add("treatmentOnEgress", applyTreatmentOnEgress())
.add("treatments", egressTreatments())
.add("treatementOnEgress", applyTreatmentOnEgress())
.toString();
}
}
......
......@@ -17,14 +17,18 @@ package org.onosproject.net.intent;
import com.google.common.annotations.Beta;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.List;
......@@ -39,6 +43,10 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent {
private final ConnectPoint ingressPoint;
private final Set<ConnectPoint> egressPoints;
/**
* To manage multiple treatments use case.
*/
private final Map<ConnectPoint, TrafficTreatment> egressTreatments;
/**
* Creates a new single-to-multi point connectivity intent.
......@@ -51,27 +59,32 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent {
* @param egressPoints set of ports on which traffic will egress
* @param constraints constraints to apply to the intent
* @param priority priority to use for flows generated by this intent
* @param egressTreatments map to store the association egress to treatment
* @throws NullPointerException if {@code ingressPoint} or
* {@code egressPoints} is null
* @throws IllegalArgumentException if the size of {@code egressPoints} is
* not more than 1
*/
private SinglePointToMultiPointIntent(ApplicationId appId,
Key key,
TrafficSelector selector, TrafficTreatment treatment,
ConnectPoint ingressPoint, Set<ConnectPoint> egressPoints,
List<Constraint> constraints,
int priority) {
super(appId, key, Collections.emptyList(), selector, treatment, constraints,
priority);
Key key,
TrafficSelector selector,
TrafficTreatment treatment,
ConnectPoint ingressPoint,
Set<ConnectPoint> egressPoints,
List<Constraint> constraints,
int priority,
Map<ConnectPoint, TrafficTreatment> egressTreatments) {
super(appId, key, ImmutableList.of(), selector, treatment, constraints,
priority);
checkNotNull(egressPoints);
checkNotNull(ingressPoint);
checkArgument(!egressPoints.isEmpty(), "Egress point set cannot be empty");
checkArgument(!egressPoints.contains(ingressPoint),
"Set of egresses should not contain ingress (ingress: %s)", ingressPoint);
this.ingressPoint = checkNotNull(ingressPoint);
this.egressPoints = egressPoints;
this.ingressPoint = ingressPoint;
this.egressPoints = Sets.newHashSet(egressPoints);
this.egressTreatments = egressTreatments;
}
/**
......@@ -92,6 +105,7 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent {
public static final class Builder extends ConnectivityIntent.Builder {
ConnectPoint ingressPoint;
Set<ConnectPoint> egressPoints;
Map<ConnectPoint, TrafficTreatment> egressTreatments = ImmutableMap.of();
private Builder() {
// Hide constructor
......@@ -152,6 +166,18 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent {
}
/**
* Sets the treatments of the single point to multi point intent
* that will be built.
*
* @param egressTreatments the multiple treatments
* @return this builder
*/
public Builder treatments(Map<ConnectPoint, TrafficTreatment> egressTreatments) {
this.egressTreatments = ImmutableMap.copyOf(egressTreatments);
return this;
}
/**
* Builds a single point to multi point intent from the
* accumulated parameters.
*
......@@ -159,6 +185,12 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent {
*/
public SinglePointToMultiPointIntent build() {
if (treatment != null && !treatment.allInstructions().isEmpty() &&
!treatment.equals(DefaultTrafficTreatment.emptyTreatment()) &&
egressTreatments != null && !egressTreatments.isEmpty()) {
throw new IllegalArgumentException("Treatment and Multiple Treatments are both set");
}
return new SinglePointToMultiPointIntent(
appId,
key,
......@@ -167,7 +199,8 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent {
ingressPoint,
egressPoints,
constraints,
priority
priority,
egressTreatments
);
}
}
......@@ -179,6 +212,7 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent {
super();
this.ingressPoint = null;
this.egressPoints = null;
this.egressTreatments = null;
}
/**
......@@ -200,6 +234,14 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent {
return egressPoints;
}
/**
* Returns the multiple treatments jointly with their connection points.
* @return multiple treatments
*/
public Map<ConnectPoint, TrafficTreatment> egressTreatments() {
return egressTreatments;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
......@@ -212,6 +254,7 @@ public final class SinglePointToMultiPointIntent extends ConnectivityIntent {
.add("treatment", treatment())
.add("ingress", ingressPoint)
.add("egress", egressPoints)
.add("treatments", egressTreatments)
.add("constraints", constraints())
.toString();
}
......
......@@ -43,6 +43,7 @@ public abstract class ConnectivityIntentTest extends IntentTest {
public static final TrafficSelector MATCH = DefaultTrafficSelector.emptySelector();
public static final TrafficTreatment NOP = DefaultTrafficTreatment.emptyTreatment();
public static final Map<ConnectPoint, TrafficSelector> MATCHES = Collections.emptyMap();
public static final Map<ConnectPoint, TrafficTreatment> TREATMENTS = Collections.emptyMap();
public static final ConnectPoint P1 = new ConnectPoint(DeviceId.deviceId("111"), PortNumber.portNumber(0x1));
public static final ConnectPoint P2 = new ConnectPoint(DeviceId.deviceId("222"), PortNumber.portNumber(0x2));
......@@ -64,4 +65,17 @@ public abstract class ConnectivityIntentTest extends IntentTest {
VLANMATCHES.put(P2, VLANMATCH2);
}
public static final TrafficTreatment VLANACTION1 = DefaultTrafficTreatment.builder()
.setVlanId(VlanId.vlanId("2"))
.build();
public static final TrafficTreatment VLANACTION2 = DefaultTrafficTreatment.builder()
.setVlanId(VlanId.vlanId("3"))
.build();
public static final Map<ConnectPoint, TrafficTreatment> VLANACTIONS = Maps.newHashMap();
static {
VLANACTIONS.put(P1, VLANACTION1);
VLANACTIONS.put(P2, VLANACTION2);
}
}
......
......@@ -15,7 +15,9 @@
*/
package org.onosproject.net.intent;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import static org.junit.Assert.assertEquals;
import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
......@@ -42,6 +44,41 @@ public class SinglePointToMultiPointIntentTest extends ConnectivityIntentTest {
assertEquals("incorrect egress", PS2, intent.egressPoints());
}
@Rule
public ExpectedException wrongMultiple = ExpectedException.none();
@Test
public void multipleTreatments() {
SinglePointToMultiPointIntent intent = createFirstMultiple();
assertEquals("incorrect id", APPID, intent.appId());
assertEquals("incorrect match", MATCH, intent.selector());
assertEquals("incorrect ingress", P1, intent.ingressPoint());
assertEquals("incorrect egress", PS2, intent.egressPoints());
assertEquals("incorrect treatment", NOP, intent.treatment());
assertEquals("incorrect treatments", TREATMENTS, intent.egressTreatments());
intent = createSecondMultiple();
assertEquals("incorrect id", APPID, intent.appId());
assertEquals("incorrect match", MATCH, intent.selector());
assertEquals("incorrect ingress", P1, intent.ingressPoint());
assertEquals("incorrect egress", PS2, intent.egressPoints());
assertEquals("incorrect treatment", VLANACTION1, intent.treatment());
assertEquals("incorrect selectors", TREATMENTS, intent.egressTreatments());
intent = createThirdMultiple();
assertEquals("incorrect id", APPID, intent.appId());
assertEquals("incorrect match", MATCH, intent.selector());
assertEquals("incorrect ingress", P1, intent.ingressPoint());
assertEquals("incorrect egress", PS2, intent.egressPoints());
assertEquals("incorrect treatment", NOP, intent.treatment());
assertEquals("incorrect selectors", VLANACTIONS, intent.egressTreatments());
wrongMultiple.expect(IllegalArgumentException.class);
wrongMultiple.expectMessage("Treatment and Multiple Treatments are both set");
intent = createWrongMultiple();
}
@Override
protected SinglePointToMultiPointIntent createOne() {
return SinglePointToMultiPointIntent.builder()
......@@ -63,4 +100,50 @@ public class SinglePointToMultiPointIntentTest extends ConnectivityIntentTest {
.egressPoints(PS1)
.build();
}
protected SinglePointToMultiPointIntent createFirstMultiple() {
return SinglePointToMultiPointIntent.builder()
.appId(APPID)
.selector(MATCH)
.treatment(NOP)
.ingressPoint(P1)
.egressPoints(PS2)
.treatments(TREATMENTS)
.build();
}
protected SinglePointToMultiPointIntent createSecondMultiple() {
return SinglePointToMultiPointIntent.builder()
.appId(APPID)
.selector(MATCH)
.treatment(VLANACTION1)
.ingressPoint(P1)
.egressPoints(PS2)
.treatments(TREATMENTS)
.build();
}
protected SinglePointToMultiPointIntent createThirdMultiple() {
return SinglePointToMultiPointIntent.builder()
.appId(APPID)
.selector(MATCH)
.treatment(NOP)
.ingressPoint(P1)
.egressPoints(PS2)
.treatments(VLANACTIONS)
.build();
}
protected SinglePointToMultiPointIntent createWrongMultiple() {
return SinglePointToMultiPointIntent.builder()
.appId(APPID)
.selector(MATCH)
.treatment(VLANACTION1)
.ingressPoint(P1)
.egressPoints(PS2)
.treatments(VLANACTIONS)
.build();
}
}
......
......@@ -27,6 +27,7 @@ import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.flow.instructions.Instruction;
import org.onosproject.net.flow.instructions.L0ModificationInstruction;
import org.onosproject.net.flow.instructions.L1ModificationInstruction;
import org.onosproject.net.flow.instructions.L2ModificationInstruction;
......@@ -211,10 +212,29 @@ public class LinkCollectionCompiler<T> {
}
} else {
if (outPorts.stream().allMatch(egressPorts::contains)) {
TrafficTreatment.Builder egressTreatmentBuilder =
DefaultTrafficTreatment.builder(intent.treatment());
outPorts.forEach(egressTreatmentBuilder::setOutput);
TrafficTreatment.Builder egressTreatmentBuilder = DefaultTrafficTreatment.builder();
if (intent.egressTreatments() != null && !intent.egressTreatments().isEmpty()) {
for (PortNumber outPort : outPorts) {
Optional<ConnectPoint> connectPoint = intent.egressPoints()
.stream()
.filter(egressPoint -> egressPoint.port().equals(outPort)
&& egressPoint.deviceId().equals(deviceId))
.findFirst();
if (connectPoint.isPresent()) {
TrafficTreatment egressTreatment = intent.egressTreatments().get(connectPoint.get());
this.addTreatment(egressTreatmentBuilder, egressTreatment);
egressTreatmentBuilder = this.updateBuilder(egressTreatmentBuilder, intent.selector());
egressTreatmentBuilder.setOutput(outPort);
} else {
throw new IntentCompilationException("Looking for connect point associated to " +
"the treatment. outPort not in egressPoints");
}
}
} else {
egressTreatmentBuilder = this
.updateBuilder(DefaultTrafficTreatment.builder(intent.treatment()), intent.selector());
outPorts.forEach(egressTreatmentBuilder::setOutput);
}
selectorBuilder = DefaultTrafficSelector.builder(intent.selector());
treatment = egressTreatmentBuilder.build();
} else {
......@@ -230,10 +250,34 @@ public class LinkCollectionCompiler<T> {
}
/**
* Update a builder using a treatment.
* @param builder the builder to update
* @param treatment the treatment to add
* @return the new builder
*/
private TrafficTreatment.Builder addTreatment(TrafficTreatment.Builder builder, TrafficTreatment treatment) {
builder.deferred();
for (Instruction instruction : treatment.deferred()) {
builder.add(instruction);
}
builder.immediate();
for (Instruction instruction : treatment.immediate()) {
builder.add(instruction);
}
return builder;
}
/**
* Update the original builder with the necessary operations
* to have a correct forwarding given an ingress selector.
* TODO
* This means that if the ingress selectors match on different vlanids and
* the egress treatment rewrite the vlanid the forwarding works
* but if we need to push for example an mpls label at the egress
* we need to implement properly this method.
*
* @param treatmentBuilder the builder to modify
* @param intentSelector the intent selector to use as input
* @return the new treatment created
*/
private TrafficTreatment.Builder updateBuilder(TrafficTreatment.Builder treatmentBuilder,
......
......@@ -34,6 +34,8 @@ import org.onosproject.net.intent.FlowRuleIntent;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentCompiler;
import org.onosproject.net.intent.LinkCollectionIntent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Collections;
......@@ -48,6 +50,9 @@ public class LinkCollectionIntentCompiler
extends LinkCollectionCompiler<FlowRule>
implements IntentCompiler<LinkCollectionIntent> {
private static Logger log = LoggerFactory.getLogger(LinkCollectionIntentCompiler.class);
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected IntentConfigurableRegistrator registrator;
......
......@@ -77,6 +77,7 @@ public class SinglePointToMultiPointIntentCompiler
.priority(intent.priority())
.applyTreatmentOnEgress(true)
.constraints(intent.constraints())
.egressTreatments(intent.egressTreatments())
.build();
return Collections.singletonList(result);
......
......@@ -64,13 +64,18 @@ public class LinkCollectionIntentCompilerTest {
private final ApplicationId appId = new TestApplicationId("test");
private final ConnectPoint d1p1 = connectPoint("s1", 0);
private final ConnectPoint d1p1 = connectPoint("s1", 1);
private final ConnectPoint d2p0 = connectPoint("s2", 0);
private final ConnectPoint d2p1 = connectPoint("s2", 1);
private final ConnectPoint d2p2 = connectPoint("s2", 2);
private final ConnectPoint d2p3 = connectPoint("s2", 3);
private final ConnectPoint d3p1 = connectPoint("s3", 1);
private final ConnectPoint d3p2 = connectPoint("s3", 9);
private final ConnectPoint d3p0 = connectPoint("s3", 10);
private final ConnectPoint d1p0 = connectPoint("s1", 10);
private final ConnectPoint d4p1 = connectPoint("s4", 1);
private final ConnectPoint d4p0 = connectPoint("s4", 10);
private final Set<Link> links = ImmutableSet.of(
DefaultLink.builder().providerId(PID).src(d1p1).dst(d2p0).type(DIRECT).build(),
......@@ -80,6 +85,11 @@ public class LinkCollectionIntentCompilerTest {
private final Set<Link> linksMultiple = ImmutableSet.of(
DefaultLink.builder().providerId(PID).src(d3p1).dst(d2p0).type(DIRECT).build());
private final Set<Link> linksMultiple2 = ImmutableSet.of(
DefaultLink.builder().providerId(PID).src(d2p0).dst(d1p1).type(DIRECT).build(),
DefaultLink.builder().providerId(PID).src(d2p1).dst(d3p1).type(DIRECT).build(),
DefaultLink.builder().providerId(PID).src(d2p2).dst(d4p1).type(DIRECT).build());
private final TrafficSelector selector = DefaultTrafficSelector.builder().build();
private final TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
......@@ -101,14 +111,40 @@ public class LinkCollectionIntentCompilerTest {
.setVlanId(egressVlan)
.build();
private final VlanId ingressVlan = VlanId.vlanId("10");
private final TrafficSelector vlanSelector = DefaultTrafficSelector
.builder()
.matchVlanId(ingressVlan)
.build();
private final VlanId egressVlan1 = VlanId.vlanId("20");
private final TrafficTreatment vlanTreatment1 = DefaultTrafficTreatment
.builder()
.setVlanId(egressVlan1)
.build();
private final VlanId egressVlan2 = VlanId.vlanId("666");
private final TrafficTreatment vlanTreatment2 = DefaultTrafficTreatment
.builder()
.setVlanId(egressVlan2)
.build();
private final VlanId egressVlan3 = VlanId.vlanId("69");
private final TrafficTreatment vlanTreatment3 = DefaultTrafficTreatment
.builder()
.setVlanId(egressVlan3)
.build();
private CoreService coreService;
private IntentExtensionService intentExtensionService;
private IntentConfigurableRegistrator registrator;
private IdGenerator idGenerator = new MockIdGenerator();
private LinkCollectionIntent intent;
private LinkCollectionIntent intentMultiple;
private LinkCollectionIntent intentMultipleSelectors;
private LinkCollectionIntent intentMultipleTreatments;
private LinkCollectionIntent intentMultipleTreatments2;
private LinkCollectionIntentCompiler sut;
......@@ -130,7 +166,7 @@ public class LinkCollectionIntentCompilerTest {
.ingressPoints(ImmutableSet.of(d1p1))
.egressPoints(ImmutableSet.of(d3p1))
.build();
intentMultiple = LinkCollectionIntent.builder()
intentMultipleSelectors = LinkCollectionIntent.builder()
.appId(APP_ID)
.treatment(vlanTreatment)
.links(linksMultiple)
......@@ -138,6 +174,24 @@ public class LinkCollectionIntentCompilerTest {
.egressPoints(ImmutableSet.of(d2p1))
.ingressSelectors(this.createIngressSelectors())
.build();
intentMultipleTreatments = LinkCollectionIntent.builder()
.appId(APP_ID)
.selector(vlanSelector)
.links(linksMultiple)
.ingressPoints(ImmutableSet.of(d3p0))
.egressPoints(ImmutableSet.of(d2p1, d2p2))
.egressTreatments(this.createEgressTreatments())
.applyTreatmentOnEgress(true)
.build();
intentMultipleTreatments2 = LinkCollectionIntent.builder()
.appId(APP_ID)
.selector(vlanSelector)
.links(linksMultiple2)
.ingressPoints(ImmutableSet.of(d2p3))
.egressPoints(ImmutableSet.of(d1p0, d3p0, d4p0))
.egressTreatments(this.createEgressTreatments2())
.applyTreatmentOnEgress(true)
.build();
intentExtensionService = createMock(IntentExtensionService.class);
intentExtensionService.registerCompiler(LinkCollectionIntent.class, sut);
......@@ -208,22 +262,22 @@ public class LinkCollectionIntentCompilerTest {
sut.deactivate();
}
@Test
@Test
public void testCompileMultipleSelectors() {
sut.activate();
List<Intent> compiled = sut.compile(intentMultiple, Collections.emptyList());
List<Intent> compiled = sut.compile(intentMultipleSelectors, Collections.emptyList());
assertThat(compiled, hasSize(1));
Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
assertThat(rules, hasSize((linksMultiple.size()) + intentMultiple.ingressPoints().size()));
assertThat(rules, hasSize((linksMultiple.size()) + intentMultipleSelectors.ingressPoints().size()));
Set<FlowRule> d3Rules = rules
.parallelStream()
.filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
.collect(Collectors.toSet());
assertThat(d3Rules, hasSize(intentMultiple.ingressPoints().size()));
assertThat(d3Rules, hasSize(intentMultipleSelectors.ingressPoints().size()));
FlowRule rule1 = rules.stream()
.filter(rule -> rule.deviceId().equals(d3p0.deviceId())
......@@ -233,18 +287,18 @@ public class LinkCollectionIntentCompilerTest {
.get();
assertThat(rule1.selector(), is(
DefaultTrafficSelector
.builder(intentMultiple.selector())
.builder(intentMultipleSelectors.selector())
.matchInPort(d3p0.port())
.matchVlanId(ingressVlan1)
.build()
));
assertThat(rule1.treatment(), is(
DefaultTrafficTreatment
.builder(intentMultiple.treatment())
.builder(intentMultipleSelectors.treatment())
.setOutput(d3p1.port())
.build()
));
assertThat(rule1.priority(), is(intentMultiple.priority()));
assertThat(rule1.priority(), is(intentMultipleSelectors.priority()));
FlowRule rule2 = rules.stream()
.filter(rule -> rule.deviceId().equals(d3p0.deviceId())
......@@ -254,24 +308,24 @@ public class LinkCollectionIntentCompilerTest {
.get();
assertThat(rule2.selector(), is(
DefaultTrafficSelector
.builder(intentMultiple.selector())
.builder(intentMultipleSelectors.selector())
.matchInPort(d3p2.port())
.matchVlanId(ingressVlan2)
.build()
));
assertThat(rule2.treatment(), is(
DefaultTrafficTreatment
.builder(intentMultiple.treatment())
.builder(intentMultipleSelectors.treatment())
.setOutput(d3p1.port())
.build()
));
assertThat(rule1.priority(), is(intentMultiple.priority()));
assertThat(rule2.priority(), is(intentMultipleSelectors.priority()));
Set<FlowRule> d2Rules = rules
.parallelStream()
.filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
.collect(Collectors.toSet());
assertThat(d2Rules, hasSize(intentMultiple.egressPoints().size()));
assertThat(d2Rules, hasSize(intentMultipleSelectors.egressPoints().size()));
// We do not need in_port filter
FlowRule rule3 = rules.stream()
......@@ -280,7 +334,7 @@ public class LinkCollectionIntentCompilerTest {
.get();
assertThat(rule3.selector(), is(
DefaultTrafficSelector
.builder(intentMultiple.selector())
.builder(intentMultipleSelectors.selector())
.matchInPort(d2p0.port())
.matchVlanId(egressVlan)
.build()
......@@ -291,15 +345,216 @@ public class LinkCollectionIntentCompilerTest {
.setOutput(d2p1.port())
.build()
));
assertThat(rule3.priority(), is(intentMultiple.priority()));
assertThat(rule3.priority(), is(intentMultipleSelectors.priority()));
sut.deactivate();
}
@Test
public void testCompileMultipleTreatments() {
sut.activate();
List<Intent> compiled = sut.compile(intentMultipleTreatments, Collections.emptyList());
assertThat(compiled, hasSize(1));
Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
assertThat(rules, hasSize((linksMultiple.size() + intentMultipleTreatments.egressPoints().size())));
Set<FlowRule> d3Rules = rules
.parallelStream()
.filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
.collect(Collectors.toSet());
assertThat(d3Rules, hasSize(intentMultipleTreatments.ingressPoints().size()));
FlowRule rule1 = rules.stream()
.filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
.findFirst()
.get();
assertThat(rule1.selector(), is(
DefaultTrafficSelector
.builder(intentMultipleTreatments.selector())
.matchInPort(d3p0.port())
.matchVlanId(ingressVlan)
.build()
));
assertThat(rule1.treatment(), is(
DefaultTrafficTreatment
.builder(intentMultipleTreatments.treatment())
.setOutput(d3p1.port())
.build()
));
assertThat(rule1.priority(), is(intentMultipleTreatments.priority()));
Set<FlowRule> d2Rules = rules
.parallelStream()
.filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
.collect(Collectors.toSet());
assertThat(d2Rules, hasSize(1));
FlowRule rule2 = rules.stream()
.filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
.findFirst()
.get();
assertThat(rule2.selector(), is(
DefaultTrafficSelector
.builder(intentMultipleTreatments.selector())
.matchInPort(d2p0.port())
.matchVlanId(ingressVlan)
.build()
));
assertThat(rule2.treatment(), is(
DefaultTrafficTreatment
.builder(intentMultipleTreatments.treatment())
.setVlanId(egressVlan1)
.setOutput(d2p1.port())
.setVlanId(egressVlan2)
.setOutput(d2p2.port())
.build()
));
assertThat(rule2.priority(), is(intentMultipleTreatments.priority()));
}
@Test
public void testCompileMultipleTreatments2() {
sut.activate();
List<Intent> compiled = sut.compile(intentMultipleTreatments2, Collections.emptyList());
assertThat(compiled, hasSize(1));
Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
assertThat(rules, hasSize((linksMultiple2.size() + intentMultipleTreatments2.egressPoints().size())));
Set<FlowRule> d2Rules = rules
.parallelStream()
.filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
.collect(Collectors.toSet());
assertThat(d2Rules, hasSize(1));
FlowRule rule1 = rules.stream()
.filter(rule -> rule.deviceId().equals(d2p0.deviceId()))
.findFirst()
.get();
assertThat(rule1.selector(), is(
DefaultTrafficSelector
.builder(intentMultipleTreatments.selector())
.matchInPort(d2p3.port())
.matchVlanId(ingressVlan)
.build()
));
assertThat(rule1.treatment(), is(
DefaultTrafficTreatment
.builder(intentMultipleTreatments.treatment())
.setOutput(d2p0.port())
.setOutput(d2p1.port())
.setOutput(d2p2.port())
.build()
));
assertThat(rule1.priority(), is(intentMultipleTreatments.priority()));
Set<FlowRule> d1Rules = rules
.parallelStream()
.filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
.collect(Collectors.toSet());
assertThat(d1Rules, hasSize(1));
FlowRule rule2 = rules.stream()
.filter(rule -> rule.deviceId().equals(d1p0.deviceId()))
.findFirst()
.get();
assertThat(rule2.selector(), is(
DefaultTrafficSelector
.builder(intentMultipleTreatments2.selector())
.matchInPort(d1p1.port())
.matchVlanId(ingressVlan)
.build()
));
assertThat(rule2.treatment(), is(
DefaultTrafficTreatment
.builder(intentMultipleTreatments2.treatment())
.setVlanId(egressVlan1)
.setOutput(d1p0.port())
.build()
));
assertThat(rule2.priority(), is(intentMultipleTreatments.priority()));
Set<FlowRule> d3Rules = rules
.parallelStream()
.filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
.collect(Collectors.toSet());
assertThat(d3Rules, hasSize(1));
FlowRule rule3 = rules.stream()
.filter(rule -> rule.deviceId().equals(d3p0.deviceId()))
.findFirst()
.get();
assertThat(rule3.selector(), is(
DefaultTrafficSelector
.builder(intentMultipleTreatments2.selector())
.matchInPort(d3p1.port())
.matchVlanId(ingressVlan)
.build()
));
assertThat(rule3.treatment(), is(
DefaultTrafficTreatment
.builder(intentMultipleTreatments2.treatment())
.setVlanId(egressVlan2)
.setOutput(d3p0.port())
.build()
));
assertThat(rule3.priority(), is(intentMultipleTreatments.priority()));
Set<FlowRule> d4Rules = rules
.parallelStream()
.filter(rule -> rule.deviceId().equals(d4p0.deviceId()))
.collect(Collectors.toSet());
assertThat(d4Rules, hasSize(1));
FlowRule rule4 = rules.stream()
.filter(rule -> rule.deviceId().equals(d4p0.deviceId()))
.findFirst()
.get();
assertThat(rule4.selector(), is(
DefaultTrafficSelector
.builder(intentMultipleTreatments2.selector())
.matchInPort(d4p1.port())
.matchVlanId(ingressVlan)
.build()
));
assertThat(rule4.treatment(), is(
DefaultTrafficTreatment
.builder(intentMultipleTreatments2.treatment())
.setVlanId(egressVlan3)
.setOutput(d4p0.port())
.build()
));
assertThat(rule4.priority(), is(intentMultipleTreatments.priority()));
}
public Map<ConnectPoint, TrafficTreatment> createEgressTreatments() {
Map<ConnectPoint, TrafficTreatment> mapToReturn = Maps.newHashMap();
mapToReturn.put(d2p1, vlanTreatment1);
mapToReturn.put(d2p2, vlanTreatment2);
return mapToReturn;
}
public Map<ConnectPoint, TrafficTreatment> createEgressTreatments2() {
Map<ConnectPoint, TrafficTreatment> mapToReturn = Maps.newHashMap();
mapToReturn.put(d1p0, vlanTreatment1);
mapToReturn.put(d3p0, vlanTreatment2);
mapToReturn.put(d4p0, vlanTreatment3);
return mapToReturn;
}
public Map<ConnectPoint, TrafficSelector> createIngressSelectors() {
Map<ConnectPoint, TrafficSelector> mapToReturn = Maps.newHashMap();
mapToReturn.put(d3p0, selectorVlan1);
mapToReturn.put(d3p2, selectorVlan2);
return mapToReturn;
}
}
......