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
diff --git a/core/api/src/main/java/org/onosproject/net/intent/LinkCollectionIntent.java b/core/api/src/main/java/org/onosproject/net/intent/LinkCollectionIntent.java
index 6a58b80..85bd5df 100644
--- a/core/api/src/main/java/org/onosproject/net/intent/LinkCollectionIntent.java
+++ b/core/api/src/main/java/org/onosproject/net/intent/LinkCollectionIntent.java
@@ -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 @@
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 @@
* @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 @@
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 @@
this.egressPoints = null;
this.egressTreatmentFlag = false;
this.ingressSelectors = null;
+ this.egressTreatments = null;
}
/**
@@ -117,6 +125,7 @@
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 @@
}
/**
+ * 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 @@
constraints,
priority,
egressTreatmentFlag,
- ingressSelectors
+ ingressSelectors,
+ egressTreatments
);
}
}
-
/**
* Returns the set of links that represent the network connections needed
* by this intent.
@@ -274,6 +294,14 @@
}
/**
+ * 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 @@
.add("ingress", ingressPoints())
.add("egress", egressPoints())
.add("selectors", ingressSelectors())
- .add("treatmentOnEgress", applyTreatmentOnEgress())
+ .add("treatments", egressTreatments())
+ .add("treatementOnEgress", applyTreatmentOnEgress())
.toString();
}
}
diff --git a/core/api/src/main/java/org/onosproject/net/intent/SinglePointToMultiPointIntent.java b/core/api/src/main/java/org/onosproject/net/intent/SinglePointToMultiPointIntent.java
index 51dfcb8..4b17c66 100644
--- a/core/api/src/main/java/org/onosproject/net/intent/SinglePointToMultiPointIntent.java
+++ b/core/api/src/main/java/org/onosproject/net/intent/SinglePointToMultiPointIntent.java
@@ -17,14 +17,18 @@
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 @@
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 @@
* @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 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 @@
}
/**
+ * 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 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 @@
ingressPoint,
egressPoints,
constraints,
- priority
+ priority,
+ egressTreatments
);
}
}
@@ -179,6 +212,7 @@
super();
this.ingressPoint = null;
this.egressPoints = null;
+ this.egressTreatments = null;
}
/**
@@ -200,6 +234,14 @@
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 @@
.add("treatment", treatment())
.add("ingress", ingressPoint)
.add("egress", egressPoints)
+ .add("treatments", egressTreatments)
.add("constraints", constraints())
.toString();
}
diff --git a/core/api/src/test/java/org/onosproject/net/intent/ConnectivityIntentTest.java b/core/api/src/test/java/org/onosproject/net/intent/ConnectivityIntentTest.java
index 6e9d68c..9cbe99f 100644
--- a/core/api/src/test/java/org/onosproject/net/intent/ConnectivityIntentTest.java
+++ b/core/api/src/test/java/org/onosproject/net/intent/ConnectivityIntentTest.java
@@ -43,6 +43,7 @@
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 @@
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);
+ }
+
}
diff --git a/core/api/src/test/java/org/onosproject/net/intent/SinglePointToMultiPointIntentTest.java b/core/api/src/test/java/org/onosproject/net/intent/SinglePointToMultiPointIntentTest.java
index b4c5952..f3db2fb 100644
--- a/core/api/src/test/java/org/onosproject/net/intent/SinglePointToMultiPointIntentTest.java
+++ b/core/api/src/test/java/org/onosproject/net/intent/SinglePointToMultiPointIntentTest.java
@@ -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 @@
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 @@
.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();
+ }
+
}