Introduces Virtual Circuit functionality for SDX-L2
Changes:
- Implements commands: sdxl2vc, sdxl2vc-add, sdxl2vc-list, sdxl2vc-remove
- Custom exceptions handled at the VC manager
- Updated README
- Updated unit tests
- Grouped some documentation and code
- Reduced checkstyle warnings
Change-Id: I4cb211dcfd1f3517f4e594c1cc1c816f9c3cdbe3
diff --git a/sdx-l2/README.md b/sdx-l2/README.md
index 8b25f24..397f4f8 100644
--- a/sdx-l2/README.md
+++ b/sdx-l2/README.md
@@ -5,6 +5,7 @@
SDX-L2 is an application for ONOS project which can provide layer 2 connectivity between edge ports of a given SDN network.
+
License
=======
@@ -13,16 +14,13 @@
Information can be found here:
[Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0).
-Tips
-==============
-
-TBD.
SDX-L2 dependencies
=============================
SDX-L2 implements its own ARP/NDP handler, it is important to disable the ONOS ARP/NDP handler.
+
SDX-L2 installation
=============================
@@ -38,9 +36,13 @@
onos-app $OC1 install target/onos-app-sdx-l2-1.7.0-SNAPSHOT.oar
-SDX-L2 cli commands
+
+SDX-L2 CLI commands
=============================
+General
+-----------------------------
+
- Create a named SDX:
sdxl2-add $sdxname
@@ -56,51 +58,149 @@
sdxl2-list
-- Create a named SDX-L2 connection point:
+Connection Points (CP)
+-----------------------------
- sdxl2cp-add [-ce_mac] $mac $sdxname $connectionpoint $vlans $sdxcpname
+- Create a named SDX-L2 CP:
+ sdxl2cp-add [-ce_mac $mac] $sdxname $connectionpoint $sdxcpname [$vlans]
-- Remove a named SDX-L2 connection point:
+ where $vlans can define:
+ - explicit VLANs, ranges or a combination of both: 5,10-15
+ - all port: -1 (or just ignore)
+
+ *note that CPs must have same number of VLANs in order to establish a VC*
+
+- Remove a named SDX-L2 CP:
sdxl2cp-remove $sdxcpname
-- List all the active SDX-L2 connection points or all the active SDX connection points related to an SDX:
-
- sdxl2cps-list [$sdxname]
-
-
-- Get the information of an SDX-L2 connection point:
+- Get the information of an SDX-L2 CP:
sdxl2cp $sdxcpname
-<!---
-NOT YET MERGED!!!
+- List all active SDX-L2 CPs or all active SDX CPs related to an SDX:
-- Create a VC between two connection points:
+ sdxl2cp-list [$sdxname]
- add-sdxl2vc $sdxname $sdxcp1 $sdxcp2
+
+Virtual Circuits (VC)
+-----------------------------
+
+- Create a VC between two CPs:
+
+ sdxl2vc-add $sdxname $sdxcp1 $sdxcp2
- Remove a named VC:
- remove-sdxl2vc $sdxcname
+ sdxl2vc-remove $sdxcname
-- List all the active layer2 virtual circuit or all the layer2 vc related to an SDX:
-
- list-sdxl2vcs [$sdxname]
-
-
-- Get the information of a layer 2 virtual circuit:
+- Get the information of a L2 VC:
sdxl2vc $sdxvcname
-SDXL2 GUI
+
+- List all active L2 VCs or all L2 VCs related to an SDX:
+
+ sdxl2vc-list [$sdxname]
+
+
+SDX-L2 usage examples
=============================
-- TBD
+- Create a named SDX-L2:
---->
\ No newline at end of file
+ onos> sdxl2:sdxl2-add SDXL2Test
+ onos> sdxl2:sdxl2-list
+
+ SDXL2
+ --------------
+ SDXL2Test
+
+
+- Create two CPs and list brief and detailed info:
+
+ where the connection points are the IDs of the devices provided through the 'edge-ports' ONOS CLI command
+
+ onos> sdxl2:sdxl2cp-add -ce_mac 00:00:00:00:00:01 SDXL2Test of:0000000000000003/2 Sw3P2 5,15-17
+ onos> sdxl2:sdxl2cp-add -ce_mac 00:00:00:00:00:02 SDXL2Test of:0000000000000002/1 Sw2P1 6,19-21
+
+ onos> sdxl2:sdxl2cp-list
+
+ Status SDXL2 Connection Point
+ -----------------------------------------------
+ ONLINE Sw2P1
+ ONLINE Sw3P2
+
+ onos> sdxl2:sdxl2cp Sw2P1
+
+ Status Connection Point Name Vlan IDs CE Mac Address
+ -------------------------------------------------------------------------------------------------------------
+ ONLINE of:0000000000000002/1 Sw2P1 [6, 19, 20, 21] 00:00:00:00:00:02
+
+
+- Create a VC connecting the two CPs and get its details:
+
+ onos> sdxl2:sdxl2vc-add SDXL2Test Sw2P1 Sw3P2
+ onos> sdxl2:sdxl2vc-list
+
+ Status Virtual Circuit
+ -----------------------------------------------
+ ONLINE Sw2P1-Sw3P2
+
+
+ onos> sdxl2:sdxl2vc SDXL2Test:Sw2P1-Sw3P2
+
+ Status Connection Point Name Vlan IDs CE Mac Address
+ -------------------------------------------------------------------------------------------------------------
+ ONLINE of:0000000000000002/1 Sw2P1 [6, 19, 20, 21] 00:00:00:00:00:02
+ ONLINE of:0000000000000003/2 Sw3P2 [5, 15, 16, 17] 00:00:00:00:00:01
+
+
+ Status Intent
+ --------------------------------------------
+ ONLINE SDXL2Test:Sw2P1-Sw3P2,4
+ ONLINE SDXL2Test:Sw3P2-Sw2P1,3
+ ONLINE SDXL2Test:Sw3P2-Sw2P1,1
+ ONLINE SDXL2Test:Sw3P2-Sw2P1,4
+ ONLINE SDXL2Test:Sw3P2-Sw2P1,2
+ ONLINE SDXL2Test:Sw2P1-Sw3P2,1
+ ONLINE SDXL2Test:Sw2P1-Sw3P2,2
+ ONLINE SDXL2Test:Sw2P1-Sw3P2,3
+
+
+- Remove VC and check it exists no longer:
+
+ onos> sdxl2:sdxl2vc-remove SDXL2Test:Sw2P1-Sw3P2
+ onos> sdxl2:sdxl2vc-list
+
+
+- Remove CPs and check they exist no longer:
+
+ onos> sdxl2:sdxl2cp-remove Sw2P1
+ onos> sdxl2:sdxl2cp-remove Sw3P2
+ onos> sdxl2:sdxl2cp-list
+
+- Remove SDX-L2 and check it does not exist anymore:
+
+ onos> sdxl2:sdxl2-list SDXL2Test
+ onos> sdxl2:sdxl2-list
+
+
+Tips
+=============================
+
+- You should define a topology and point to your local/remote ONOS instance. Some examples:
+
+ - Mininet
+ sudo mn --controller remote,ip=127.0.0.1 --tree,2,2
+ - ONOS/Mininet
+ onos-start-network
+
+- You may check the nodes available at ONOS from Mininet:
+
+ onos> edge-ports
diff --git a/sdx-l2/pom.xml b/sdx-l2/pom.xml
index 90f7236..2401c3f 100644
--- a/sdx-l2/pom.xml
+++ b/sdx-l2/pom.xml
@@ -1,4 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
+
<!--
~ Copyright 2016-present Open Networking Laboratory
~
@@ -95,6 +96,15 @@
<build>
<plugins>
<plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.18.1</version>
+ <configuration>
+ <useFile>false</useFile>
+ <redirectTestOutputToFile>false</redirectTestOutputToFile>
+ </configuration>
+ </plugin>
+ <plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.5.3</version>
diff --git a/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2ConnectionPoint.java b/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2ConnectionPoint.java
index f5f6849..e1075df 100644
--- a/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2ConnectionPoint.java
+++ b/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2ConnectionPoint.java
@@ -24,22 +24,25 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import static com.google.common.base.Preconditions.*;
/**
- * SDX-L2 connection point expressed as composition of a:
- * connect point; set of VLAN id; MAC address (optional).
+ * SDX-L2 Connection Point expressed as composition of a:
+ * Connect Point; set of VLAN ids; MAC address (optional).
*/
public class SdxL2ConnectionPoint {
- private String name;
+ private static final String ERROR_INVALID_VLAN = "Provide VLAN with at least value '-1' or '1'";
private final ConnectPoint cPoint;
private final List<VlanId> vlanIds;
private final MacAddress ceMac;
+ private String name;
/**
- * Creates a new SDX-L2 connection point.
+ * Creates a new SDX-L2 Connection Point.
*
* @param name SDX-L2 connection point name
* @param cPoint connect point
@@ -54,18 +57,151 @@
}
/**
- * Returns the name of SDX-L2 connection point.
+ * Parses a device Connection Point from a string, set of VLANs
+ * from a string and MAC from a string.
+ * The connect point should be in the format "deviceUri/portNumber".
+ * The vlans should be in the format "vlan1,vlan2,vlan3"
+ * The mac address should be in hex
*
- * @return a string representing the name of connection point
+ * @param name name of the SDX-L2 Connection Point
+ * @param connectPoint Connection Point to parse
+ * @param vlans VLAN IDs to parse
+ * @param mac MAC address to parse
+ * @return a Connection Point based on the information in the string
+ *
+ */
+ public static SdxL2ConnectionPoint sdxl2ConnectionPoint(
+ String name, String connectPoint, String vlans, String mac) {
+ checkNotNull(connectPoint);
+ enforceNameFormat(name);
+ ConnectPoint connectionPoint = ConnectPoint.deviceConnectPoint(connectPoint);
+ List<VlanId> vlansList = enforceVlans(vlans);
+ MacAddress macAddress = MacAddress.ZERO;
+ if (mac != null) {
+ macAddress = MacAddress.valueOf(mac);
+ }
+ return new SdxL2ConnectionPoint(name, connectionPoint, vlansList, macAddress);
+ }
+
+ /**
+ * Parses a device Connection Point from a string and set of
+ * VLANs from a string.
+ * The Connection Point should be in the format "deviceUri/portNumber".
+ * The VLANs should be in the format "vlan1,vlan2,vlan3"
+ *
+ * @param name name of the SDX-L2 CP
+ * @param connectPoint Connection Point to parse
+ * @param vlans VLAN IDs to parse
+ * @return a Connection Point based on the information in the string
+ *
+ */
+ public static SdxL2ConnectionPoint sdxl2ConnectionPoint(
+ String name, String connectPoint, String vlans) {
+ return sdxl2ConnectionPoint(name, connectPoint, vlans, null);
+ }
+
+ /**
+ * Enforces proper format on the name of the Connection Point.
+ *
+ * @param name name of the SDX-L2 Connection Point
+ */
+ private static void enforceNameFormat(String name) {
+ checkState(!(name.contains(",") ||
+ name.contains("-") ||
+ name.contains("vlanid=") ||
+ name.contains("ConnectPoint{") ||
+ name.contains("elementId=") ||
+ name.contains("portNumber=") ||
+ name.contains("{") ||
+ name.contains("}") ||
+ name.contains("|")), "Names cannot contain some special characters");
+ }
+
+ /**
+ * Enforces proper format on the requested VLANs.
+ *
+ * @param vlans VLANs expressed explicitly, as a range or in combination
+ * @return a list of VLANs to be added
+ */
+ private static List<VlanId> enforceVlans(String vlans) {
+ String[] splitted = parseVlans(vlans);
+ List<VlanId> vlansList = new ArrayList<>();
+ for (String vlan : splitted) {
+ short vlanNumber = Short.parseShort(vlan);
+ if (!vlansList.contains(VlanId.vlanId(vlanNumber)) &&
+ Short.parseShort(vlan) != -1 &&
+ Short.parseShort(vlan) != 1 &&
+ Short.parseShort(vlan) >= 0 &&
+ Short.parseShort(vlan) != 4095) {
+ vlansList.add(VlanId.vlanId(vlanNumber));
+ }
+ }
+ return vlansList;
+ }
+
+ /**
+ * Parses the VLANs requested by the user.
+ *
+ * @param vlans VLANs expressed explicitly, as a range or in combination
+ * @return an array of VLANs to add
+ */
+ private static String[] parseVlans(String vlans) {
+ if (vlans == null) {
+ vlans = "-1";
+ }
+ ArrayList<String> vlanRange = new ArrayList<String>();
+ String[] splittedVlans;
+ String commaSeparator = ",";
+ if (vlans.contains(commaSeparator)) {
+ splittedVlans = vlans.split(commaSeparator);
+ for (String vlan : splittedVlans) {
+ vlanRange.addAll(generateNumberRange(vlan));
+ }
+ } else {
+ vlanRange.addAll(generateNumberRange(vlans));
+ }
+ splittedVlans = new String[vlanRange.size()];
+ splittedVlans = vlanRange.toArray(splittedVlans);
+ return splittedVlans;
+ }
+
+ /**
+ * Generates a range of numbers, given a string of type "X-Y" ("%d-%d").
+ *
+ * @param range range of numbers to compute
+ * @return a list with numbers between "X" and "Y" (inclusive)
+ */
+ private static ArrayList<String> generateNumberRange(String range) {
+ ArrayList<String> parsedNumbers = new ArrayList<String>();
+ Pattern p = Pattern.compile("(\\d+)-(\\d+)");
+ Matcher m = p.matcher(range);
+ if (m.matches()) {
+ int start = Integer.parseInt(m.group(1));
+ int end = Integer.parseInt(m.group(2));
+ int min = Math.min(start, end);
+ int max = Math.max(start, end);
+ for (int v = min; v <= max; v++) {
+ parsedNumbers.add(Integer.toString(v));
+ }
+ } else {
+ parsedNumbers.add(range);
+ }
+ return parsedNumbers;
+ }
+
+ /**
+ * Returns the name of SDX-L2 Connection Point.
+ *
+ * @return a string representing the name of Connection Point
*/
public String name() {
return name;
}
/**
- * Returns the connect point.
+ * Returns the Connection Point.
*
- * @return connect point object
+ * @return Connection Point object
*/
public ConnectPoint connectPoint() {
return cPoint;
@@ -89,87 +225,6 @@
return ceMac;
}
- /**
- * Parse a device connect point from a string, set of VLANs from a string
- * and MAC from a string.
- * The connect point should be in the format "deviceUri/portNumber".
- * The VLANs should be in the format "vlan1,vlan2,vlan3"
- * The MAC address should be in hex
- *
- * @param name name of the SDX-L2 connection point
- * @param connectPoint connect point to parse
- * @param vlans VLAN ids to parse
- * @param mac MAC address to parse
- * @return a SDX-L2 connection point based on the information in the string.
- *
- */
- public static SdxL2ConnectionPoint
- sdxl2ConnectionPoint(String name, String connectPoint, String vlans, String mac) {
- checkNotNull(connectPoint);
- checkNotNull(vlans);
- checkState(!(name.contains(",") ||
- name.contains("-") ||
- name.contains("vlanid=") ||
- name.contains("ConnectPoint{") ||
- name.contains("elementId=") ||
- name.contains("portNumber=") ||
- name.contains("{") ||
- name.contains("}") ||
- name.contains("|")), "Names cannot contain some special characters");
- checkNotNull(mac);
- ConnectPoint connectionPoint = ConnectPoint.deviceConnectPoint(connectPoint);
- String[] splitted = vlans.split(",");
- checkArgument(splitted.length != 0, "At least '-1' or '1' as value");
- List<VlanId> vlanslist = new ArrayList<>();
- for (String vlan : splitted) {
- if (!vlanslist.contains(VlanId.vlanId(Short.parseShort(vlan))) &&
- Short.parseShort(vlan) != -1 &&
- Short.parseShort(vlan) != 1) {
- vlanslist.add(VlanId.vlanId(Short.parseShort(vlan)));
- }
- }
- MacAddress macAddress = MacAddress.valueOf(mac);
- return new SdxL2ConnectionPoint(name, connectionPoint, vlanslist, macAddress);
- }
-
- /**
- * Parse a device connect point from a string and set of VLANs from a string.
- * The connect point should be in the format "deviceUri/portNumber".
- * The VLANs should be in the format "vlan1,vlan2,vlan3"
- *
- * @param name name of the SDX-L2 connection point
- * @param connectPoint connect point to parse
- * @param vlans VLAN ids to parse
- * @return a SDX-L2 connection point based on the information in the string.
- *
- */
- public static SdxL2ConnectionPoint sdxl2ConnectionPoint(String name, String connectPoint, String vlans) {
- checkNotNull(connectPoint);
- checkNotNull(vlans);
- checkState(!(name.contains(",") ||
- name.contains("-") ||
- name.contains("vlanid=") ||
- name.contains("ConnectPoint{") ||
- name.contains("elementId=") ||
- name.contains("portNumber=") ||
- name.contains("{") ||
- name.contains("}") ||
- name.contains("|")), "Names cannot contain some special characters");
- ConnectPoint connectionPoint = ConnectPoint.deviceConnectPoint(connectPoint);
- String[] splitted = vlans.split(",");
- checkArgument(splitted.length != 0, "At least '-1' or '1' as value");
- List<VlanId> vlanslist = new ArrayList<>();
- for (String vlan : splitted) {
- if (!vlanslist.contains(VlanId.vlanId(Short.parseShort(vlan))) &&
- Short.parseShort(vlan) != -1 &&
- Short.parseShort(vlan) != 1) {
- vlanslist.add(VlanId.vlanId(Short.parseShort(vlan)));
- }
- }
- MacAddress macAddress = MacAddress.ZERO;
- return new SdxL2ConnectionPoint(name, connectionPoint, vlanslist, macAddress);
- }
-
@Override
public int hashCode() {
return Objects.hash(name, cPoint, vlanIds, ceMac);
diff --git a/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2DistributedStore.java b/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2DistributedStore.java
index 02ea103..a3ada37 100644
--- a/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2DistributedStore.java
+++ b/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2DistributedStore.java
@@ -18,12 +18,12 @@
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
+import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Deactivate;
import org.onlab.packet.VlanId;
import org.onlab.util.KryoNamespace;
import org.onosproject.store.primitives.DefaultDistributedSet;
@@ -35,14 +35,15 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
-import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
+import static java.lang.String.format;
/**
* SDX-L2 Store implementation backed by different distributed primitives.
@@ -61,12 +62,18 @@
private Map<SdxL2ConnectionPoint, String> sdxL2CPs;
private ConsistentMap<SdxL2ConnectionPoint, String> sdxL2cps;
+ private Map<String, String> sdxL2VCs;
+ private ConsistentMap<String, String> sdxL2vcs;
+
private static String errorAddSdx = "It is not possible to add %s " +
"because it exists";
private static String errorRemoveSdx = "It is not possible to remove %s " +
"because it does not exist";
+ /*
+ Error definitions for CPs.
+ */
private static String errorAddSdxL2CPName = "It is not possible to add %s " +
"because there is a sdxl2cp with the same name";
private static String errorAddSdxL2CPVlans = "It is not possible to add %s " +
@@ -74,25 +81,31 @@
private static String errorAddSdxL2CPCP = "It is not possible to add %s " +
"because there is a conflict with %s on the connection point";
private static String errorAddSdxL2CPSdx = "It is not possible to add %s " +
- "because the relative sdxl2 does not exist";
+ "because the relative sdxl2 %s does not exist";
+ private static String errorGetSdxL2CP = "It is not possible to retrieve %s " +
+ "because it does not exist";
private static String errorGetSdxL2CPs = "It is not possible to list the sdxl2cps " +
"because sdxl2 %s does not exist";
private static String errorRemoveSdxL2CP = "It is not possible to remove %s " +
"because it does not exist";
- private static String errorGetSdxL2CP = "It is not possible to retrieve %s " +
- "because it does not exist";
+ /*
+ Error definitions for VCs.
+ */
+ private static String errorVCKey = "It is not possible to add vc because " +
+ "there is a problem with key %s (wrong format)";
+ private static String errorAddVCOverlap = "It is not possible to add vc " +
+ "because there is an overlap with %s";
+ private static String errorRemoveVC = "It is not possible to remove the " +
+ "vc because it does not exist";
+ private static String errorRemoveVCAux = "Virtual Circuit between %s and %s " +
+ "does not exist";
- public void initForTest() {
-
- this.sdxL2s = Sets.newHashSet();
-
- this.sdxL2CPs = new ConcurrentHashMap<SdxL2ConnectionPoint, String>();
-
- }
-
+ /**
+ * Activates the implementation of the SDX-L2 store.
+ */
@Activate
public void activate() {
@@ -103,10 +116,10 @@
.build();
sdxL2s = new DefaultDistributedSet<>(this.storageService
- .<String>setBuilder()
- .withSerializer(Serializer.using(custom))
- .withName("sdxl2s")
- .build(), DistributedPrimitive.DEFAULT_OPERTATION_TIMEOUT_MILLIS);
+ .<String>setBuilder()
+ .withSerializer(Serializer.using(custom))
+ .withName("sdxl2s")
+ .build(), DistributedPrimitive.DEFAULT_OPERTATION_TIMEOUT_MILLIS);
sdxL2cps = this.storageService
.<SdxL2ConnectionPoint, String>consistentMapBuilder()
@@ -115,20 +128,32 @@
.build();
sdxL2CPs = sdxL2cps.asJavaMap();
+ sdxL2vcs = this.storageService.<String, String>consistentMapBuilder()
+ .withSerializer(Serializer.using(custom))
+ .withName("vcs")
+ .build();
+ sdxL2VCs = sdxL2vcs.asJavaMap();
+
log.info("Started");
}
+ /**
+ * Helper class called to initialise tests.
+ */
+ public void initForTest() {
+ this.sdxL2s = Sets.newHashSet();
+ this.sdxL2CPs = new ConcurrentHashMap<SdxL2ConnectionPoint, String>();
+ this.sdxL2VCs = new ConcurrentHashMap<String, String>();
+ }
+
+ /**
+ * Deactivates the implementation of the SDX-L2 store.
+ */
@Deactivate
public void deactivate() {
log.info("Stopped");
}
- /**
- * Creates a named SDX-L2.
- *
- * @param sdxl2 SDX-L2 name
- * @throws SdxL2Exception if SDX-L2 exists
- */
@Override
public void putSdxL2(String sdxl2) throws SdxL2Exception {
boolean inserted = sdxL2s.add(sdxl2);
@@ -137,12 +162,6 @@
}
}
- /**
- * Removes a named SDX-L2.
- *
- * @param sdxl2 SDX-L2 name
- * @throws SdxL2Exception if SDX-L2 does not exist
- */
@Override
public void removeSdxL2(String sdxl2) throws SdxL2Exception {
boolean removed = sdxL2s.remove(sdxl2);
@@ -158,35 +177,22 @@
toRemove.forEach(key_value -> sdxL2CPs.remove(key_value.getKey()));
}
- /**
- * Returns a set of SDX-L2 names.
- *
- * @return a set of SDX-L2 names
- */
@Override
public Set<String> getSdxL2s() {
return ImmutableSet.copyOf(sdxL2s);
}
- /**
- * Adds an SDX-L2 connection point to an SDX-L2.
- *
- * @param sdxl2 SDX-L2 name
- * @param connectionPoint the connection point object
- * @throws SdxL2Exception if it is not possible to add the SDX-L2 connection point
- */
@Override
public void addSdxL2ConnectionPoint(String sdxl2, SdxL2ConnectionPoint connectionPoint) throws SdxL2Exception {
-
boolean exist = sdxL2s.contains(sdxl2);
-
+ String errorMissingSdxL2 = String.format(errorAddSdxL2CPSdx, connectionPoint.name(), sdxl2);
if (!exist) {
- throw new SdxL2Exception(String.format(errorAddSdxL2CPSdx, connectionPoint.name()));
+ throw new SdxL2Exception(errorMissingSdxL2);
}
Set<SdxL2ConnectionPoint> sdxl2cpsTemp = ImmutableSet.copyOf(sdxL2CPs.keySet());
Set<SdxL2ConnectionPoint> sdxl2cpsTempByName = sdxl2cpsTemp.parallelStream().filter(
- sdxl2cpTemp-> sdxl2cpTemp.name().equals(connectionPoint.name()
+ sdxl2cpTemp -> sdxl2cpTemp.name().equals(connectionPoint.name()
)
).collect(Collectors.toSet());
@@ -194,9 +200,8 @@
throw new SdxL2Exception(String.format(errorAddSdxL2CPName, connectionPoint.name()));
}
-
Set<SdxL2ConnectionPoint> sdxl2cpsByCP = sdxl2cpsTemp.parallelStream().filter(
- sdxl2cp_temp-> sdxl2cp_temp.connectPoint().equals(connectionPoint.connectPoint()
+ sdxl2cpTemp -> sdxl2cpTemp.connectPoint().equals(connectionPoint.connectPoint()
)
).collect(Collectors.toSet());
@@ -208,7 +213,7 @@
sdxl2cp_by_vlan.vlanIds().contains(vlanId) || sdxl2cp_by_vlan.vlanIds().size() == 0
)).collect(Collectors.toSet());
- tempName = sdxl2cpsByVlan.iterator().hasNext() ? sdxl2cpsByVlan.iterator().next().name() : null;
+ tempName = sdxl2cpsByVlan.iterator().hasNext() ? sdxl2cpsByVlan.iterator().next().name() : null;
if (sdxl2cpsByVlan.size() != 0) {
throw new SdxL2Exception(String.format(errorAddSdxL2CPVlans, connectionPoint.name(), tempName));
@@ -216,24 +221,14 @@
}
- tempName = sdxl2cpsByCP.iterator().hasNext() ? sdxl2cpsByCP.iterator().next().name() : null;
-
+ tempName = sdxl2cpsByCP.iterator().hasNext() ? sdxl2cpsByCP.iterator().next().name() : null;
if (sdxl2cpsByCP.size() != 0 && vlans.size() == 0) {
throw new SdxL2Exception(String.format(errorAddSdxL2CPCP, connectionPoint.name(), tempName));
}
sdxL2CPs.put(connectionPoint, sdxl2);
-
}
- /**
- * Returns all the SDX-L2 connection points names or the SDX-L2 2connection points names
- * that are related to an SDX-L2.
- *
- * @param sdxl2 name (optional) of the SDX-L2
- * @return a set of SDX-L2 connection points names, the result depends on the input parameter;
- * @throws SdxL2Exception if SDX-L2 is present but it does not exist
- */
@Override
public Set<String> getSdxL2ConnectionPoints(Optional<String> sdxl2) throws SdxL2Exception {
@@ -270,12 +265,6 @@
}
- /**
- * Removes a named SDX-L2 connection point in an SDX-L2.
- *
- * @param sdxl2cp the connection point name
- * @throws SdxL2Exception if SDX-L2 connection point does not exist
- */
@Override
public void removeSdxL2ConnectionPoint(String sdxl2cp) throws SdxL2Exception {
@@ -295,13 +284,6 @@
}
- /**
- * Returns an SDX-L2 connection point in a SDX-L2.
- *
- * @param sdxl2cp the connection point name
- * @return the relative SDXL2ConnectionPoint object
- * @throws SdxL2Exception if SDX-L2 connection point does not exist
- */
@Override
public SdxL2ConnectionPoint getSdxL2ConnectionPoint(String sdxl2cp) throws SdxL2Exception {
SdxL2ConnectionPoint sdxl2cpTemp = ImmutableSet.copyOf(sdxL2CPs.keySet()).parallelStream()
@@ -314,4 +296,108 @@
return sdxl2cpTemp;
}
+ @Override
+ public void addVC(String sdxl2, SdxL2ConnectionPoint sdxl2cplhs, SdxL2ConnectionPoint sdxl2cprhs)
+ throws SdxL2Exception {
+ Set<String> vcs = ImmutableSet.copyOf(
+ sdxL2VCs.keySet().parallelStream().filter((vctemp->vctemp.contains(sdxl2cplhs.toString())
+ || vctemp.contains(sdxl2cprhs.toString()))).collect(Collectors.toSet()));
+ for (String vctemp : vcs) {
+ String[] splitted = vctemp.split("~");
+
+ if (splitted.length != 2) {
+ throw new SdxL2Exception(String.format(errorVCKey, "add", vctemp));
+ }
+
+ if (!(!sdxl2cplhs.toString().equals(splitted[0]) &&
+ !sdxl2cplhs.toString().equals(splitted[1]) &&
+ !sdxl2cprhs.toString().equals(splitted[0]) &&
+ !sdxl2cprhs.toString().equals(splitted[1]))) {
+ throw new SdxL2Exception(String.format(errorAddVCOverlap, vctemp));
+ }
+ }
+
+ String cps = sdxl2cplhs.toString().compareTo(sdxl2cprhs.toString()) < 0 ?
+ format(SdxL2VCManager.SDXL2_CPS_FORMAT, sdxl2cplhs, sdxl2cprhs) :
+ format(SdxL2VCManager.SDXL2_CPS_FORMAT, sdxl2cprhs, sdxl2cplhs);
+ String name = sdxl2cplhs.name().compareTo(sdxl2cprhs.name().toString()) < 0 ?
+ format(SdxL2VCManager.NAME_FORMAT, sdxl2, sdxl2cplhs.name(), sdxl2cprhs.name()) :
+ format(SdxL2VCManager.NAME_FORMAT, sdxl2, sdxl2cprhs.name(), sdxl2cplhs.name());
+ sdxL2VCs.put(cps, name);
+ }
+
+ @Override
+ public void removeVC(SdxL2ConnectionPoint sdxl2cplhs, SdxL2ConnectionPoint sdxl2cprhs)
+ throws SdxL2Exception {
+
+ String cps = sdxl2cplhs.toString().compareTo(sdxl2cprhs.toString()) < 0 ?
+ format(SdxL2VCManager.SDXL2_CPS_FORMAT, sdxl2cplhs, sdxl2cprhs) :
+ format(SdxL2VCManager.SDXL2_CPS_FORMAT, sdxl2cprhs, sdxl2cplhs);
+ String name = sdxL2VCs.remove(cps);
+ if (name == null) {
+ throw new SdxL2Exception(String.format(errorRemoveVC));
+ }
+ }
+
+ @Override
+ public void removeVC(SdxL2ConnectionPoint cp) throws SdxL2Exception {
+
+ Set<String> vcs = ImmutableSet.copyOf(sdxL2VCs.keySet()
+ .parallelStream()
+ .filter((vctemp -> vctemp.contains(cp.toString())))
+ .collect(Collectors.toSet()));
+
+ for (String vctemp : vcs) {
+ String[] splitted = vctemp.split("~");
+ if (splitted.length != 2) {
+ throw new SdxL2Exception(String.format(errorVCKey, "delete", vctemp));
+ }
+ if (cp.toString().equals(splitted[0]) || cp.toString().equals(splitted[1])) {
+ sdxL2VCs.remove(vctemp);
+ }
+ }
+ }
+
+ @Override
+ public void removeVCs(String sdxl2) {
+
+ Set<Map.Entry<String, String>> vcsToRemove = sdxL2VCs.entrySet().parallelStream().filter(key_value -> {
+ String[] fields = key_value.getValue().split(":");
+ return fields.length == 2 && fields[0].equals(sdxl2) ? true : false;
+ }).collect(Collectors.toSet());
+
+ vcsToRemove.forEach(key_value -> sdxL2VCs.remove(key_value.getKey()));
+ }
+
+ @Override
+ public String getVC(SdxL2ConnectionPoint sdxl2cplhs, SdxL2ConnectionPoint sdxl2cprhs)
+ throws SdxL2Exception {
+ String cps = sdxl2cplhs.toString().compareTo(sdxl2cprhs.toString()) < 0 ?
+ format(SdxL2VCManager.SDXL2_CPS_FORMAT, sdxl2cplhs, sdxl2cprhs) :
+ format(SdxL2VCManager.SDXL2_CPS_FORMAT, sdxl2cprhs, sdxl2cplhs);
+
+ String encodedvc = ImmutableSet.copyOf(sdxL2VCs.keySet()).parallelStream().filter(
+ encoded_cps -> encoded_cps.equals(cps)).findFirst().orElse(null);
+
+ if (encodedvc == null) {
+ throw new SdxL2Exception(String.format(errorRemoveVCAux,
+ sdxl2cplhs.name(), sdxl2cprhs.name()));
+ }
+ return encodedvc;
+ }
+
+ @Override
+ public Set<String> getVCs(Optional<String> sdxl2) {
+ if (sdxl2.isPresent()) {
+ Set<String> vcs = ImmutableSet.copyOf(sdxL2VCs.values())
+ .parallelStream()
+ .filter(vc -> {
+ String[] parts = vc.split(":");
+ return parts.length == 2 && parts[0].equals(sdxl2.get());
+ }).collect(Collectors.toSet());
+
+ return vcs;
+ }
+ return ImmutableSet.copyOf(sdxL2VCs.values());
+ }
}
diff --git a/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2Exception.java b/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2Exception.java
index 1692edc..cd7973b 100644
--- a/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2Exception.java
+++ b/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2Exception.java
@@ -21,6 +21,11 @@
*/
public class SdxL2Exception extends Exception {
+ /**
+ * Returns a custom exception, given a message.
+ *
+ * @param message Exception with custom message
+ */
public SdxL2Exception(String message) {
super(message);
}
diff --git a/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2MacVCManager.java b/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2MacVCManager.java
new file mode 100644
index 0000000..5a76979
--- /dev/null
+++ b/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2MacVCManager.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.sdxl2;
+
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.ApplicationId;
+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.intent.Intent;
+import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.PointToPointIntent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import static com.google.common.base.Preconditions.checkState;
+
+/**
+ * Manages Virtual Circuits using MAC addresses.
+ */
+public class SdxL2MacVCManager extends SdxL2VCManager {
+
+ private static final int PRIORITY_OFFSET = 2000;
+ private static Logger log = LoggerFactory.getLogger(SdxL2MacVCManager.class);
+
+ private static String errorMacNull = "VC cannot be %s: the mac address of %s is null";
+ private static String errorMacEqual = "VC cannot be %s: same mac addresses on both sides";
+
+ /**
+ * Creates an SDX-L2 MAC VC Manager.
+ *
+ * @param sdxl2id application ID
+ * @param store reference to the SDX-L2 store
+ * @param intentService reference to the Intent service
+ */
+ public SdxL2MacVCManager(ApplicationId sdxl2id,
+ SdxL2Store store,
+ IntentService intentService) {
+ super(sdxl2id, store, intentService);
+ log.info("Started");
+ }
+
+ @Override
+ public Collection<Intent> buildIntents(String sdxl2, SdxL2ConnectionPoint ingress, SdxL2ConnectionPoint egress) {
+ List<Intent> intents = null;
+ TrafficSelector selector;
+ TrafficTreatment treatment;
+ Key key;
+
+ if (ingress.vlanIds().size() == egress.vlanIds().size()) {
+ intents = new ArrayList<Intent>();
+ if (ingress.vlanIds().size() == 0) {
+ selector = buildSelector(ingress.macAddress(),
+ egress.macAddress(),
+ null,
+ null);
+ treatment = DefaultTrafficTreatment.emptyTreatment();
+ key = generateIntentKey(sdxl2, ingress, egress, "1");
+
+ intents.add(PointToPointIntent.builder()
+ .appId(appId)
+ .key(key)
+ .selector(selector)
+ .treatment(treatment)
+
+ .ingressPoint(ingress.connectPoint())
+ .egressPoint(egress.connectPoint())
+ .priority(PRIORITY_OFFSET)
+ .build());
+ } else {
+ Iterator<VlanId> ingressTags = ingress.vlanIds().iterator();
+ Iterator<VlanId> egressTags = egress.vlanIds().iterator();
+ int index = 1;
+ while (ingressTags.hasNext()) {
+ selector = buildSelector(ingress.macAddress(),
+ egress.macAddress(),
+ null,
+ ingressTags.next());
+ treatment = buildTreatment(egressTags.next(),
+ null,
+ false);
+ key = generateIntentKey(sdxl2, ingress, egress, String.valueOf(index));
+
+ intents.add(PointToPointIntent.builder()
+ .appId(appId)
+ .key(key)
+ .selector(selector)
+ .treatment(treatment)
+ .ingressPoint(ingress.connectPoint())
+ .egressPoint(egress.connectPoint())
+ .priority(PRIORITY_OFFSET)
+ .build());
+ index = index + 1;
+ }
+ }
+ return intents;
+ }
+
+ if (ingress.vlanIds().size() == 1 && egress.vlanIds().size() == 0) {
+ Iterator<VlanId> ingressTags = ingress.vlanIds().iterator();
+ intents = new ArrayList<Intent>();
+ selector = buildSelector(ingress.macAddress(),
+ egress.macAddress(),
+ null,
+ ingressTags.next());
+ treatment = buildTreatment(null,
+ null,
+ true);
+ key = generateIntentKey(sdxl2, ingress, egress, "1");
+
+ intents.add(PointToPointIntent.builder()
+ .appId(appId)
+ .key(key)
+ .selector(selector)
+ .treatment(treatment)
+ .ingressPoint(ingress.connectPoint())
+ .egressPoint(egress.connectPoint())
+ .priority(PRIORITY_OFFSET)
+ .build());
+ return intents;
+ }
+
+ if (ingress.vlanIds().size() == 0 && egress.vlanIds().size() == 1) {
+ Iterator<VlanId> egressTags = egress.vlanIds().iterator();
+ intents = new ArrayList<Intent>();
+ selector = buildSelector(ingress.macAddress(),
+ egress.macAddress(),
+ null,
+ null);
+ treatment = buildTreatment(null,
+ egressTags.next(),
+ false);
+ key = generateIntentKey(sdxl2, ingress, egress, "1");
+
+ intents.add(PointToPointIntent.builder()
+ .appId(appId)
+ .key(key)
+ .selector(selector)
+ .treatment(treatment)
+ .ingressPoint(ingress.connectPoint())
+ .egressPoint(egress.connectPoint())
+ .priority(PRIORITY_OFFSET)
+ .build());
+ return intents;
+ }
+
+ log.warn(String.format(errorCreateIntents, ingress.name(), egress.name()));
+
+ return intents;
+ }
+
+ @Override
+ public void addVC(String sdxl2, SdxL2ConnectionPoint sdxl2cplhs, SdxL2ConnectionPoint sdxl2cprhs) {
+ String action = "created";
+ checkState(!(isNullMac(sdxl2cplhs.macAddress()) && isNullMac(sdxl2cprhs.macAddress())),
+ errorMacNull, action, sdxl2cplhs.name() + " and " + sdxl2cprhs.name());
+ checkState(!isNullMac(sdxl2cprhs.macAddress()), errorMacNull, action, sdxl2cplhs.name());
+ checkState(!isNullMac(sdxl2cprhs.macAddress()), errorMacNull, action, sdxl2cprhs.name());
+ checkState(!sdxl2cplhs.macAddress().equals(sdxl2cprhs.macAddress()), errorMacEqual, action);
+ super.addVC(sdxl2, sdxl2cplhs, sdxl2cprhs);
+ }
+
+ @Override
+ public void removeVC(SdxL2ConnectionPoint sdxl2cplhs, SdxL2ConnectionPoint sdxl2cprhs) {
+ String action = "deleted";
+ checkState(!(isNullMac(sdxl2cplhs.macAddress()) && isNullMac(sdxl2cprhs.macAddress())),
+ errorMacNull, action, sdxl2cplhs.name() + " and " + sdxl2cprhs.name());
+ checkState(!sdxl2cplhs.macAddress().equals(MacAddress.ZERO), errorMacNull, action, sdxl2cplhs.name());
+ checkState(!sdxl2cprhs.macAddress().equals(MacAddress.ZERO), errorMacNull, action, sdxl2cprhs.name());
+ checkState(!sdxl2cplhs.macAddress().equals(sdxl2cprhs.macAddress()), errorMacEqual, action);
+ super.removeVC(sdxl2cplhs, sdxl2cprhs);
+ }
+
+ @Override
+ public void removeVC(SdxL2ConnectionPoint cp) {
+ checkState(!cp.macAddress().equals(MacAddress.ZERO), errorMacNull, "deleted", cp.name());
+ super.removeVC(cp);
+ }
+
+ private boolean isNullMac(MacAddress mac) {
+ return mac.equals(MacAddress.ZERO);
+ }
+
+ private TrafficSelector buildSelector(MacAddress ingressMac,
+ MacAddress egressMac,
+ Short ethertype,
+ VlanId ingresstag) {
+
+ TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
+ selectorBuilder.matchEthSrc(ingressMac);
+ selectorBuilder.matchEthDst(egressMac);
+ if (ethertype != null) {
+ selectorBuilder.matchEthType(ethertype);
+ }
+ if (ingresstag != null) {
+ selectorBuilder.matchVlanId(ingresstag);
+ }
+ return selectorBuilder.build();
+ }
+
+}
diff --git a/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2Manager.java b/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2Manager.java
index 21dd06a..edd7901 100644
--- a/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2Manager.java
+++ b/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2Manager.java
@@ -16,13 +16,12 @@
package org.onosproject.sdxl2;
-
+import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Deactivate;
import org.onlab.packet.Ethernet;
import org.onlab.packet.ICMP6;
import org.onlab.packet.IPv6;
@@ -46,6 +45,7 @@
import java.util.Collections;
import java.util.Optional;
import java.util.Set;
+import java.util.stream.Collectors;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
@@ -56,52 +56,56 @@
import static org.onlab.packet.IPv6.PROTOCOL_ICMP6;
import static org.onosproject.net.packet.PacketPriority.CONTROL;
+
/**
- * Implementation of the SdxL2Service.
+ * Implements SdxL2Service.
*/
@Component(immediate = true)
@Service
public class SdxL2Manager implements SdxL2Service {
private static final String SDXL2_APP = "org.onosproject.sdxl2";
+ private static final String ERROR_ADD_VC_VLANS =
+ "Cannot create VC when CPs have different number of VLANs";
+ private static final String ERROR_ADD_VC_VLANS_CLI =
+ "\u001B[0;31mError executing command: " + ERROR_ADD_VC_VLANS + "\u001B[0;49m";
+ private static final String VC_0 = "MAC";
private static Logger log = LoggerFactory.getLogger(SdxL2Manager.class);
-
+ private static final String ERROR_ADD_VC_CPS = "Unable to find %s and %s in sdxl2=%s";
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected SdxL2Store sdxL2Store;
-
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
-
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected IntentService intentService;
-
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected EdgePortService edgePortService;
-
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected PacketService packetService;
-
protected SdxL2Processor processor = new SdxL2Processor();
-
- protected SdxL2ArpNdpHandler arpndpHandler;
-
protected ApplicationId appId;
-
protected SdxL2MonitoringService monitoringManager;
-
- protected String vcType = "MAC";
+ protected SdxL2ArpNdpHandler arpndpHandler;
+ protected SdxL2VCService vcManager;
+ /**
+ * Activates the implementation of the SDX-L2 service.
+ * @param context ComponentContext object
+ */
@Activate
protected void activate(ComponentContext context) {
appId = coreService.registerApplication(SDXL2_APP);
monitoringManager = new SdxL2MonitoringManager(appId, intentService, edgePortService);
+ SdxL2ArpNdpHandler.vcType = VC_0;
+ vcManager = new SdxL2MacVCManager(appId, sdxL2Store, intentService);
handleArpNdp();
log.info("Started");
}
-
-
+ /**
+ * Deactivates the implementation of the SDX-L2 service.
+ */
@Deactivate
protected void deactivate() {
this.cleanSdxL2();
@@ -109,11 +113,6 @@
log.info("Stopped");
}
- /**
- * Creates a named SDX-L2.
- *
- * @param sdxl2 SDX-L2 name
- */
@Override
public void createSdxL2(String sdxl2) {
@@ -128,14 +127,8 @@
} catch (SdxL2Exception e) {
log.info(e.getMessage());
}
-
}
- /**
- * Deletes a named SDX-L2.
- *
- * @param sdxl2 SDX-L2 name
- */
@Override
public void deleteSdxL2(String sdxl2) {
@@ -149,22 +142,11 @@
}
- /**
- * Returns a set of SDX-L2 names.
- *
- * @return a set of SDX-L2 names
- */
@Override
public Set<String> getSdxL2s() {
return this.sdxL2Store.getSdxL2s();
}
- /**
- * Adds an SDX-L2 connection point to an SDX-L2.
- *
- * @param sdxl2 SDX-L2 name
- * @param sdxl2cp SDX-L2 connection point object
- */
@Override
public void addSdxL2ConnectionPoint(String sdxl2, SdxL2ConnectionPoint sdxl2cp) {
@@ -179,12 +161,6 @@
}
- /**
- * Returns all the SDX-L2 connection points names in a SDX-L2 or all the SDX-L2 connection points names.
- *
- * @param sdxl2 SDX-L2 name
- * @return a set of SDX-L2 connection points names
- */
@Override
public Set<String> getSdxL2ConnectionPoints(Optional<String> sdxl2) {
@@ -195,14 +171,8 @@
}
return Collections.emptySet();
-
}
- /**
- * Removes an SDX-L2 connection point from an SDX-L2.
- *
- * @param sdxl2cp SDX-L2 connection point name
- */
@Override
public void removeSdxL2ConnectionPoint(String sdxl2cp) {
@@ -216,12 +186,55 @@
}
- /**
- * Returns an SDX-L2 connection point in a SDX-L2.
- *
- * @param sdxl2cp SDX-L2 connection point name
- * @return the relative SdxL2ConnectionPoint object
- */
+ @Override
+ public void addVC(String sdxl2, String sdxl2cplhs, String sdxl2cprhs) {
+ SdxL2ConnectionPoint lhs = this.getSdxL2ConnectionPoint(sdxl2cplhs);
+ SdxL2ConnectionPoint rhs = this.getSdxL2ConnectionPoint(sdxl2cprhs);
+
+ Set<String> cps = this.getSdxL2ConnectionPoints(Optional.of(sdxl2))
+ .parallelStream()
+ .filter(cptemp -> (cptemp.equals(sdxl2cplhs) || cptemp.equals(sdxl2cprhs)))
+ .collect(Collectors.toSet());
+
+ checkState(cps.size() == 2, ERROR_ADD_VC_CPS, sdxl2cplhs, sdxl2cprhs, sdxl2);
+
+ if ((lhs.vlanIds().size() != rhs.vlanIds().size()) &&
+ (lhs.vlanIds().size() > 1 || rhs.vlanIds().size() > 1)) {
+ // User can correct this issue in the CLI. Show in console and log
+ System.err.println(ERROR_ADD_VC_VLANS_CLI);
+ log.info(ERROR_ADD_VC_VLANS);
+ return;
+ }
+ this.vcManager.addVC(sdxl2, lhs, rhs);
+ }
+
+ @Override
+ public void removeVC(String vc) {
+ checkNotNull(vc, "VC name cannot be null");
+ String[] splitKeyCPs = vc.split(":");
+ checkState(splitKeyCPs.length == 2, "Bad name format $sdx:$something");
+ String[] cps = splitKeyCPs[1].split("-");
+ checkState(cps.length == 2, "Bad name format $sdx:$lhs-$rhs");
+
+ String lhsName = cps[0];
+ String rhsName = cps[1];
+ SdxL2ConnectionPoint lhs = this.getSdxL2ConnectionPoint(lhsName);
+ SdxL2ConnectionPoint rhs = this.getSdxL2ConnectionPoint(rhsName);
+ if (lhs == null || rhs == null) {
+ return;
+ }
+
+ Set<String> cpsByVC = this.getSdxL2ConnectionPoints(Optional.of(splitKeyCPs[0]))
+ .parallelStream()
+ .filter(tempCP -> (tempCP.equals(lhs.name()) || tempCP.equals(rhs.name())))
+ .collect(Collectors.toSet());
+
+ if (cpsByVC.size() != 2) {
+ return;
+ }
+ this.vcManager.removeVC(lhs, rhs);
+ }
+
@Override
public SdxL2ConnectionPoint getSdxL2ConnectionPoint(String sdxl2cp) {
checkNotNull(sdxl2cp, "SdxL2ConnectionPoint name cannot be null");
@@ -230,28 +243,42 @@
} catch (SdxL2Exception e) {
log.info(e.getMessage());
}
-
return null;
}
- /**
- * Returns the state of the Intent that has been provided as input.
- *
- * @param intentKey key of the intent;
- * @return the last state of the intent;
- */
+ @Override
+ public Set<String> getVirtualCircuits(Optional<String> sdxl2) {
+ return this.vcManager.getVCs(sdxl2);
+ }
+
+ @Override
+ public VirtualCircuit getVirtualCircuit(String sdxl2vc) {
+ checkNotNull(sdxl2vc, "VC name cannot be null");
+ String[] splitKeyCPs = sdxl2vc.split(":");
+ checkState(splitKeyCPs.length == 2, "Bad name format $sdx:$something");
+ String[] cps = splitKeyCPs[1].split("-");
+ checkState(cps.length == 2, "Bad name format $sdx:$lhs-$rhs");
+
+ SdxL2ConnectionPoint lhs = this.getSdxL2ConnectionPoint(cps[0]);
+ SdxL2ConnectionPoint rhs = this.getSdxL2ConnectionPoint(cps[1]);
+ VirtualCircuit vc = null;
+ if (lhs == null || rhs == null) {
+ return vc;
+ }
+
+ String result = this.vcManager.getVC(lhs, rhs);
+ if (result != null) {
+ vc = new VirtualCircuit(lhs, rhs);
+ }
+ return vc;
+ }
+
@Override
public SdxL2State getIntentState(Key intentKey) {
checkNotNull(intentKey, "Intent key cannot be null");
return this.monitoringManager.getIntentState(intentKey);
}
- /**
- * Returns the state of the EdgePort that has been provided as input.
- *
- * @param edgeport the connect point representing the edge port
- * @return the last state of the edgeport;
- */
@Override
public SdxL2State getEdgePortState(ConnectPoint edgeport) {
checkNotNull(edgeport, "Edge port cannot be null");
@@ -267,11 +294,11 @@
}
/**
- * It requests ARP and NDP packets to the PacketService
+ * Requests ARP and NDP packets to the PacketService
* and registers the SDX-L2 PacketProcessor.
*/
private void handleArpNdp() {
- SdxL2ArpNdpHandler.vcType = vcType;
+ SdxL2ArpNdpHandler.vcType = VC_0;
arpndpHandler = new SdxL2ArpNdpHandler(intentService, packetService, appId);
packetService.addProcessor(processor, PacketProcessor.director(1));
@@ -280,7 +307,7 @@
DefaultTrafficSelector.builder();
selectorBuilder.matchEthType(TYPE_ARP);
packetService.requestPackets(selectorBuilder.build(),
- CONTROL, appId, Optional.<DeviceId>empty());
+ CONTROL, appId, Optional.<DeviceId>empty());
// IPv6 Neighbor Solicitation packet.
selectorBuilder = DefaultTrafficSelector.builder();
@@ -288,7 +315,7 @@
selectorBuilder.matchIPProtocol(PROTOCOL_ICMP6);
selectorBuilder.matchIcmpv6Type(NEIGHBOR_SOLICITATION);
packetService.requestPackets(selectorBuilder.build(),
- CONTROL, appId, Optional.<DeviceId>empty());
+ CONTROL, appId, Optional.<DeviceId>empty());
// IPv6 Neighbor Advertisement packet.
selectorBuilder = DefaultTrafficSelector.builder();
@@ -296,7 +323,7 @@
selectorBuilder.matchIPProtocol(PROTOCOL_ICMP6);
selectorBuilder.matchIcmpv6Type(NEIGHBOR_ADVERTISEMENT);
packetService.requestPackets(selectorBuilder.build(),
- CONTROL, appId, Optional.<DeviceId>empty());
+ CONTROL, appId, Optional.<DeviceId>empty());
}
/**
@@ -312,21 +339,21 @@
DefaultTrafficSelector.builder();
selectorBuilder.matchEthType(TYPE_ARP);
packetService.cancelPackets(selectorBuilder.build(),
- CONTROL, appId, Optional.<DeviceId>empty());
+ CONTROL, appId, Optional.<DeviceId>empty());
selectorBuilder = DefaultTrafficSelector.builder();
selectorBuilder.matchEthType(TYPE_IPV6);
selectorBuilder.matchIPProtocol(PROTOCOL_ICMP6);
selectorBuilder.matchIcmpv6Type(NEIGHBOR_SOLICITATION);
packetService.cancelPackets(selectorBuilder.build(),
- CONTROL, appId, Optional.<DeviceId>empty());
+ CONTROL, appId, Optional.<DeviceId>empty());
selectorBuilder = DefaultTrafficSelector.builder();
selectorBuilder.matchEthType(TYPE_IPV6);
selectorBuilder.matchIPProtocol(PROTOCOL_ICMP6);
selectorBuilder.matchIcmpv6Type(NEIGHBOR_ADVERTISEMENT);
packetService.cancelPackets(selectorBuilder.build(),
- CONTROL, appId, Optional.<DeviceId>empty());
+ CONTROL, appId, Optional.<DeviceId>empty());
}
/**
diff --git a/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2MplsVCManager.java b/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2MplsVCManager.java
new file mode 100644
index 0000000..3a6c33d
--- /dev/null
+++ b/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2MplsVCManager.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.sdxl2;
+
+
+import org.onlab.packet.VlanId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.EncapsulationType;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.intent.Constraint;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.PointToPointIntent;
+import org.onosproject.net.intent.constraint.EncapsulationConstraint;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Manages Virtual Circuits using MPLS headers.
+ */
+public class SdxL2MplsVCManager extends SdxL2VCManager {
+
+ private static final int PRIORITY_OFFSET = 2000;
+ private static Logger log = LoggerFactory.getLogger(SdxL2MplsVCManager.class);
+
+ // TODO Remember to create two intents: one for IPv4 and one for IPv6
+
+ /**
+ * Creates an SDX-L2 MPLS VC Manager.
+ *
+ * @param sdxl2id application ID
+ * @param store reference to the SDX-L2 store
+ * @param intentService reference to the Intent service
+ */
+ public SdxL2MplsVCManager(ApplicationId sdxl2id,
+ SdxL2Store store,
+ IntentService intentService) {
+
+ super(sdxl2id, store, intentService);
+ log.info("Started");
+ }
+
+ @Override
+ public Collection<Intent> buildIntents(String sdxl2, SdxL2ConnectionPoint ingress,
+ SdxL2ConnectionPoint egress) {
+ List<Intent> intents = null;
+ TrafficSelector selector;
+ TrafficTreatment treatment;
+ List<Constraint> encapsulation;
+ Key key;
+
+ if (ingress.vlanIds().size() == egress.vlanIds().size()) {
+ intents = new ArrayList<Intent>();
+ if (ingress.vlanIds().size() == 0) {
+
+ selector = buildSelector(null, null);
+ treatment = DefaultTrafficTreatment.emptyTreatment();
+ encapsulation = buildConstraints();
+
+ key = generateIntentKey(sdxl2, ingress, egress, "1");
+
+ intents.add(PointToPointIntent.builder()
+ .appId(appId)
+ .key(key)
+ .selector(selector)
+ .treatment(treatment)
+ .constraints(encapsulation)
+ .ingressPoint(ingress.connectPoint())
+ .egressPoint(egress.connectPoint())
+ .priority(PRIORITY_OFFSET)
+ .build());
+ } else {
+
+ Iterator<VlanId> ingressTags = ingress.vlanIds().iterator();
+ Iterator<VlanId> egressTags = egress.vlanIds().iterator();
+ int index = 1;
+ while (ingressTags.hasNext()) {
+ selector = buildSelector(null, ingressTags.next());
+ treatment = buildTreatment(egressTags.next(),
+ null,
+ false);
+ encapsulation = buildConstraints();
+
+ key = generateIntentKey(sdxl2, ingress, egress, String.valueOf(index));
+
+ intents.add(PointToPointIntent.builder()
+ .appId(appId)
+ .key(key)
+ .selector(selector)
+ .treatment(treatment)
+ .constraints(encapsulation)
+ .ingressPoint(ingress.connectPoint())
+ .egressPoint(egress.connectPoint())
+ .priority(PRIORITY_OFFSET)
+ .build());
+ index = index + 1;
+ }
+
+ }
+ return intents;
+ }
+
+ if (ingress.vlanIds().size() == 1 && egress.vlanIds().size() == 0) {
+
+ Iterator<VlanId> ingressTags = ingress.vlanIds().iterator();
+ intents = new ArrayList<Intent>();
+
+ selector = buildSelector(null, ingressTags.next());
+ treatment = buildTreatment(null,
+ null,
+ true);
+ encapsulation = buildConstraints();
+
+
+ key = generateIntentKey(sdxl2, ingress, egress, "1");
+
+ intents.add(PointToPointIntent.builder()
+ .appId(appId)
+ .key(key)
+ .selector(selector)
+ .treatment(treatment)
+ .constraints(encapsulation)
+ .ingressPoint(ingress.connectPoint())
+ .egressPoint(egress.connectPoint())
+ .priority(PRIORITY_OFFSET)
+ .build());
+ return intents;
+
+ }
+
+ if (ingress.vlanIds().size() == 0 && egress.vlanIds().size() == 1) {
+
+ Iterator<VlanId> egressTags = egress.vlanIds().iterator();
+ intents = new ArrayList<Intent>();
+
+ selector = buildSelector(null, null);
+ treatment = buildTreatment(null,
+ egressTags.next(),
+ false);
+ encapsulation = buildConstraints();
+
+ key = generateIntentKey(sdxl2, ingress, egress, "1");
+
+ intents.add(PointToPointIntent.builder()
+ .appId(appId)
+ .key(key)
+ .selector(selector)
+ .treatment(treatment)
+ .constraints(encapsulation)
+ .ingressPoint(ingress.connectPoint())
+ .egressPoint(egress.connectPoint())
+ .priority(PRIORITY_OFFSET)
+ .build());
+ return intents;
+ }
+
+ log.warn(String.format(errorCreateIntents, ingress.name(), egress.name()));
+
+ return intents;
+ }
+
+ @Override
+ protected List<Constraint> buildConstraints() {
+ final List<Constraint> constraints = new LinkedList<>();
+ constraints.add(new EncapsulationConstraint(EncapsulationType.MPLS));
+ return constraints;
+ }
+
+}
\ No newline at end of file
diff --git a/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2Service.java b/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2Service.java
index 94629d7..8601abb 100644
--- a/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2Service.java
+++ b/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2Service.java
@@ -39,61 +39,94 @@
/**
* Deletes a named SDX-L2.
*
- * @param sdxl2 SDX-L2 name
+ * @param sdxl2 name of SDX-L2
*/
void deleteSdxL2(String sdxl2);
/**
* Returns a set of SDX-L2 names.
*
- * @return a set of SDX-L2 names
+ * @return set of SDX-L2 names
*/
Set<String> getSdxL2s();
/**
- * Adds an SDX-L2 connection point to an SDX-L2.
+ * Adds a Connection Point to an SDX-L2.
*
- * @param sdxl2 SDX-L2 name
- * @param sdxl2cp SDX-L2 connection point object
+ * @param sdxl2 name of SDX-L2
+ * @param sdxl2cp SDX-L2 Connection Point object
*/
void addSdxL2ConnectionPoint(String sdxl2, SdxL2ConnectionPoint sdxl2cp);
/**
- * Returns all the SDX-L2 connection points names in a SDX-L2 or all the SDX-L2 connection points names.
+ * Returns all names of Connection Points names in a SDX-L2 or
+ * all the names of SDX-L2 Connection Points.
*
- * @param sdxl2 SDX-L2 name
+ * @param sdxl2 name of SDX-L2
* @return a set of SDX-L2 connection points names
*/
Set<String> getSdxL2ConnectionPoints(Optional<String> sdxl2);
/**
- * Removes an SDX-L2 connection point from an SDX-L2.
+ * Removes a Connection Point from an SDX-L2.
*
- * @param sdxl2cp SDX-L2 connection point name
+ * @param sdxl2cp name of SDX-L2 Connection Point
*/
void removeSdxL2ConnectionPoint(String sdxl2cp);
/**
- * Returns an SDX-L2 connection point in a SDX-L2.
+ * Creates an L2 Virtual Circuit between two SDX-L2 Connection Points.
*
- * @param sdxl2cp SDX-L2 connection point name
+ * @param sdxl2 name of SDX-L2
+ * @param sdxl2cplhs name of SDX-L2 CP, left hand side of the VC
+ * @param sdxl2cprhs name of SDX-L2 CP, right hand side of the VC
+ */
+ void addVC(String sdxl2, String sdxl2cplhs, String sdxl2cprhs);
+
+ /**
+ * Deletes a Virtual Circuit between Connection Points in an SDX-L2.
+ *
+ * @param vc name of SDX-L2 VC
+ */
+ void removeVC(String vc);
+
+ /**
+ * Returns a Connection Point in an SDX-L2.
+ *
+ * @param sdxl2cp name of SDX-L2 Connection Point
* @return the relative SdxL2ConnectionPoint object
*/
SdxL2ConnectionPoint getSdxL2ConnectionPoint(String sdxl2cp);
/**
+ * Returns all the Virtual Circuits in an SDX-L2.
+ *
+ * @param sdxl2 name of SDX-L2
+ * @return set of Virtual Circuits names
+ */
+ Set<String> getVirtualCircuits(Optional<String> sdxl2);
+
+ /**
+ * Returns a Virtual Circuit in an SDX-L2.
+ *
+ * @param sdxl2vc name of the SDX-L2 VC
+ * @return the relative VirtualCircuit object
+ */
+ VirtualCircuit getVirtualCircuit(String sdxl2vc);
+
+ /**
* Returns the state of the Intent that has been provided as input.
*
- * @param intentKey key of the intent;
- * @return the last state of the intent;
+ * @param intentKey key of the intent
+ * @return the last state of the intent
*/
SdxL2State getIntentState(Key intentKey);
/**
* Returns the state of the EdgePort that has been provided as input.
*
- * @param edgeport the connect point representing the edge port
- * @return the last state of the edgeport;
+ * @param edgeport the Connection Point representing the edge port
+ * @return the last state of the edge port
*/
SdxL2State getEdgePortState(ConnectPoint edgeport);
diff --git a/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2Store.java b/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2Store.java
index c19ee42..0c465ee 100644
--- a/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2Store.java
+++ b/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2Store.java
@@ -27,32 +27,32 @@
/**
* Creates a named SDX-L2.
*
- * @param sdxl2 SDX-L2 name
- * @throws SdxL2Exception if SDX-L2 exists
+ * @param sdxl2 name of SDX-L2
+ * @throws SdxL2Exception if SDX-L2 is not added
*/
void putSdxL2(String sdxl2) throws SdxL2Exception;
/**
* Removes a named SDX-L2.
*
- * @param sdxl2 SDX-L2 name
- * @throws SdxL2Exception if SDX-L2 does not exist
+ * @param sdxl2 name of SDX-L2
+ * @throws SdxL2Exception if SDX-L2 is not removed
*/
void removeSdxL2(String sdxl2) throws SdxL2Exception;
/**
* Returns a set of SDX-L2 names.
*
- * @return a set of SDX-L2 names
+ * @return set of SDX-L2 names
*/
Set<String> getSdxL2s();
/**
- * Adds an SDX-L2 connection point to an SDX-L2.
+ * Adds a Connection Point to an SDX-L2.
*
- * @param sdxl2 SDX-L2 name
- * @param connectionPoint the SDX-L2 connection point object
- * @throws SdxL2Exception if it is not possible to add the SDX-L2 connection point
+ * @param sdxl2 name of SDX-L2
+ * @param connectionPoint SDX-L2 cCnnection Point object
+ * @throws SdxL2Exception if SDX-L2 is not added
*/
void addSdxL2ConnectionPoint(String sdxl2, SdxL2ConnectionPoint connectionPoint) throws SdxL2Exception;
@@ -60,28 +60,81 @@
* Returns all the SDX-L2 connection points names or the SDX-L2 connection points name
* that are related to an SDX-L2.
*
- * @param sdxl2 name (optional) of the SDX-L2
+ * @param sdxl2 name of the SDX-L2 (optional)
* @return a set of SDX-L2 connection points names, the result depends on the input parameter;
- * @throws SdxL2Exception if SDX-L2 is present but it does not exist
+ * @throws SdxL2Exception if SDX-L2 cannot be found
*/
Set<String> getSdxL2ConnectionPoints(Optional<String> sdxl2) throws SdxL2Exception;
-
/**
- * Removes a named SDX-L2 connection point in an SDX-L2.
+ * Removes a named Connection Point in an SDX-L2.
*
- * @param sdxl2cp the connection point name
- * @throws SdxL2Exception if the connection point does not exist
+ * @param sdxl2cp name of Connection Point
+ * @throws SdxL2Exception if SDX-L2 Connection Point does not exist
*/
void removeSdxL2ConnectionPoint(String sdxl2cp) throws SdxL2Exception;
/**
- * Returns an SDX-L2 connection point in a SDX-L2.
+ * Returns a Connection Point in a SDX-L2.
*
- * @param sdxl2cp the connection point name
- * @return the relative SDXL2ConnectionPoint object
- * @throws SdxL2Exception if SDX-L2 connection point does not exist
+ * @param sdxl2cp name of Connection Point
+ * @return relative SDX-L2 Connection Point
+ * @throws SdxL2Exception if SDX-L2 CP cannot be found
*/
SdxL2ConnectionPoint getSdxL2ConnectionPoint(String sdxl2cp) throws SdxL2Exception;
+ /**
+ * Creates a Virtual Circuit between two SDX-L2 Connection Points.
+ *
+ * @param sdxl2 name of SDX-L2
+ * @param sdxl2cplhs name of SDX-L2 CP, left hand side of the VC
+ * @param sdxl2cprhs name of SDX-L2 CP, right hand side of the VC
+ * @throws SdxL2Exception if SDX-L2 VC cannot be added
+ */
+ void addVC(String sdxl2, SdxL2ConnectionPoint sdxl2cplhs, SdxL2ConnectionPoint sdxl2cprhs)
+ throws SdxL2Exception;;
+
+ /**
+ * Deletes a Virtual Circuit between Connection Points in an SDX-L2.
+ *
+ * @param sdxl2cplhs name of SDX-L2 CP, left hand side of the VC
+ * @param sdxl2cprhs ame of SDX-L2 CP, right hand side of the VC
+ * @throws SdxL2Exception if no name is provided for VC
+ */
+ void removeVC(SdxL2ConnectionPoint sdxl2cplhs, SdxL2ConnectionPoint sdxl2cprhs)
+ throws SdxL2Exception;;
+
+ /**
+ * Deletes a Virtual Circuit where a given SDX-L2 CP acts as endpoint.
+ *
+ * @param cp Connection Point
+ * @throws SdxL2Exception if appropriate VC identifier is not provided
+ */
+ void removeVC(SdxL2ConnectionPoint cp) throws SdxL2Exception;;
+
+ /**
+ * Removes all Virtual Circuits created in a given SDX-L2.
+ *
+ * @param sdxl2 name of SDX-L2
+ */
+ void removeVCs(String sdxl2);
+
+ /**
+ * Returns an encoded Virtual Circuit in a SDX-L2.
+ *
+ * @param sdxl2cplhs name of SDX-L2 CP, left hand side of the VC
+ * @param sdxl2cprhs ame of SDX-L2 CP, right hand side of the VC
+ * @return the encoded Virtual Circuit
+ * @throws SdxL2Exception if no matching VC exists
+ */
+ String getVC(SdxL2ConnectionPoint sdxl2cplhs, SdxL2ConnectionPoint sdxl2cprhs)
+ throws SdxL2Exception;
+
+ /**
+ * Returns a) all Virtual Circuits, or b) Virtual Circuits in a given SDX-L2.
+ *
+ * @param sdxl2 name of SDX-L2
+ * @return set of names for Virtual Circuits
+ */
+ Set<String> getVCs(Optional<String> sdxl2);
}
diff --git a/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2VCManager.java b/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2VCManager.java
new file mode 100644
index 0000000..1d4d4e1
--- /dev/null
+++ b/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2VCManager.java
@@ -0,0 +1,309 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.sdxl2;
+
+import com.google.common.collect.Iterables;
+import org.apache.commons.lang.NotImplementedException;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.ApplicationId;
+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.intent.Constraint;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.intent.Key;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+
+import static java.lang.String.format;
+
+
+/**
+ * Manages Virtual Circuits.
+ * Base class extended by different types of VCs.
+ */
+public class SdxL2VCManager implements SdxL2VCService {
+
+ private static Logger log = LoggerFactory.getLogger(SdxL2VCManager.class);
+
+ protected static final String MATCH_FORMAT = "%s-%s";
+ protected static final String NAME_FORMAT = "%s:%s-%s";
+ protected static final String SDXL2_CPS_FORMAT = "%s~%s";
+ protected static final String KEY_FORMAT = "%s,%s";
+
+ protected ApplicationId appId;
+ protected SdxL2Store sdxL2Store;
+ protected IntentService intentService;
+
+ private static String errorIntentsForward = "Unable to create forward Intents";
+ private static String errorIntentsReverse = "Unable to create reverse Intents";
+ protected static String errorCreateIntents = "Unable to create Intents for %s-%s";
+
+
+ /**
+ * Creates an SDX-L2 VC Manager.
+ *
+ * @param sdxl2id application ID
+ * @param store reference to the SDX-L2 store
+ * @param intentService reference to the Intent service
+ */
+ public SdxL2VCManager(ApplicationId sdxl2id,
+ SdxL2Store store,
+ IntentService intentService) {
+
+ this.appId = sdxl2id;
+ this.sdxL2Store = store;
+ this.intentService = intentService;
+ }
+
+ @Override
+ public void addVC(String sdxl2, SdxL2ConnectionPoint sdxl2cplhs, SdxL2ConnectionPoint sdxl2cprhs) {
+ try {
+ this.sdxL2Store.addVC(sdxl2, sdxl2cplhs, sdxl2cprhs);
+
+ Collection<Intent> intentsFW = buildIntents(sdxl2, sdxl2cplhs, sdxl2cprhs);
+ Collection<Intent> intentsRV = buildIntents(sdxl2, sdxl2cprhs, sdxl2cplhs);
+
+ if (intentsFW == null) {
+ System.err.println("\u001B[0;31mError executing command: "
+ + errorIntentsForward + "\u001B[0;49m");
+ return;
+ }
+ if (intentsRV == null) {
+ System.err.println("\u001B[0;31mError executing command: "
+ + errorIntentsReverse + "\u001B[0;49m");
+ return;
+ }
+
+ List<Intent> intents = new ArrayList<Intent>();
+ intents.addAll(intentsFW);
+ intents.addAll(intentsRV);
+ intents.forEach(intent -> {
+ intentService.submit(intent);
+ });
+ } catch (SdxL2Exception e) {
+ log.error(e.getMessage());
+ }
+ }
+
+ @Override
+ public void removeVC(SdxL2ConnectionPoint sdxl2cplhs, SdxL2ConnectionPoint sdxl2cprhs) {
+ try {
+ this.sdxL2Store.removeVC(sdxl2cplhs, sdxl2cprhs);
+ Iterables.filter(intentService.getIntents(), intent ->
+ (matches(sdxl2cplhs, sdxl2cprhs, intent) ||
+ (matches(sdxl2cprhs, sdxl2cplhs, intent))))
+ .forEach(intentService::withdraw);
+ } catch (SdxL2Exception e) {
+ log.error(e.getMessage());
+ }
+ }
+
+ @Override
+ public void removeVC(SdxL2ConnectionPoint cp) {
+ try {
+ this.sdxL2Store.removeVC(cp);
+ Iterables.filter(intentService.getIntents(), intent -> (matches(cp, intent)))
+ .forEach(intentService::withdraw);
+ } catch (SdxL2Exception e) {
+ log.error(e.getMessage());
+ }
+ }
+
+ /**
+ * Creates a set of Intents for the ingress and egress SDX-L2 Connection Point.
+ *
+ * @param sdxl2 name of SDX-L2
+ * @param ingress the ingress point with the relative traffic attributes
+ * @param egress the egress point with the relative traffic attributes
+ * @return a set of intent or a null set;
+ */
+ public Collection<Intent> buildIntents(String sdxl2, SdxL2ConnectionPoint ingress,
+ SdxL2ConnectionPoint egress) {
+ throw new NotImplementedException("buildIntents not implemented");
+ }
+
+ /**
+ * Matches an intent given two SDX-L2 connection points.
+ *
+ * @param sdxl2cplhs left hand side of the virtual circuit
+ * @param sdxl2cprhs right hand side of the virtual circuit
+ * @param intent intent to match
+ * @return result of the match
+ */
+ protected boolean matches(SdxL2ConnectionPoint sdxl2cplhs, SdxL2ConnectionPoint sdxl2cprhs, Intent intent) {
+ if (!Objects.equals(appId, intent.appId())) {
+ // different app ids
+ return false;
+ }
+
+ String key = intent.key().toString();
+ String[] fields = key.split(":");
+ String cps = format(MATCH_FORMAT, sdxl2cplhs.name(), sdxl2cprhs.name());
+
+ return fields.length == 2 && fields[1].contains(cps);
+ }
+
+ /**
+ * Matches an intent given an SDX-L2 Connection Point.
+ *
+ * @param cp hand side of a Virtual Circuit
+ * @param intent intent to match
+ * @return result of the match
+ */
+ protected boolean matches(SdxL2ConnectionPoint cp, Intent intent) {
+ if (!Objects.equals(appId, intent.appId())) {
+ // different app ids
+ return false;
+ }
+
+ String key = intent.key().toString();
+ String[] fields = key.split(":");
+
+ if (fields.length != 2) {
+ return false;
+ }
+ String[] cps = fields[1].split(",");
+
+ if (cps.length != 2) {
+ return false;
+ }
+ String[] hss = cps[0].split("-");
+
+ return hss.length == 2 && (hss[0].equals(cp.name()) || hss[1].equals(cp.name()));
+ }
+
+ @Override
+ public void removeVCs(String sdxl2) {
+ this.sdxL2Store.removeVCs(sdxl2);
+ Iterables.filter(intentService.getIntents(), intent -> (matches(sdxl2, intent)))
+ .forEach(intentService::withdraw);
+
+ }
+
+ /**
+ * Matches an intent given an SDX-L2 Connection Point.
+ *
+ * @param sdxl2 name of SDX-L2
+ * @param intent intent to match
+ * @return result of the match
+ */
+ protected boolean matches(String sdxl2, Intent intent) {
+ if (!Objects.equals(appId, intent.appId())) {
+ // different app ids
+ return false;
+ }
+
+ String key = intent.key().toString();
+ String[] fields = key.split(":");
+
+ return fields.length == 2 && fields[0].equals(sdxl2);
+ }
+
+ @Override
+ public Set<String> getVCs(Optional<String> sdxl2) {
+ return this.sdxL2Store.getVCs(sdxl2);
+ }
+
+ @Override
+ public String getVC(SdxL2ConnectionPoint sdxl2cplhs, SdxL2ConnectionPoint sdxl2cprhs) {
+ try {
+ return this.sdxL2Store.getVC(sdxl2cplhs, sdxl2cprhs);
+ } catch (SdxL2Exception e) {
+ log.error(e.getMessage());
+ }
+ return null;
+ }
+
+ /**
+ * Returns Intent key from SDX-L2 and two SDX-L2 Connection Points.
+ *
+ * @param sdxl2 name of SDX-L2
+ * @param cpone sdxl2 connection point one
+ * @param cptwo sdxl2 connection point two
+ * @param index digit used to help identify Intent
+ * @return canonical intent string key
+ */
+ protected Key generateIntentKey(String sdxl2, SdxL2ConnectionPoint cpone,
+ SdxL2ConnectionPoint cptwo, String index) {
+ String cps = format(NAME_FORMAT, sdxl2, cpone.name(), cptwo.name());
+ String key = format(KEY_FORMAT, cps, index);
+ return Key.of(key, appId);
+ }
+
+ /**
+ * Returns the traffic treatment, used in the definition of the intents.
+ *
+ * @param setVlan VLAN to set
+ * @param pushVlan VLAN to push
+ * @param popVlan boolean to indicate whether a popVlan action is
+ * performed (true) or not (false)
+ * @return TrafficTreatment object
+ */
+ protected TrafficTreatment buildTreatment(VlanId setVlan,
+ VlanId pushVlan,
+ boolean popVlan) {
+ TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
+ if (setVlan != null) {
+ treatmentBuilder.setVlanId(setVlan);
+ }
+ if (pushVlan != null) {
+ treatmentBuilder.pushVlan();
+ treatmentBuilder.setVlanId(pushVlan);
+ }
+ if (popVlan) {
+ treatmentBuilder.popVlan();
+ }
+ return treatmentBuilder.build();
+ }
+
+ /**
+ * Returns the traffic selector, used in the definition of the intents.
+ *
+ * @param ethertype name of the Ethernet type used (e.g. of SDX-L2
+ * @param ingresstag VLAN id used at the ingress
+ * @return TrafficSelector object
+ */
+ protected TrafficSelector buildSelector(Short ethertype, VlanId ingresstag) {
+ TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
+ if (ethertype != null) {
+ selectorBuilder.matchEthType(ethertype);
+ }
+ if (ingresstag != null) {
+ selectorBuilder.matchVlanId(ingresstag);
+ }
+ return selectorBuilder.build();
+ }
+
+ /**
+ * Returns constraints depending on the encapsulation used on the VC.
+ *
+ * @return list of constraints to be used in the intents
+ */
+ protected List<Constraint> buildConstraints() {
+ throw new NotImplementedException("buildConstraints not implemented");
+ }
+}
\ No newline at end of file
diff --git a/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2VCService.java b/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2VCService.java
new file mode 100644
index 0000000..6f65b8b
--- /dev/null
+++ b/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2VCService.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.sdxl2;
+
+import java.util.Optional;
+import java.util.Set;
+
+/**
+ * Service that allows the creation of L2 Virtual Circuits
+ * between edge ports of a given SDN network.
+ */
+public interface SdxL2VCService {
+
+ /**
+ * Creates an L2 Virtual Circuit between two SDX-L2 Connection Points.
+ *
+ * @param sdxl2 name of SDX-L2
+ * @param sdxl2cplhs name of SDX-L2 CP, left hand side of the VC
+ * @param sdxl2cprhs name of SDX-L2 CP, right hand side of the VC
+ */
+ void addVC(String sdxl2, SdxL2ConnectionPoint sdxl2cplhs, SdxL2ConnectionPoint sdxl2cprhs);
+
+ /**
+ * Deletes a Virtual Circuit from an SDX-L2.
+ *
+ * @param sdxl2cplhs name of SDX-L2 CP, left hand side of the VC
+ * @param sdxl2cprhs name of SDX-L2 CP, right hand side of the VC
+ */
+ void removeVC(SdxL2ConnectionPoint sdxl2cplhs, SdxL2ConnectionPoint sdxl2cprhs);
+
+ /**
+ * Deletes a Virtual Circuit where a given SDX-L2 CP acts as endpoint.
+ *
+ * @param cp Connection Point
+ */
+ void removeVC(SdxL2ConnectionPoint cp);
+
+ /**
+ * Removes all Virtual Circuits created in a given SDX-L2.
+ *
+ * @param sdxl2 name of SDX-L2
+ */
+ void removeVCs(String sdxl2);
+
+ /**
+ * Returns Virtual Circuits (either all or those created in a given SDX-L2).
+ *
+ * @param sdxl2 name of SDX-L2
+ * @return the set of virtual circuits name
+ */
+ Set<String> getVCs(Optional<String> sdxl2);
+
+ /**
+ * Returns an encoded Virtual Circuit in a given SDX-L2.
+ *
+ * @param lhs left hand side of the VC
+ * @param rhs right hand side of the VC
+ * @return encoded VC
+ */
+ String getVC(SdxL2ConnectionPoint lhs, SdxL2ConnectionPoint rhs);
+}
diff --git a/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2VlanVCManager.java b/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2VlanVCManager.java
new file mode 100644
index 0000000..ddf6896
--- /dev/null
+++ b/sdx-l2/src/main/java/org/onosproject/sdxl2/SdxL2VlanVCManager.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.sdxl2;
+
+
+import org.onlab.packet.VlanId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.EncapsulationType;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.intent.Constraint;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.PointToPointIntent;
+import org.onosproject.net.intent.constraint.EncapsulationConstraint;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Manages Virtual Circuits using VLANs.
+ */
+public class SdxL2VlanVCManager extends SdxL2VCManager {
+
+ private static final int PRIORITY_OFFSET = 2000;
+ private static Logger log = LoggerFactory.getLogger(SdxL2VlanVCManager.class);
+
+ /**
+ * Creates an SDX-L2 VLAN VC Manager.
+ *
+ * @param sdxl2id application ID
+ * @param store reference to the SDX-L2 store
+ * @param intentService reference to the Intent service
+ */
+ public SdxL2VlanVCManager(ApplicationId sdxl2id,
+ SdxL2Store store,
+ IntentService intentService) {
+ super(sdxl2id, store, intentService);
+ log.info("Started");
+ }
+
+ @Override
+ public Collection<Intent> buildIntents(String sdxl2, SdxL2ConnectionPoint ingress, SdxL2ConnectionPoint egress) {
+ List<Intent> intents = null;
+ TrafficSelector selector;
+ TrafficTreatment treatment;
+ List<Constraint> encapsulation;
+ Key key;
+
+ if (ingress.vlanIds().size() == egress.vlanIds().size()) {
+ intents = new ArrayList<Intent>();
+ if (ingress.vlanIds().size() == 0) {
+
+ selector = buildSelector(null, null);
+ treatment = DefaultTrafficTreatment.emptyTreatment();
+ encapsulation = buildConstraints();
+
+ key = generateIntentKey(sdxl2, ingress, egress, "1");
+
+ intents.add(PointToPointIntent.builder()
+ .appId(appId)
+ .key(key)
+ .selector(selector)
+ .treatment(treatment)
+ .constraints(encapsulation)
+ .ingressPoint(ingress.connectPoint())
+ .egressPoint(egress.connectPoint())
+ .priority(PRIORITY_OFFSET)
+ .build());
+ } else {
+
+ Iterator<VlanId> ingressTags = ingress.vlanIds().iterator();
+ Iterator<VlanId> egressTags = egress.vlanIds().iterator();
+ int index = 1;
+ while (ingressTags.hasNext()) {
+
+ selector = buildSelector(null, ingressTags.next());
+ treatment = buildTreatment(egressTags.next(),
+ null,
+ false);
+ encapsulation = buildConstraints();
+
+ key = generateIntentKey(sdxl2, ingress, egress, String.valueOf(index));
+
+ intents.add(PointToPointIntent.builder()
+ .appId(appId)
+ .key(key)
+ .selector(selector)
+ .treatment(treatment)
+ .constraints(encapsulation)
+ .ingressPoint(ingress.connectPoint())
+ .egressPoint(egress.connectPoint())
+ .priority(PRIORITY_OFFSET)
+ .build());
+ index = index + 1;
+ }
+
+ }
+ return intents;
+ }
+
+ if (ingress.vlanIds().size() == 1 && egress.vlanIds().size() == 0) {
+
+ Iterator<VlanId> ingressTags = ingress.vlanIds().iterator();
+ intents = new ArrayList<Intent>();
+
+ selector = buildSelector(null, ingressTags.next());
+ treatment = buildTreatment(null,
+ null,
+ true);
+ encapsulation = buildConstraints();
+
+
+ key = generateIntentKey(sdxl2, ingress, egress, "1");
+
+ intents.add(PointToPointIntent.builder()
+ .appId(appId)
+ .key(key)
+ .selector(selector)
+ .treatment(treatment)
+ .constraints(encapsulation)
+ .ingressPoint(ingress.connectPoint())
+ .egressPoint(egress.connectPoint())
+ .priority(PRIORITY_OFFSET)
+ .build());
+ return intents;
+
+ }
+
+ if (ingress.vlanIds().size() == 0 && egress.vlanIds().size() == 1) {
+
+ Iterator<VlanId> egressTags = egress.vlanIds().iterator();
+ intents = new ArrayList<Intent>();
+
+ selector = buildSelector(null, null);
+ treatment = buildTreatment(null,
+ egressTags.next(),
+ false);
+ encapsulation = buildConstraints();
+
+ key = generateIntentKey(sdxl2, ingress, egress, "1");
+
+ intents.add(PointToPointIntent.builder()
+ .appId(appId)
+ .key(key)
+ .selector(selector)
+ .treatment(treatment)
+ .constraints(encapsulation)
+ .ingressPoint(ingress.connectPoint())
+ .egressPoint(egress.connectPoint())
+ .priority(PRIORITY_OFFSET)
+ .build());
+ return intents;
+ }
+
+ log.warn(String.format(errorCreateIntents, ingress.name(), egress.name()));
+
+ return intents;
+ }
+
+ @Override
+ protected List<Constraint> buildConstraints() {
+ final List<Constraint> constraints = new LinkedList<>();
+ constraints.add(new EncapsulationConstraint(EncapsulationType.VLAN));
+ return constraints;
+ }
+
+}
\ No newline at end of file
diff --git a/sdx-l2/src/main/java/org/onosproject/sdxl2/VirtualCircuit.java b/sdx-l2/src/main/java/org/onosproject/sdxl2/VirtualCircuit.java
new file mode 100644
index 0000000..1561382
--- /dev/null
+++ b/sdx-l2/src/main/java/org/onosproject/sdxl2/VirtualCircuit.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.sdxl2;
+
+import com.google.common.base.MoreObjects;
+
+import java.util.Objects;
+
+/**
+ * Abstraction of a L2 Virtual Circuit.
+ * Note the circuit is expressed as a composition of two SDX-L2 Connection Points.
+ */
+public class VirtualCircuit {
+
+ private final String name;
+ private final SdxL2ConnectionPoint sdxl2cplhs;
+ private final SdxL2ConnectionPoint sdxl2cprhs;
+
+ /**
+ * Creates a new Virtual Circuit.
+ *
+ * @param sdxl2cplhs left hand side of the virtual circuit
+ * @param sdxl2cprhs right hand side of the virtual circuit
+ */
+ public VirtualCircuit(SdxL2ConnectionPoint sdxl2cplhs, SdxL2ConnectionPoint sdxl2cprhs) {
+ this.name = sdxl2cplhs.name() + "-" + sdxl2cprhs.name();
+ this.sdxl2cplhs = sdxl2cplhs;
+ this.sdxl2cprhs = sdxl2cprhs;
+ }
+
+ /**
+ * Returns the left hand side of the Virtual Circuit.
+ *
+ * @return SDX-L2 Connection Point
+ */
+ public SdxL2ConnectionPoint lhs() {
+ return sdxl2cplhs;
+ }
+
+ /**
+ * Returns the right hand side of the Virtual Circuit.
+ *
+ * @return SDX-L2 Connection Point
+ */
+ public SdxL2ConnectionPoint rhs() {
+ return sdxl2cprhs;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(name, sdxl2cplhs, sdxl2cprhs);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof VirtualCircuit) {
+ final VirtualCircuit other = (VirtualCircuit) obj;
+ return (Objects.equals(this.sdxl2cplhs, other.sdxl2cplhs) &&
+ Objects.equals(this.sdxl2cprhs, other.sdxl2cprhs)) ||
+ (Objects.equals(this.sdxl2cplhs, other.sdxl2cprhs) &&
+ Objects.equals(this.sdxl2cprhs, other.sdxl2cplhs));
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("name", name)
+ .add("lhs", sdxl2cplhs)
+ .add("rhs", sdxl2cprhs)
+ .toString();
+ }
+}
diff --git a/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2AddCPCommand.java b/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2AddCPCommand.java
index eb000b8..ea13441 100644
--- a/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2AddCPCommand.java
+++ b/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2AddCPCommand.java
@@ -27,38 +27,33 @@
/**
* CLI to create a named SDX-L2 connection point.
*/
-@Command(scope = "sdxl2", name = "sdxl2cp-add", description = "Create a named sdx-l2 connection point")
+@Command(scope = "sdxl2", name = "sdxl2cp-add", description = "Creates a named SDX-L2 Connection Point")
public class SdxL2AddCPCommand extends AbstractShellCommand {
- @Argument(index = 0, name = "sdxl2name", description = "Sdxl2name",
+ @Argument(index = 0, name = "sdxl2name", description = "Name of SDX-L2",
required = true, multiValued = false)
- String sdxl2name = null;
+ private String sdxl2name = null;
- @Argument(index = 1, name = "connectionpoint", description = "Connection point",
+ @Argument(index = 1, name = "connectionpoint", description = "Identifier of SDX-L2 Connection point",
required = true, multiValued = false)
- String cp = null;
+ private String cp = null;
- @Argument(index = 2, name = "vlans", description = "Customer edge vlans separated by comma",
+ @Argument(index = 2, name = "sdxl2cpname", description = "Name of SDX-L2 Connection Point",
required = true, multiValued = false)
- String vlans = null;
+ private String sdxl2cpname = null;
- @Argument(index = 3, name = "sdxl2cpname", description = "Sdxl2 connection point name",
- required = true, multiValued = false)
- String sdxl2cpname = null;
+ @Argument(index = 3, name = "vlans", description = "Customer edge VLANs, separated by dash " +
+ "and comma", required = false, multiValued = false)
+ private String vlans = null;
- @Option(name = "-ce_mac", description = "Customer edge mac address",
+ @Option(name = "-ce_mac", description = "Customer edge MAC address",
required = false, multiValued = false)
- String mac = null;
+ private String mac = null;
@Override
protected void execute() {
SdxL2Service sdxl2Service = get(SdxL2Service.class);
- SdxL2ConnectionPoint sdxl2cp;
- if (mac != null) {
- sdxl2cp = SdxL2ConnectionPoint.sdxl2ConnectionPoint(sdxl2cpname, cp, vlans, mac);
- } else {
- sdxl2cp = SdxL2ConnectionPoint.sdxl2ConnectionPoint(sdxl2cpname, cp, vlans);
- }
+ SdxL2ConnectionPoint sdxl2cp = SdxL2ConnectionPoint.sdxl2ConnectionPoint(sdxl2cpname, cp, vlans, mac);
sdxl2Service.addSdxL2ConnectionPoint(sdxl2name, sdxl2cp);
}
diff --git a/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2AddCommand.java b/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2AddCommand.java
index c7bb963..4aea7be 100644
--- a/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2AddCommand.java
+++ b/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2AddCommand.java
@@ -24,11 +24,11 @@
/**
* CLI to create SDX-L2.
*/
-@Command(scope = "sdxl2", name = "sdxl2-add", description = "Create a sdx-l2")
+@Command(scope = "sdxl2", name = "sdxl2-add", description = "Creates a SDX-L2")
public class SdxL2AddCommand extends AbstractShellCommand {
- @Argument(index = 0, name = "sdxl2name", description = "Sdxl2 name", required = true, multiValued = false)
- String sdxl2 = null;
+ @Argument(index = 0, name = "sdxl2name", description = "Name of SDX-L2", required = true, multiValued = false)
+ private String sdxl2 = null;
@Override
protected void execute() {
diff --git a/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2AddVCCommand.java b/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2AddVCCommand.java
new file mode 100644
index 0000000..2a75e37
--- /dev/null
+++ b/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2AddVCCommand.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.sdxl2.cli;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.sdxl2.SdxL2Service;
+
+/**
+ * CLI to create a VC between two Connection Points in the same SDX-L2.
+ */
+@Command(scope = "sdxl2", name = "sdxl2vc-add",
+ description = "Creates a VC between two Connection Points in the same SDX-L2")
+public class SdxL2AddVCCommand extends AbstractShellCommand {
+
+ @Argument(index = 0, name = "sdxl2name", description = "Name of SDX-L2",
+ required = true, multiValued = false)
+ private String sdxL2name = null;
+
+ @Argument(index = 1, name = "lhs", description = "Left hand side Connection Point",
+ required = true, multiValued = false)
+ private String lhs = null;
+
+ @Argument(index = 2, name = "rhs", description = "Right hand side Connection Point",
+ required = true, multiValued = false)
+ private String rhs = null;
+
+ @Override
+ protected void execute() {
+ SdxL2Service sdxl2Service = get(SdxL2Service.class);
+ sdxl2Service.addVC(sdxL2name, lhs, rhs);
+ }
+}
diff --git a/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2GetCPCommand.java b/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2GetCPCommand.java
index 8f5b3ea..779da65 100644
--- a/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2GetCPCommand.java
+++ b/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2GetCPCommand.java
@@ -24,13 +24,13 @@
import org.onosproject.sdxl2.SdxL2State;
/**
- * Cli to print the details of an SdxL2ConnectionPoint.
+ * CLI to print the details of an SdxL2ConnectionPoint.
*/
-@Command(scope = "sdxl2", name = "sdxl2cp", description = "Prints the details of an SDXL2ConnectionPoint")
+@Command(scope = "sdxl2", name = "sdxl2cp", description = "Prints the details of an SDX-L2 Connection Point")
public class SdxL2GetCPCommand extends AbstractShellCommand {
- @Argument(index = 0, name = "sdxl2cpname", description = "Sdxl2cp name", required = true, multiValued = false)
- String sdxl2cpname = null;
+ @Argument(index = 0, name = "sdxl2cpname", description = "Name of SDX-L2", required = true, multiValued = false)
+ private String sdxl2cpname = null;
private static final String HEADER = "\n\u001B[1;37mStatus\t\t" +
"Connection Point\t\tName\t\tVlan IDs\t\tCE Mac Address\u001B[0m";
diff --git a/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2GetVCCommand.java b/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2GetVCCommand.java
new file mode 100644
index 0000000..66efaf7
--- /dev/null
+++ b/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2GetVCCommand.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.sdxl2.cli;
+
+import com.google.common.collect.Iterables;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.intent.Key;
+import org.onosproject.sdxl2.SdxL2ConnectionPoint;
+import org.onosproject.sdxl2.SdxL2Service;
+import org.onosproject.sdxl2.SdxL2State;
+import org.onosproject.sdxl2.VirtualCircuit;
+
+import java.util.Iterator;
+
+import static java.lang.String.format;
+
+/**
+ * CLI to print the details of a Virtual Circuit in an SDX-L2.
+ */
+@Command(scope = "sdxl2", name = "sdxl2vc", description = "Prints the details of an SDX-L2 Virtual Circuit")
+public class SdxL2GetVCCommand extends AbstractShellCommand {
+
+ @Argument(index = 0, name = "sdxl2vcname", description = "Name of SDX-L2 VC", required = true, multiValued = false)
+ private String sdxl2vcname = null;
+
+ private static final String MATCH_FORMAT = "%s-%s";
+ private static final String HEADER_CP =
+ "\n\u001B[1;37mStatus\t\tConnection Point\t\tName\t\tVlan IDs\t\tCE Mac Address\u001B[0m";
+ private static final String SEPARATOR_CP = "\u001B[1;37m------------" +
+ "-----------------------------------------------------------" +
+ "--------------------------------------\u001B[0m";
+ private static final String FORMAT_SDXL2CP_ONLINE =
+ "\u001B[1;32m%s\u001B[0m\t\t\u001B[1;37m%s/%s\t\t%s\t\t%s\t\t%s\u001B[0m";
+ private static final String FORMAT_SDXL2CP_OFFLINE =
+ "\u001B[1;31m%s\u001B[0m\t\t\u001B[1;37m%s/%s\t\t%s\t\t%s\t\t%s\u001B[0m";
+
+ private static final String HEADER_VC =
+ "\n\u001B[1;37mStatus\t\tIntent\u001B[0m";
+ private static final String SEPARATOR_VC =
+ "\u001B[1;37m--------------------------------------------\u001B[0m";
+ private static final String FORMAT_SDXL2VC_ONLINE =
+ "\u001B[1;32m%s\u001B[0m\t\t\u001B[1;37m%s\u001B[0m";
+ private static final String FORMAT_SDXL2VC_OFFLINE =
+ "\u001B[1;31m%s\u001B[0m\t\t\u001B[1;37m%s\u001B[0m";
+ private static final String FORMAT_SDXL2VC_CHECK =
+ "\u001B[1;33m%s\u001B[0m\t\t\u001B[1;37m%s\u001B[0m";
+
+ @Override
+ protected void execute() {
+ SdxL2Service sdxl2Service = get(SdxL2Service.class);
+ VirtualCircuit virtualCircuit;
+ SdxL2ConnectionPoint sdxl2ConnectionPoint;
+ SdxL2State state;
+ virtualCircuit = sdxl2Service.getVirtualCircuit(sdxl2vcname);
+ if (virtualCircuit == null) {
+ return;
+ }
+
+ print(HEADER_CP);
+ print(SEPARATOR_CP);
+
+ sdxl2ConnectionPoint = virtualCircuit.lhs();
+ state = sdxl2Service.getEdgePortState(sdxl2ConnectionPoint.connectPoint());
+ if (state == SdxL2State.ONLINE) {
+ print(FORMAT_SDXL2CP_ONLINE,
+ "ONLINE",
+ sdxl2ConnectionPoint.connectPoint().elementId(),
+ sdxl2ConnectionPoint.connectPoint().port(),
+ sdxl2ConnectionPoint.name(),
+ sdxl2ConnectionPoint.vlanIds(),
+ sdxl2ConnectionPoint.macAddress());
+ } else if (state == SdxL2State.OFFLINE) {
+ print(FORMAT_SDXL2CP_OFFLINE,
+ "OFFLINE",
+ sdxl2ConnectionPoint.connectPoint().elementId(),
+ sdxl2ConnectionPoint.connectPoint().port(),
+ sdxl2ConnectionPoint.name(),
+ sdxl2ConnectionPoint.vlanIds(),
+ sdxl2ConnectionPoint.macAddress());
+ }
+
+
+ sdxl2ConnectionPoint = virtualCircuit.rhs();
+ state = sdxl2Service.getEdgePortState(sdxl2ConnectionPoint.connectPoint());
+ if (state == SdxL2State.ONLINE) {
+ print(FORMAT_SDXL2CP_ONLINE,
+ "ONLINE",
+ sdxl2ConnectionPoint.connectPoint().elementId(),
+ sdxl2ConnectionPoint.connectPoint().port(),
+ sdxl2ConnectionPoint.name(),
+ sdxl2ConnectionPoint.vlanIds(),
+ sdxl2ConnectionPoint.macAddress());
+ } else if (state == SdxL2State.OFFLINE) {
+ print(FORMAT_SDXL2CP_OFFLINE,
+ "OFFLINE",
+ sdxl2ConnectionPoint.connectPoint().elementId(),
+ sdxl2ConnectionPoint.connectPoint().port(),
+ sdxl2ConnectionPoint.name(),
+ sdxl2ConnectionPoint.vlanIds(),
+ sdxl2ConnectionPoint.macAddress());
+ }
+ print("");
+
+ print(HEADER_VC);
+ print(SEPARATOR_VC);
+ IntentService intentService = get(IntentService.class);
+ Iterator<Intent> intents = Iterables.filter(intentService.getIntents(), intent ->
+ (matches(virtualCircuit.lhs(), virtualCircuit.rhs(), intent) ||
+ (matches(virtualCircuit.rhs(), virtualCircuit.lhs(), intent)))).iterator();
+ Intent intent;
+ Key key;
+ while (intents.hasNext()) {
+ intent = intents.next();
+ key = intent.key();
+ state = sdxl2Service.getIntentState(key);
+ if (state == SdxL2State.ONLINE) {
+ print(FORMAT_SDXL2VC_ONLINE,
+ "ONLINE",
+ key);
+ } else if (state == SdxL2State.OFFLINE) {
+ print(FORMAT_SDXL2VC_OFFLINE,
+ "OFFLINE",
+ key);
+ } else {
+ print(FORMAT_SDXL2VC_CHECK,
+ "CHECK",
+ key);
+ }
+ }
+ print("");
+ }
+
+ /**
+ * Matches an intent given two sdxl2 connection points.
+ *
+ * @param lhs left hand side of the virtual circuit
+ * @param rhs right hand side of the virtual circuit
+ * @param intent intent to match
+ * @return result of the match
+ */
+ private boolean matches(SdxL2ConnectionPoint lhs, SdxL2ConnectionPoint rhs, Intent intent) {
+
+ String key = intent.key().toString();
+ String[] fields = key.split(":");
+ String cps = format(MATCH_FORMAT, lhs.name(), rhs.name());
+
+ return fields.length == 2 && fields[1].contains(cps);
+ }
+}
diff --git a/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2ListCPCommand.java b/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2ListCPCommand.java
index b25f349..4e702af 100644
--- a/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2ListCPCommand.java
+++ b/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2ListCPCommand.java
@@ -29,12 +29,12 @@
/**
* CLI to list the SDX-L2 connection points.
*/
-@Command(scope = "sdxl2", name = "sdxl2cps-list", description = "Lists " +
- "all the sdxl2 connection points. Argument not required the name of sdxl2")
+@Command(scope = "sdxl2", name = "sdxl2cp-list", description = "Lists " +
+ "all the SDX-L2 Connection Points. Argument not required the name of SDX-L2")
public class SdxL2ListCPCommand extends AbstractShellCommand {
- @Argument(index = 0, name = "sdxl2name", description = "sdxl2name", required = false, multiValued = false)
- String sdxl2 = null;
+ @Argument(index = 0, name = "sdxl2name", description = "Name of SDX-L2", required = false, multiValued = false)
+ private String sdxl2 = null;
private static final String HEADER = "\n\u001B[1;37mStatus\t\tSDXL2 Connection Point\u001B[0m";
private static final String SEPARATOR = "\u001B[1;37m-----------------------------------------------\u001B[0m";
@@ -48,9 +48,9 @@
Set<String> result = sdxl2Service.getSdxL2ConnectionPoints(sdxl2name);
SdxL2ConnectionPoint sdxl2ConnectionPoint;
SdxL2State sdxl2cpState;
+ print(HEADER);
+ print(SEPARATOR);
if (result.size() > 0) {
- print(HEADER);
- print(SEPARATOR);
for (String sdxl2cp : result) {
sdxl2ConnectionPoint = sdxl2Service.getSdxL2ConnectionPoint(sdxl2cp);
if (sdxl2ConnectionPoint == null) {
diff --git a/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2ListCommand.java b/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2ListCommand.java
index 42f91d1..f03b656 100644
--- a/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2ListCommand.java
+++ b/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2ListCommand.java
@@ -25,7 +25,7 @@
/**
* CLI to list the SDX-L2s.
*/
-@Command(scope = "sdxl2", name = "sdxl2-list", description = "Lists the sdx-l2s")
+@Command(scope = "sdxl2", name = "sdxl2-list", description = "Lists the SDX-L2s")
public class SdxL2ListCommand extends AbstractShellCommand {
private static final String HEADER = "\n\u001B[1;37mSDXL2\u001B[0m";
diff --git a/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2ListVCCommand.java b/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2ListVCCommand.java
new file mode 100644
index 0000000..13eb0f9
--- /dev/null
+++ b/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2ListVCCommand.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.sdxl2.cli;
+
+import com.google.common.collect.Iterables;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.intent.Key;
+import org.onosproject.sdxl2.SdxL2ConnectionPoint;
+import org.onosproject.sdxl2.SdxL2Service;
+import org.onosproject.sdxl2.SdxL2State;
+import org.onosproject.sdxl2.VirtualCircuit;
+
+import java.util.Iterator;
+import java.util.Optional;
+import java.util.Set;
+
+import static java.lang.String.format;
+
+/**
+ * CLI to delete a Connection Point in an SDX-L2.
+ */
+@Command(scope = "sdxl2", name = "sdxl2vc-list",
+ description = "Lists all the SDX-L2 Virtual Circuits. Argument not required the name of SDX-L2")
+public class SdxL2ListVCCommand extends AbstractShellCommand {
+
+ @Argument(index = 0, name = "Name of SDX-L2",
+ description = "Sdxl2 name", required = false, multiValued = false)
+ private String sdxl2 = null;
+
+ private static final String MATCH_FORMAT = "%s-%s";
+
+ private static final String HEADER =
+ "\n\u001B[1;37mStatus\t\tVirtual Circuit\u001B[0m";
+ private static final String SEPARATOR =
+ "\u001B[1;37m-----------------------------------------------\u001B[0m";
+ private static final String FORMAT_SDXL2VC_ONLINE =
+ "\u001B[1;32m%s\u001B[0m\t\t\u001B[1;37m%s\u001B[0m";
+ private static final String FORMAT_SDXL2VC_OFFLINE =
+ "\u001B[1;31m%s\u001B[0m\t\t\u001B[1;37m%s\u001B[0m";
+ private static final String FORMAT_SDXL2VC_CHECK =
+ "\u001B[1;33m%s\u001B[0m\t\t\u001B[1;37m%s\u001B[0m";
+
+
+ @Override
+ protected void execute() {
+ SdxL2Service sdxl2Service = get(SdxL2Service.class);
+ Optional<String> sdxl2name = Optional.ofNullable(sdxl2);
+ Set<String> result = sdxl2Service.getVirtualCircuits(sdxl2name);
+ VirtualCircuit vc;
+ SdxL2State state;
+ print(HEADER);
+ print(SEPARATOR);
+ if (result.size() > 0) {
+ String[] sdxl2VC;
+ for (String sdxl2vc : result) {
+ sdxl2VC = sdxl2vc.split(":");
+ vc = sdxl2Service.getVirtualCircuit(sdxl2vc);
+ if (vc == null) {
+ break;
+ }
+ state = this.getVirtualCircuitState(vc);
+ if (state == SdxL2State.ONLINE) {
+ print(FORMAT_SDXL2VC_ONLINE, "ONLINE", sdxl2VC[1]);
+ } else if (state == SdxL2State.OFFLINE) {
+ print(FORMAT_SDXL2VC_OFFLINE, "OFFLINE", sdxl2VC[1]);
+ } else {
+ print(FORMAT_SDXL2VC_CHECK, "CHECK", sdxl2VC[1]);
+ }
+ }
+ print("");
+ }
+ }
+
+ /**
+ * Retrieves status of a Virtual Circuit from the status of its
+ * Connection Points.
+ *
+ * @param vc VirtualCircuit object
+ * @return state of the Virtual Circuit
+ */
+ private SdxL2State getVirtualCircuitState(VirtualCircuit vc) {
+ IntentService intentService = get(IntentService.class);
+ SdxL2Service sdxl2Service = get(SdxL2Service.class);
+ SdxL2State intentState = SdxL2State.ONLINE;
+ SdxL2State lhsState;
+ SdxL2State rhsstate;
+ Iterator<Intent> intents = Iterables.filter(intentService.getIntents(), intent ->
+ (matches(vc.lhs(), vc.rhs(), intent) ||
+ (matches(vc.rhs(), vc.lhs(), intent)))).iterator();
+ Intent intent;
+ Key key;
+ int numIntents = 0;
+ int numIntentsOffline = 0;
+ while (intents.hasNext()) {
+ intent = intents.next();
+ key = intent.key();
+ intentState = sdxl2Service.getIntentState(key);
+ if (intentState == SdxL2State.OFFLINE || intentState == SdxL2State.CHECK) {
+ numIntentsOffline = numIntentsOffline + 1;
+ }
+ numIntents = numIntents + 1;
+ }
+
+ if (numIntents == numIntentsOffline) {
+ return SdxL2State.OFFLINE;
+ }
+
+ lhsState = sdxl2Service.getEdgePortState(vc.lhs().connectPoint());
+ if (lhsState == SdxL2State.OFFLINE) {
+ return SdxL2State.OFFLINE;
+ }
+
+ rhsstate = sdxl2Service.getEdgePortState(vc.rhs().connectPoint());
+ if (rhsstate == SdxL2State.OFFLINE) {
+ return SdxL2State.OFFLINE;
+ }
+
+ if (intentState == SdxL2State.ONLINE && lhsState == SdxL2State.ONLINE &&
+ rhsstate == SdxL2State.ONLINE) {
+ return SdxL2State.ONLINE;
+ }
+
+ return SdxL2State.CHECK;
+ }
+
+ /**
+ * Matches an intent given two SDX-L2 Connection Points.
+ *
+ * @param lhs left hand side of the virtual circuit
+ * @param rhs right hand side of the virtual circuit
+ * @param intent intent to match
+ * @return result of the match
+ */
+ private boolean matches(SdxL2ConnectionPoint lhs, SdxL2ConnectionPoint rhs, Intent intent) {
+ String key = intent.key().toString();
+ String[] fields = key.split(":");
+ String cps = format(MATCH_FORMAT, lhs.name(), rhs.name());
+
+ return fields.length == 2 && fields[1].contains(cps);
+ }
+}
diff --git a/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2RemoveCPCommand.java b/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2RemoveCPCommand.java
index 3e1dfee..00da8c5 100644
--- a/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2RemoveCPCommand.java
+++ b/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2RemoveCPCommand.java
@@ -23,14 +23,14 @@
import org.onosproject.sdxl2.SdxL2Service;
/**
- * CLI to delete a named SDX-L2 connection point.
+ * CLI to delete a named SDX-L2 Connection Point.
*/
-@Command(scope = "sdxl2", name = "sdxl2cp-remove", description = "Remove a named sdxl2 connection point")
+@Command(scope = "sdxl2", name = "sdxl2cp-remove", description = "Removes a named SDX-L2 Connection Point")
public class SdxL2RemoveCPCommand extends AbstractShellCommand {
- @Argument(index = 0, name = "sdxl2cpname", description = "Sdxl2 connection point name",
+ @Argument(index = 0, name = "sdxl2cpname", description = "Name of SDX-L2 Connection Point",
required = true, multiValued = false)
- String sdxl2cpname = null;
+ private String sdxl2cpname = null;
@Override
protected void execute() {
diff --git a/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2RemoveCommand.java b/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2RemoveCommand.java
index aecb899..ab416e4 100644
--- a/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2RemoveCommand.java
+++ b/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2RemoveCommand.java
@@ -24,12 +24,12 @@
/**
* CLI to delete a named SDX-L2.
*/
-@Command(scope = "sdxl2", name = "sdxl2-remove", description = "Delete a sdx-l2")
+@Command(scope = "sdxl2", name = "sdxl2-remove", description = "Deletes a SDX-L2")
public class SdxL2RemoveCommand extends AbstractShellCommand {
- @Argument(index = 0, name = "sdxl2name", description = "Sdxl2 name",
+ @Argument(index = 0, name = "sdxl2name", description = "Name of SDX-L2",
required = true, multiValued = false)
- String sdxl2 = null;
+ private String sdxl2 = null;
@Override
protected void execute() {
diff --git a/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2RemoveVCCommand.java b/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2RemoveVCCommand.java
new file mode 100644
index 0000000..d4b8d25
--- /dev/null
+++ b/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/SdxL2RemoveVCCommand.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.sdxl2.cli;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.sdxl2.SdxL2Service;
+
+/**
+ * CLI to delete a named Virtual Circuit in an SDX-L2.
+ */
+@Command(scope = "sdxl2", name = "sdxl2vc-remove", description = "Removes a named Virtual Circuit")
+public class SdxL2RemoveVCCommand extends AbstractShellCommand {
+
+ @Argument(index = 0, name = "sdxl2vcname", description = "Name of SDX-L2 Virtual Circuit",
+ required = true, multiValued = false)
+ private String sdxL2VCname = null;
+
+ @Override
+ protected void execute() {
+ SdxL2Service sdxl2Service = get(SdxL2Service.class);
+ sdxl2Service.removeVC(sdxL2VCname);
+ }
+
+}
+
diff --git a/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/completer/SdxL2CPNameCompleter.java b/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/completer/SdxL2CPNameCompleter.java
index 706c1e3..31bebb4 100644
--- a/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/completer/SdxL2CPNameCompleter.java
+++ b/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/completer/SdxL2CPNameCompleter.java
@@ -25,7 +25,7 @@
import java.util.Optional;
/**
- * Completes SDX-L2 connection point names.
+ * Completes name for SDX-L2 Connection Point.
*/
public class SdxL2CPNameCompleter implements Completer {
diff --git a/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/completer/SdxL2NameCompleter.java b/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/completer/SdxL2NameCompleter.java
index 50b4366..df31856 100644
--- a/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/completer/SdxL2NameCompleter.java
+++ b/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/completer/SdxL2NameCompleter.java
@@ -24,7 +24,7 @@
import java.util.List;
/**
- * Completes SDX-L2 names.
+ * Completes name for SDX-L2.
*/
public class SdxL2NameCompleter implements Completer {
diff --git a/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/completer/SdxL2VCNameCompleter.java b/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/completer/SdxL2VCNameCompleter.java
new file mode 100644
index 0000000..e61c33f
--- /dev/null
+++ b/sdx-l2/src/main/java/org/onosproject/sdxl2/cli/completer/SdxL2VCNameCompleter.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.sdxl2.cli.completer;
+
+
+import org.apache.karaf.shell.console.Completer;
+import org.apache.karaf.shell.console.completer.StringsCompleter;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.sdxl2.SdxL2Service;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * Completes name for SDX-L2 Virtual Circuit.
+ */
+public class SdxL2VCNameCompleter implements Completer {
+
+ @Override
+ public int complete(String buffer, int cursor, List<String> candidates) {
+ StringsCompleter delegate = new StringsCompleter();
+ SdxL2Service service = AbstractShellCommand.get(SdxL2Service.class);
+ delegate.getStrings().addAll(service.getVirtualCircuits(Optional.ofNullable(null)));
+ return delegate.complete(buffer, cursor, candidates);
+ }
+}
diff --git a/sdx-l2/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/sdx-l2/src/main/resources/OSGI-INF/blueprint/shell-config.xml
index 5d576d5..76b3572 100644
--- a/sdx-l2/src/main/resources/OSGI-INF/blueprint/shell-config.xml
+++ b/sdx-l2/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -13,6 +13,7 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
+
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
@@ -42,15 +43,39 @@
</completers>
</command>
<command>
+ <action class="org.onosproject.sdxl2.cli.SdxL2GetCPCommand"/>
+ <completers>
+ <ref component-id="sdxl2cpnameCompleter"/>
+ </completers>
+ </command>
+ <command>
<action class="org.onosproject.sdxl2.cli.SdxL2ListCPCommand"/>
<completers>
<ref component-id="sdxl2Completer"/>
</completers>
</command>
<command>
- <action class="org.onosproject.sdxl2.cli.SdxL2GetCPCommand"/>
+ <action class="org.onosproject.sdxl2.cli.SdxL2AddVCCommand"/>
<completers>
- <ref component-id="sdxl2cpnameCompleter"/>
+ <ref component-id="sdxl2vcnameCompleter"/>
+ </completers>
+ </command>
+ <command>
+ <action class="org.onosproject.sdxl2.cli.SdxL2RemoveVCCommand"/>
+ <completers>
+ <ref component-id="sdxl2vcnameCompleter"/>
+ </completers>
+ </command>
+ <command>
+ <action class="org.onosproject.sdxl2.cli.SdxL2GetVCCommand"/>
+ <completers>
+ <ref component-id="sdxl2vcnameCompleter"/>
+ </completers>
+ </command>
+ <command>
+ <action class="org.onosproject.sdxl2.cli.SdxL2ListVCCommand"/>
+ <completers>
+ <ref component-id="sdxl2Completer"/>
</completers>
</command>
</command-bundle>
@@ -58,5 +83,6 @@
<bean id="sdxl2Completer" class="org.onosproject.sdxl2.cli.completer.SdxL2NameCompleter"/>
<bean id="connectPointCompleter" class="org.onosproject.cli.net.ConnectPointCompleter"/>
<bean id="sdxl2cpnameCompleter" class="org.onosproject.sdxl2.cli.completer.SdxL2CPNameCompleter"/>
+ <bean id="sdxl2vcnameCompleter" class="org.onosproject.sdxl2.cli.completer.SdxL2VCNameCompleter"/>
</blueprint>
diff --git a/sdx-l2/src/test/java/org/onosproject/sdxl2/IntentServiceTest.java b/sdx-l2/src/test/java/org/onosproject/sdxl2/IntentServiceTest.java
new file mode 100644
index 0000000..a9711d3
--- /dev/null
+++ b/sdx-l2/src/test/java/org/onosproject/sdxl2/IntentServiceTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.sdxl2;
+
+import com.google.common.collect.Sets;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentServiceAdapter;
+import org.onosproject.net.intent.Key;
+
+import java.util.Set;
+
+/**
+ * Represents a fake IntentService class that easily allows to store and
+ * retrieve intents without implementing the IntentService logic.
+ */
+public class IntentServiceTest extends IntentServiceAdapter {
+
+ private Set<Intent> intents;
+
+ /**
+ * Defines a set of intents.
+ */
+ public IntentServiceTest() {
+ intents = Sets.newHashSet();
+ }
+
+ @Override
+ public void submit(Intent intent) {
+ intents.add(intent);
+ }
+
+ @Override
+ public long getIntentCount() {
+ return intents.size();
+ }
+
+ @Override
+ public Iterable<Intent> getIntents() {
+ return Sets.newHashSet(intents.iterator());
+ }
+
+ @Override
+ public Intent getIntent(Key intentKey) {
+ for (Intent intent : intents) {
+ if (intent.key().equals(intentKey)) {
+ return intent;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void withdraw(Intent intent) {
+ intents.remove(intent);
+ }
+
+}
diff --git a/sdx-l2/src/test/java/org/onosproject/sdxl2/SdxL2MacVCManagerTest.java b/sdx-l2/src/test/java/org/onosproject/sdxl2/SdxL2MacVCManagerTest.java
new file mode 100644
index 0000000..32865c7
--- /dev/null
+++ b/sdx-l2/src/test/java/org/onosproject/sdxl2/SdxL2MacVCManagerTest.java
@@ -0,0 +1,430 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.sdxl2;
+
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.TestApplicationId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.ConnectPoint;
+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.intent.AbstractIntentTest;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentUtils;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.PointToPointIntent;
+
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Optional;
+
+import static java.lang.String.format;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+
+/**
+ * Unit tests for SDX-L2 Mac VC Manager.
+ */
+public class SdxL2MacVCManagerTest extends AbstractIntentTest {
+
+ private static final String SDXL2_2 = "sdxl2_test2";
+ private static final String CP1 = "of:00000000000001/1";
+ private static final String CP2 = "of:00000000000002/1";
+ private static final String CP5 = "of:00000000000002/4";
+ private static final String CP6 = "of:00000000000004/4";
+ private static final String CP7 = "of:0000000000000a/4";
+ private static final String CP8 = "of:00000000000009/4";
+ private static final String CP9 = "of:0000000000000a/4";
+ private static final String CP10 = "of:00000000000009/4";
+ private static final String VLANS1 = "2,3,4";
+ private static final ArrayList<String> VLANS1_ARRAY =
+ new ArrayList<String>(Arrays.asList(VLANS1.split(",")));
+ private static final String VLANS2 = "4,5,6";
+ private static final ArrayList<String> VLANS2_ARRAY =
+ new ArrayList<String>(Arrays.asList(VLANS2.split(",")));
+
+ private static final String VLANS5 = "100";
+ private static final String VLANS6 = "1";
+ private static final String VLANS7 = "1";
+ private static final String VLANS8 = "111";
+ private static final String VLANS9 = "1";
+ private static final String VLANS10 = "1";
+ private static final String CEMAC1 = "52:40:00:12:44:01";
+ private static final String CEMAC2 = "51:12:11:00:23:01";
+ private static final String CEMAC5 = "52:12:11:00:23:11";
+ private static final String CEMAC6 = "52:12:11:a0:23:11";
+ private static final String CEMAC7 = "52:12:21:00:25:11";
+ private static final String CEMAC8 = "52:12:14:a0:23:11";
+ private static final String CEMAC9 = "52:12:21:00:28:11";
+ private static final String CEMAC10 = "52:12:14:aa:23:11";
+ private static final String NAME_FORMAT = "%s:%s-%s";
+ private static final String KEY_FORMAT = "%s,%s";
+ private static final ApplicationId APPID = TestApplicationId.create("foo");
+ private static final int POINT_TO_POINT_INDEXES = 3;
+ private SdxL2MacVCManager manager;
+ private List<PointToPointIntent> intentList;
+
+ /**
+ * Prepare environment before starting testing MAC-based VCs.
+ */
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ SdxL2DistributedStore store = new SdxL2DistributedStore();
+ store.initForTest();
+ manager = new SdxL2MacVCManager(APPID, store, new IntentServiceTest());
+ intentList = setIntents();
+ }
+
+ /**
+ * Clean up environment after finishing testing MAC-based VCs.
+ */
+ @After
+ public void tearDown() {
+ super.tearDown();
+ }
+
+ public List<PointToPointIntent> setIntents() {
+ List<PointToPointIntent> intents = new ArrayList<PointToPointIntent>();
+ intents.addAll(setupConnectionPoints1To2());
+ intents.addAll(setupConnectionPoints5To6());
+ intents.addAll(setupConnectionPoints7To8());
+ intents.addAll(setupConnectionPoints9To10());
+ return intents;
+ }
+
+ private TrafficTreatment buildTreatment(VlanId setVlan,
+ VlanId pushVlan,
+ boolean popVlan) {
+
+ TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
+ if (setVlan != null) {
+ treatmentBuilder.setVlanId(setVlan);
+ }
+ if (pushVlan != null) {
+ treatmentBuilder.pushVlan();
+ treatmentBuilder.setVlanId(pushVlan);
+ }
+ if (popVlan) {
+ treatmentBuilder.popVlan();
+ }
+ return treatmentBuilder.build();
+ }
+
+ private TrafficSelector buildSelector(MacAddress ingressMac,
+ MacAddress egressMac,
+ Short etherType,
+ VlanId ingressTag) {
+
+ TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
+ selectorBuilder.matchEthSrc(ingressMac);
+ selectorBuilder.matchEthDst(egressMac);
+ if (etherType != null) {
+ selectorBuilder.matchEthType(etherType);
+ }
+ if (ingressTag != null) {
+ selectorBuilder.matchVlanId(ingressTag);
+ }
+ return selectorBuilder.build();
+ }
+
+ private Key generateIntentKey(String sdxl2, SdxL2ConnectionPoint cpOne, SdxL2ConnectionPoint cpTwo, String index) {
+ String cps = format(NAME_FORMAT, sdxl2, cpOne.name(), cpTwo.name());
+ String key = format(KEY_FORMAT, cps, index);
+ return Key.of(key, APPID);
+ }
+
+ @Test
+ public void testConnectionSetup() {
+ Iterator<SdxL2ConnectionPoint> lhs = setupLhsCPs().iterator();
+ Iterator<SdxL2ConnectionPoint> rhs = setupRhsCPs().iterator();
+ while (lhs.hasNext()) {
+ manager.addVC(SDXL2_2, lhs.next(), rhs.next());
+ }
+
+ assertEquals(intentList.size(), manager.intentService.getIntentCount());
+
+ for (Intent emulatedIntent : intentList) {
+ boolean found = false;
+ for (Intent realIntent : manager.intentService.getIntents()) {
+ if (emulatedIntent.key().equals(realIntent.key())) {
+ found = true;
+ assertTrue(format("Comparing %s and %s", emulatedIntent, realIntent),
+ IntentUtils.intentsAreEqual(emulatedIntent, realIntent));
+ break;
+ }
+ }
+ assertTrue(found);
+ }
+ }
+
+ public List<SdxL2ConnectionPoint> setupLhsCPs() {
+ List<SdxL2ConnectionPoint> cps = new ArrayList<SdxL2ConnectionPoint>();
+ SdxL2ConnectionPoint cpone = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST1", CP1, VLANS1, CEMAC1);
+ cps.add(cpone);
+ SdxL2ConnectionPoint cpfive = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST5", CP5, VLANS5, CEMAC5);
+ cps.add(cpfive);
+ SdxL2ConnectionPoint cpseven = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST7", CP7, VLANS7, CEMAC7);
+ cps.add(cpseven);
+ SdxL2ConnectionPoint cpnine = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST9", CP9, VLANS9, CEMAC9);
+ cps.add(cpnine);
+ return cps;
+ }
+
+ public List<SdxL2ConnectionPoint> setupRhsCPs() {
+ List<SdxL2ConnectionPoint> cps = new ArrayList<SdxL2ConnectionPoint>();
+ SdxL2ConnectionPoint cptwo = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST2", CP2, VLANS2, CEMAC2);
+ cps.add(cptwo);
+ SdxL2ConnectionPoint cpsix = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST6", CP6, VLANS6, CEMAC6);
+ cps.add(cpsix);
+ SdxL2ConnectionPoint cpeight = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST8", CP8, VLANS8, CEMAC8);
+ cps.add(cpeight);
+ SdxL2ConnectionPoint cpten = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST10", CP10, VLANS10, CEMAC10);
+ cps.add(cpten);
+ return cps;
+ }
+
+ private List<PointToPointIntent> setupConnectionPoints(String keyIndex,
+ SdxL2ConnectionPoint lhs, String lhsID,
+ String lhsMac, String lhsVlan,
+ TrafficTreatment lhsBuiltTreatment,
+ SdxL2ConnectionPoint rhs, String rhsID,
+ String rhsMac, String rhsVlan,
+ TrafficTreatment rhsBuiltTreatment) {
+ List<PointToPointIntent> intents = new ArrayList<PointToPointIntent>();
+ VlanId lhsVlanValue = null, rhsVlanValue = null;
+ if (lhsVlan != null) {
+ lhsVlanValue = VlanId.vlanId(Short.parseShort(lhsVlan));
+ }
+ if (rhsVlan != null) {
+ rhsVlanValue = VlanId.vlanId(Short.parseShort(rhsVlan));
+ }
+
+ intents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, lhs, rhs, keyIndex))
+ .selector(buildSelector(MacAddress.valueOf(lhsMac),
+ MacAddress.valueOf(rhsMac),
+ null, lhsVlanValue))
+ .treatment(lhsBuiltTreatment)
+ .ingressPoint(ConnectPoint.deviceConnectPoint(lhsID))
+ .egressPoint(ConnectPoint.deviceConnectPoint(rhsID))
+ .priority(2000)
+ .build());
+ intents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, rhs, lhs, keyIndex))
+ .selector(buildSelector(MacAddress.valueOf(rhsMac),
+ MacAddress.valueOf(lhsMac),
+ null, rhsVlanValue))
+ .treatment(rhsBuiltTreatment)
+ .ingressPoint(ConnectPoint.deviceConnectPoint(rhsID))
+ .egressPoint(ConnectPoint.deviceConnectPoint(lhsID))
+ .priority(2000)
+ .build());
+ return intents;
+ }
+
+ private List<PointToPointIntent> setupConnectionPoints1To2() {
+ List<PointToPointIntent> intents = new ArrayList<PointToPointIntent>();
+ String lhsID = CP1;
+ ArrayList<String> lhsVlan = VLANS1_ARRAY;
+ String lhsMac = CEMAC1;
+ String rhsID = CP2;
+ ArrayList<String> rhsVlan = VLANS2_ARRAY;
+ String rhsMac = CEMAC2;
+ SdxL2ConnectionPoint lhs = SdxL2ConnectionPoint.sdxl2ConnectionPoint(
+ "TEST1", lhsID, VLANS1, lhsMac);
+ SdxL2ConnectionPoint rhs = SdxL2ConnectionPoint.sdxl2ConnectionPoint(
+ "TEST2", rhsID, VLANS2, rhsMac);
+ TrafficTreatment lhsBuiltTreatment, rhsBuiltTreatment;
+
+ for (int i = 0; i < POINT_TO_POINT_INDEXES; i++) {
+ lhsBuiltTreatment = buildTreatment(VlanId.vlanId(rhsVlan.get(i)), null, false);
+ rhsBuiltTreatment = buildTreatment(VlanId.vlanId(lhsVlan.get(i)), null, false);
+ intents.addAll(setupConnectionPoints(Integer.toString(i + 1),
+ lhs, lhsID, lhsMac, lhsVlan.get(i), lhsBuiltTreatment,
+ rhs, rhsID, rhsMac, rhsVlan.get(i), rhsBuiltTreatment));
+ }
+ return intents;
+ }
+
+ private List<PointToPointIntent> setupConnectionPoints5To6() {
+ String lhsID = CP5;
+ String lhsVlan = VLANS5;
+ String lhsMac = CEMAC5;
+ SdxL2ConnectionPoint lhs = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST5", lhsID, lhsVlan, lhsMac);
+ String rhsID = CP6;
+ String rhsVlan = VLANS6;
+ String rhsMac = CEMAC6;
+ SdxL2ConnectionPoint rhs = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST6", rhsID, rhsVlan, rhsMac);
+ TrafficTreatment lhsBuiltTreatment = buildTreatment(null, null, true);
+ TrafficTreatment rhsBuiltTreatment = buildTreatment(null, VlanId.vlanId(Short.parseShort(lhsVlan)), false);
+ return setupConnectionPoints("1", lhs, lhsID, lhsMac, lhsVlan, lhsBuiltTreatment,
+ rhs, rhsID, rhsMac, null, rhsBuiltTreatment);
+ }
+
+ private List<PointToPointIntent> setupConnectionPoints7To8() {
+ String lhsID = CP7;
+ String lhsVlan = VLANS7;
+ String lhsMac = CEMAC7;
+ SdxL2ConnectionPoint lhs = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST7", lhsID, lhsVlan, lhsMac);
+ String rhsID = CP8;
+ String rhsVlan = VLANS8;
+ String rhsMac = CEMAC8;
+ SdxL2ConnectionPoint rhs = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST8", rhsID, rhsVlan, rhsMac);
+ TrafficTreatment lhsBuiltTreatment = buildTreatment(null, VlanId.vlanId(Short.parseShort(rhsVlan)), false);
+ TrafficTreatment rhsBuiltTreatment = buildTreatment(null, null, true);
+ return setupConnectionPoints("1", lhs, lhsID, lhsMac, null, lhsBuiltTreatment,
+ rhs, rhsID, rhsMac, rhsVlan, rhsBuiltTreatment);
+ }
+
+ private List<PointToPointIntent> setupConnectionPoints9To10() {
+ String lhsID = CP9;
+ String lhsVlan = VLANS9;
+ String lhsMac = CEMAC9;
+ SdxL2ConnectionPoint lhs = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST9", lhsID, lhsVlan, lhsMac);
+ String rhsID = CP10;
+ String rhsVlan = VLANS10;
+ String rhsMac = CEMAC10;
+ SdxL2ConnectionPoint rhs = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST10", rhsID, rhsVlan, rhsMac);
+ TrafficTreatment nullTreatment = buildTreatment(null, null, false);
+ return setupConnectionPoints("1", lhs, lhsID, lhsMac, null, nullTreatment,
+ rhs, rhsID, rhsMac, null, nullTreatment);
+ }
+
+ @Test
+ public void removeConnection() {
+ testConnectionSetup();
+ List<PointToPointIntent> removedIntents = new ArrayList<PointToPointIntent>();
+
+ SdxL2ConnectionPoint cpone = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST1", CP1, VLANS1, CEMAC1);
+ SdxL2ConnectionPoint cptwo = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST2", CP2, VLANS2, CEMAC2);
+ removedIntents.addAll(setupConnectionPoints1To2());
+
+ SdxL2ConnectionPoint cpfive = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST5", CP5, VLANS5, CEMAC5);
+ SdxL2ConnectionPoint cpsix = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST6", CP6, VLANS6, CEMAC6);
+ removedIntents.addAll(setupConnectionPoints5To6());
+
+ SdxL2ConnectionPoint cpseven = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST7", CP7, VLANS7, CEMAC7);
+ SdxL2ConnectionPoint cpeight = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST8", CP8, VLANS8, CEMAC8);
+ removedIntents.addAll(setupConnectionPoints7To8());
+
+ manager.removeVC(cpone, cptwo);
+ manager.removeVC(cpfive, cpsix);
+ manager.removeVC(cpseven, cpeight);
+
+ assertEquals(2, manager.intentService.getIntentCount());
+
+ for (Intent removedIntent : removedIntents) {
+ boolean found = false;
+ for (Intent existingIntent : manager.intentService.getIntents()) {
+ if (removedIntent.key().equals(existingIntent.key())) {
+ found = true;
+ assertTrue(format("Intent %s equal %s", removedIntent, existingIntent),
+ !IntentUtils.intentsAreEqual(removedIntent, existingIntent));
+ break;
+ }
+ }
+ assertTrue(!found);
+ }
+
+ }
+
+ @Test
+ public void testRemoveVCbyCP() {
+ testConnectionSetup();
+
+ List<PointToPointIntent> removedIntents = new ArrayList<PointToPointIntent>();
+
+ SdxL2ConnectionPoint cpone = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST1", CP1, VLANS1, CEMAC1);
+ removedIntents.addAll(setupConnectionPoints1To2());
+
+ SdxL2ConnectionPoint cpsix = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST6", CP6, VLANS6, CEMAC6);
+ removedIntents.addAll(setupConnectionPoints5To6());
+
+ SdxL2ConnectionPoint cpseven = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST7", CP7, VLANS7, CEMAC7);
+ removedIntents.addAll(setupConnectionPoints7To8());
+
+ SdxL2ConnectionPoint cpten = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST10", CP10, VLANS10, CEMAC10);
+ removedIntents.addAll(setupConnectionPoints9To10());
+
+ manager.removeVC(cpone);
+ manager.removeVC(cpsix);
+ manager.removeVC(cpseven);
+ manager.removeVC(cpten);
+
+ assertEquals(Collections.emptySet(), manager.getVCs(Optional.ofNullable(null)));
+
+ assertEquals(0, manager.intentService.getIntentCount());
+
+ for (Intent removedIntent : removedIntents) {
+ boolean found = false;
+ for (Intent existingIntent : manager.intentService.getIntents()) {
+ if (removedIntent.key().equals(existingIntent.key())) {
+ found = true;
+ assertTrue(format("Intent %s equal %s", removedIntent, existingIntent),
+ !IntentUtils.intentsAreEqual(removedIntent, existingIntent));
+ break;
+ }
+ }
+ assertTrue(!found);
+ }
+
+ }
+
+ @Test
+ public void testRemoveVCbySdx() {
+ testConnectionSetup();
+
+ List<PointToPointIntent> removedIntents = new ArrayList<PointToPointIntent>();
+
+ removedIntents.addAll(setupConnectionPoints1To2());
+ removedIntents.addAll(setupConnectionPoints5To6());
+ removedIntents.addAll(setupConnectionPoints7To8());
+ removedIntents.addAll(setupConnectionPoints9To10());
+ manager.removeVCs(SDXL2_2);
+
+ assertEquals(Collections.emptySet(), manager.getVCs(Optional.ofNullable(null)));
+ assertEquals(Collections.emptySet(), manager.getVCs(Optional.of(SDXL2_2)));
+
+ for (Intent removedIntent : removedIntents) {
+ boolean found = false;
+ for (Intent existingIntent : manager.intentService.getIntents()) {
+ if (removedIntent.key().equals(existingIntent.key())) {
+ found = true;
+ assertTrue(format("Intent %s equal %s", removedIntent, existingIntent),
+ !IntentUtils.intentsAreEqual(removedIntent, existingIntent));
+ break;
+ }
+ }
+ assertTrue(!found);
+ }
+
+ }
+}
diff --git a/sdx-l2/src/test/java/org/onosproject/sdxl2/SdxL2ManagerTest.java b/sdx-l2/src/test/java/org/onosproject/sdxl2/SdxL2ManagerTest.java
index 1b502b1..1017e72 100644
--- a/sdx-l2/src/test/java/org/onosproject/sdxl2/SdxL2ManagerTest.java
+++ b/sdx-l2/src/test/java/org/onosproject/sdxl2/SdxL2ManagerTest.java
@@ -19,23 +19,71 @@
import com.google.common.collect.Sets;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.ExpectedException;
import org.onosproject.TestApplicationId;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.MockIdGenerator;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
+import static java.lang.String.format;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
-
+import static org.junit.Assert.assertNull;
/**
* Tests SdxL2Manager functionality.
*/
public class SdxL2ManagerTest {
+ public static final String SDXL2 = "test";
+ public static final String SDXL2_2 = "test2";
+ public static final String CP1 = "of:00000000000001/1";
+ public static final String CP2 = "of:00000000000002/1";
+ public static final String CP3 = "of:00000000000003/1";
+ public static final String CP4 = "of:00000000000003/2";
+ public static final String CP5 = "of:00000000000004/2";
+ public static final String VLANS1 = "1,2,3,4";
+ public static final String VLANS2 = "-1";
+ public static final String VLANS3 = "1,2,3";
+ public static final String VLANS4 = "2,2,2";
+ public static final String VLANS7 = "5";
+ public static final String VLANS8 = "3,2,1";
+ public static final String CEMAC1 = "52:40:00:12:44:01";
+ public static final String CEMAC2 = "52:44:00:12:44:01";
+ public static final String CEMAC3 = "54:40:00:12:44:01";
+ public static final String CEMAC4 = "52:40:00:12:42:01";
+ public static final String CEMAC5 = "52:40:00:10:44:01";
+ public static final String CEMAC6 = "52:40:00:12:46:01";
+ public static final String CP6 = "of:00000000000004/3";
+ public static final String CP7 = "of:00000000000004/3";
+ public static final String CP8 = "of:00000000000005/2";
+ public static final String VLANS6 = "1,2,3,4";
+ public static final String VLANS5 = "8,9,10";
+ public static final String CEMAC7 = "52:40:00:12:46:01";
+ public static final String CEMAC8 = "52:40:90:12:46:01";
+ @Rule
+ public ExpectedException exceptionAddVC1 = ExpectedException.none();
+ @Rule
+ public ExpectedException exceptionAddVC2 = ExpectedException.none();
+ @Rule
+ public ExpectedException exceptionRemoveVC1 = ExpectedException.none();
+ @Rule
+ public ExpectedException exceptionRemoveVC2 = ExpectedException.none();
+ @Rule
+ public ExpectedException exceptionSdxL2Name = ExpectedException.none();
+ @Rule
+ public ExpectedException exceptionDelSdxL2Name = ExpectedException.none();
+ @Rule
+ public ExpectedException exceptionGetVC2 = ExpectedException.none();
protected SdxL2Manager manager;
+ protected IdGenerator idGenerator = new MockIdGenerator();
@Before
public void setUp() {
@@ -44,19 +92,19 @@
SdxL2DistributedStore store = new SdxL2DistributedStore();
store.initForTest();
manager.sdxL2Store = store;
+ SdxL2MacVCManager vcManager = new SdxL2MacVCManager(
+ manager.appId, manager.sdxL2Store, new IntentServiceTest());
+ manager.vcManager = vcManager;
+ Intent.bindIdGenerator(idGenerator);
}
@After
public void tearDown() {
+ Intent.unbindIdGenerator(idGenerator);
}
- public static final String SDXL2 = "test";
- public static final String SDXL2_2 = "test2";
-
-
@Test
public void testCreateSdxL2s() {
-
manager.createSdxL2(SDXL2);
manager.createSdxL2(SDXL2_2);
manager.createSdxL2(SDXL2);
@@ -85,23 +133,8 @@
assertNotEquals(sdxl2, old);
}
- public static final String CP1 = "of:00000000000001/1";
- public static final String CP2 = "of:00000000000002/1";
- public static final String CP3 = "of:00000000000003/1";
- public static final String CP4 = "of:00000000000003/2";
- public static final String CP5 = "of:00000000000004/2";
-
- public static final String VLANS1 = "1,2,3,4";
- public static final String VLANS2 = "-1";
- public static final String VLANS3 = "1,2,3";
- public static final String VLANS4 = "2,2,2";
- public static final String VLANS7 = "5";
- public static final String VLANS8 = "3,2,1";
-
- public static final String CEMAC1 = "52:40:00:12:44:01";
-
@Test
- public void testaddSdxL2ConnectionPoint() {
+ public void testAddSdxL2ConnectionPoint() {
manager.createSdxL2(SDXL2);
manager.createSdxL2(SDXL2_2);
@@ -125,12 +158,12 @@
SdxL2ConnectionPoint ten = SdxL2ConnectionPoint.sdxl2ConnectionPoint("FI2", CP5, VLANS2, CEMAC1);
manager.addSdxL2ConnectionPoint(SDXL2, ten);
- SdxL2ConnectionPoint fourteen = SdxL2ConnectionPoint.sdxl2ConnectionPoint("RO1",
- "of:0000000000000003/3", "1", "52:54:00:04:E5:9E");
+ SdxL2ConnectionPoint fourteen = SdxL2ConnectionPoint.
+ sdxl2ConnectionPoint("RO1", "of:0000000000000003/3", "1", "52:54:00:04:E5:9E");
manager.addSdxL2ConnectionPoint("test1", fourteen);
- SdxL2ConnectionPoint fifteen = SdxL2ConnectionPoint.sdxl2ConnectionPoint("RO2",
- "of:0000000000000009/3", "1", "52:54:00:68:F7:D9");
+ SdxL2ConnectionPoint fifteen = SdxL2ConnectionPoint.
+ sdxl2ConnectionPoint("RO2", "of:0000000000000009/3", "1", "52:54:00:68:F7:D9");
manager.addSdxL2ConnectionPoint("test1", fifteen);
SdxL2ConnectionPoint two = SdxL2ConnectionPoint.sdxl2ConnectionPoint("ROM1", CP2, VLANS1, CEMAC1);
@@ -157,14 +190,14 @@
}
@Test
- public void testgetSdxL2ConnectionPoints() {
+ public void testGetSdxL2ConnectionPoints() {
manager.createSdxL2(SDXL2);
manager.createSdxL2(SDXL2_2);
Set<String> allExt = Sets.newHashSet();
Set<String> allExtBySdxl2 = Sets.newHashSet();
- Set<String> allExtBySdxl22 = Sets.newHashSet();
+ Set<String> allExtBySdxl2Aux = Sets.newHashSet();
SdxL2ConnectionPoint one = SdxL2ConnectionPoint.sdxl2ConnectionPoint("ROM1", CP1, VLANS1, CEMAC1);
manager.addSdxL2ConnectionPoint(SDXL2, one);
@@ -177,7 +210,7 @@
SdxL2ConnectionPoint six = SdxL2ConnectionPoint.sdxl2ConnectionPoint("ROM3", CP1, VLANS7, CEMAC1);
manager.addSdxL2ConnectionPoint(SDXL2_2, six);
allExt.add(six.name());
- allExtBySdxl22.add(six.name());
+ allExtBySdxl2Aux.add(six.name());
SdxL2ConnectionPoint seven = SdxL2ConnectionPoint.sdxl2ConnectionPoint("MI3", CP3, VLANS3, CEMAC1);
manager.addSdxL2ConnectionPoint(SDXL2, seven);
allExt.add(seven.name());
@@ -185,7 +218,7 @@
SdxL2ConnectionPoint nine = SdxL2ConnectionPoint.sdxl2ConnectionPoint("FI1", CP4, VLANS8, CEMAC1);
manager.addSdxL2ConnectionPoint(SDXL2_2, nine);
allExt.add(nine.name());
- allExtBySdxl22.add(nine.name());
+ allExtBySdxl2Aux.add(nine.name());
SdxL2ConnectionPoint ten = SdxL2ConnectionPoint.sdxl2ConnectionPoint("FI2", CP5, VLANS2, CEMAC1);
manager.addSdxL2ConnectionPoint(SDXL2, ten);
allExt.add(ten.name());
@@ -197,20 +230,20 @@
assertEquals(allExt, all);
assertNotEquals(allExtBySdxl2, all);
- assertNotEquals(allExtBySdxl22, all);
+ assertNotEquals(allExtBySdxl2Aux, all);
assertNotEquals(allExt, allBySdxl2);
assertEquals(allExtBySdxl2, allBySdxl2);
- assertNotEquals(allExtBySdxl22, allBySdxl2);
+ assertNotEquals(allExtBySdxl2Aux, allBySdxl2);
assertNotEquals(allExt, allBySdxl22);
assertNotEquals(allExtBySdxl2, allBySdxl22);
- assertEquals(allExtBySdxl22, allBySdxl22);
+ assertEquals(allExtBySdxl2Aux, allBySdxl22);
}
@Test
- public void testremoveSdxL2ConnectionPoint() {
+ public void testRemoveSdxL2ConnectionPoint() {
manager.createSdxL2(SDXL2);
manager.createSdxL2(SDXL2_2);
@@ -241,7 +274,50 @@
}
@Test
- public void testgetSdxL2ConnectionPoint() {
+ public void test2RemoveSdxL2s() {
+ manager.createSdxL2(SDXL2);
+ manager.createSdxL2(SDXL2_2);
+
+ Set<String> sdxL2CPs = Sets.newHashSet();
+ Set<String> sdxl2CPsAux = Sets.newHashSet();
+
+ SdxL2ConnectionPoint one = SdxL2ConnectionPoint.sdxl2ConnectionPoint("ROM1", CP1, VLANS1, CEMAC1);
+ sdxL2CPs.add(one.name());
+ manager.addSdxL2ConnectionPoint(SDXL2, one);
+
+ SdxL2ConnectionPoint three = SdxL2ConnectionPoint.sdxl2ConnectionPoint("ROM2", CP2, VLANS2, CEMAC1);
+ sdxL2CPs.add(three.name());
+ manager.addSdxL2ConnectionPoint(SDXL2, three);
+
+ SdxL2ConnectionPoint six = SdxL2ConnectionPoint.sdxl2ConnectionPoint("ROM3", CP1, VLANS7, CEMAC1);
+ sdxl2CPsAux.add(six.name());
+ manager.addSdxL2ConnectionPoint(SDXL2_2, six);
+
+ SdxL2ConnectionPoint seven = SdxL2ConnectionPoint.sdxl2ConnectionPoint("MI3", CP3, VLANS3, CEMAC1);
+ sdxL2CPs.add(seven.name());
+ manager.addSdxL2ConnectionPoint(SDXL2, seven);
+
+ SdxL2ConnectionPoint nine = SdxL2ConnectionPoint.sdxl2ConnectionPoint("FI1", CP4, VLANS8, CEMAC1);
+ sdxl2CPsAux.add(nine.name());
+ manager.addSdxL2ConnectionPoint(SDXL2_2, nine);
+
+ SdxL2ConnectionPoint ten = SdxL2ConnectionPoint.sdxl2ConnectionPoint("FI2", CP5, VLANS2, CEMAC1);
+ sdxL2CPs.add(ten.name());
+ manager.addSdxL2ConnectionPoint(SDXL2, ten);
+
+ manager.deleteSdxL2(SDXL2);
+
+ assertEquals(sdxl2CPsAux, this.manager.getSdxL2ConnectionPoints(Optional.of(SDXL2_2)));
+ assertEquals(sdxl2CPsAux, this.manager.getSdxL2ConnectionPoints(Optional.ofNullable(null)));
+ manager.deleteSdxL2(SDXL2_2);
+
+ assertEquals(Collections.emptySet(), this.manager.getSdxL2ConnectionPoints(Optional.of(SDXL2)));
+ assertEquals(Collections.emptySet(), this.manager.getSdxL2ConnectionPoints(Optional.of(SDXL2_2)));
+
+ }
+
+ @Test
+ public void testGetSdxL2ConnectionPoint() {
manager.createSdxL2(SDXL2);
manager.createSdxL2(SDXL2_2);
@@ -284,4 +360,240 @@
}
+ @Test
+ public void testAddVCChecks() {
+
+ manager.createSdxL2(SDXL2);
+ manager.createSdxL2(SDXL2_2);
+
+ SdxL2ConnectionPoint one = SdxL2ConnectionPoint.sdxl2ConnectionPoint("ROM1", CP1, VLANS1, CEMAC1);
+ SdxL2ConnectionPoint two = SdxL2ConnectionPoint.sdxl2ConnectionPoint("ROM2", CP2, VLANS2, CEMAC2);
+ SdxL2ConnectionPoint three = SdxL2ConnectionPoint.sdxl2ConnectionPoint("ROM3", CP1, VLANS7, CEMAC3);
+ SdxL2ConnectionPoint four = SdxL2ConnectionPoint.sdxl2ConnectionPoint("MI3", CP3, VLANS3, CEMAC4);
+ SdxL2ConnectionPoint five = SdxL2ConnectionPoint.sdxl2ConnectionPoint("FI1", CP4, VLANS8, CEMAC5);
+ SdxL2ConnectionPoint six = SdxL2ConnectionPoint.sdxl2ConnectionPoint("FI2", CP5, VLANS2, CEMAC6);
+ SdxL2ConnectionPoint seven = SdxL2ConnectionPoint.sdxl2ConnectionPoint("FI23", CP6, VLANS6, CEMAC7);
+ SdxL2ConnectionPoint eight = SdxL2ConnectionPoint.sdxl2ConnectionPoint("FI24", CP7, VLANS5, CEMAC8);
+ SdxL2ConnectionPoint nine = SdxL2ConnectionPoint.sdxl2ConnectionPoint("FI25", CP8, VLANS5, CEMAC8);
+
+ manager.addSdxL2ConnectionPoint(SDXL2, one);
+ manager.addSdxL2ConnectionPoint(SDXL2, two);
+ manager.addSdxL2ConnectionPoint(SDXL2_2, three);
+ manager.addSdxL2ConnectionPoint(SDXL2, four);
+ manager.addSdxL2ConnectionPoint(SDXL2_2, five);
+ manager.addSdxL2ConnectionPoint(SDXL2, six);
+ manager.addSdxL2ConnectionPoint(SDXL2, seven);
+ manager.addSdxL2ConnectionPoint(SDXL2, eight);
+ manager.addSdxL2ConnectionPoint(SDXL2, nine);
+
+ manager.addVC(SDXL2, two.name(), six.name());
+ manager.addVC(SDXL2, seven.name(), nine.name());
+ manager.addVC(SDXL2, one.name(), two.name());
+ manager.addVC(SDXL2, one.name(), four.name());
+ manager.addVC(SDXL2, one.name(), six.name());
+ manager.addVC(SDXL2, two.name(), four.name());
+ manager.addVC(SDXL2, seven.name(), eight.name());
+
+ exceptionAddVC2.expect(IllegalStateException.class);
+ manager.addVC(SDXL2, four.name() + "x", five.name());
+ manager.addVC(SDXL2, one.name(), three.name());
+ manager.addVC(SDXL2, one.name(), five.name());
+ manager.addVC(SDXL2, two.name(), three.name());
+ manager.addVC(SDXL2, two.name(), five.name());
+ manager.addVC(SDXL2, three.name(), four.name());
+ manager.addVC(SDXL2, three.name(), five.name());
+ manager.addVC(SDXL2, three.name(), six.name());
+ manager.addVC(SDXL2, four.name(), five.name());
+ }
+
+ @Test
+ public void testRemoveVCChecks() {
+
+ manager.createSdxL2(SDXL2);
+ manager.createSdxL2(SDXL2_2);
+
+ SdxL2ConnectionPoint one = SdxL2ConnectionPoint.sdxl2ConnectionPoint("ROM1", CP1, VLANS1, CEMAC1);
+ SdxL2ConnectionPoint two = SdxL2ConnectionPoint.sdxl2ConnectionPoint("ROM2", CP2, VLANS2, CEMAC2);
+ SdxL2ConnectionPoint three = SdxL2ConnectionPoint.sdxl2ConnectionPoint("ROM3", CP1, VLANS7, CEMAC3);
+ SdxL2ConnectionPoint four = SdxL2ConnectionPoint.sdxl2ConnectionPoint("MI3", CP3, VLANS3, CEMAC4);
+ SdxL2ConnectionPoint five = SdxL2ConnectionPoint.sdxl2ConnectionPoint("FI1", CP4, VLANS8, CEMAC5);
+ SdxL2ConnectionPoint six = SdxL2ConnectionPoint.sdxl2ConnectionPoint("FI2", CP5, VLANS2, CEMAC6);
+ SdxL2ConnectionPoint seven = SdxL2ConnectionPoint.sdxl2ConnectionPoint("FI23", CP6, VLANS6, CEMAC7);
+ SdxL2ConnectionPoint eight = SdxL2ConnectionPoint.sdxl2ConnectionPoint("FI24", CP7, VLANS5, CEMAC8);
+ SdxL2ConnectionPoint nine = SdxL2ConnectionPoint.sdxl2ConnectionPoint("FI25", CP8, VLANS5, CEMAC8);
+
+ manager.addSdxL2ConnectionPoint(SDXL2, one);
+ manager.addSdxL2ConnectionPoint(SDXL2, two);
+ manager.addSdxL2ConnectionPoint(SDXL2_2, three);
+ manager.addSdxL2ConnectionPoint(SDXL2, four);
+ manager.addSdxL2ConnectionPoint(SDXL2_2, five);
+ manager.addSdxL2ConnectionPoint(SDXL2, six);
+ manager.addSdxL2ConnectionPoint(SDXL2, seven);
+ manager.addSdxL2ConnectionPoint(SDXL2, eight);
+ manager.addSdxL2ConnectionPoint(SDXL2, nine);
+
+ manager.addVC(SDXL2, two.name(), six.name());
+ manager.addVC(SDXL2, seven.name(), nine.name());
+
+ String vc;
+ vc = two.name().compareTo(six.name().toString()) < 0 ?
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, two.name(), six.name()) :
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, six.name(), two.name());
+ manager.removeVC(vc);
+
+ vc = seven.name().compareTo(nine.name().toString()) < 0 ?
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, seven.name(), nine.name()) :
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, seven.name(), nine.name());
+ manager.removeVC(vc);
+
+ vc = one.name().compareTo(four.name().toString()) < 0 ?
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, one.name(), four.name()) :
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, four.name(), one.name());
+ manager.removeVC(vc);
+ vc = one.name().compareTo(five.name().toString()) < 0 ?
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, one.name(), five.name()) :
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, five.name(), one.name());
+ manager.removeVC(vc);
+ vc = one.name().compareTo(six.name().toString()) < 0 ?
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, one.name(), six.name()) :
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, six.name(), one.name());
+ manager.removeVC(vc);
+ vc = two.name().compareTo(three.name().toString()) < 0 ?
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, two.name(), three.name()) :
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, three.name(), two.name());
+ manager.removeVC(vc);
+ vc = two.name().compareTo(four.name().toString()) < 0 ?
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, two.name(), four.name()) :
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, four.name(), two.name());
+ manager.removeVC(vc);
+ vc = two.name().compareTo(five.name().toString()) < 0 ?
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, two.name(), five.name()) :
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, five.name(), two.name());
+ manager.removeVC(vc);
+ vc = three.name().compareTo(four.name().toString()) < 0 ?
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, three.name(), four.name()) :
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, four.name(), three.name());
+ manager.removeVC(vc);
+ vc = three.name().compareTo(five.name().toString()) < 0 ?
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, three.name(), five.name()) :
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, five.name(), three.name());
+ manager.removeVC(vc);
+ vc = three.name().compareTo(six.name().toString()) < 0 ?
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, three.name(), six.name()) :
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, six.name(), three.name());
+ manager.removeVC(vc);
+ vc = four.name().compareTo(five.name().toString()) < 0 ?
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, four.name(), five.name()) :
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, five.name(), four.name());
+ manager.removeVC(vc);
+ vc = seven.name().compareTo(eight.name().toString()) < 0 ?
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, seven.name(), eight.name()) :
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, eight.name(), seven.name());
+ manager.removeVC(vc);
+ vc = seven.name().compareTo(nine.name().toString()) < 0 ?
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2_2, seven.name(), nine.name()) :
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, seven.name(), nine.name());
+ manager.removeVC(vc);
+ vc = seven.name().compareTo(nine.name().toString()) < 0 ?
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2 + "x", seven.name(), nine.name()) :
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, seven.name(), nine.name());
+ manager.removeVC(vc);
+
+ exceptionRemoveVC1.expect(IllegalStateException.class);
+ vc = one.name().compareTo(three.name().toString()) < 0 ?
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, one.name(), three.name()) :
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, three.name(), one.name());
+ manager.removeVC(vc);
+ manager.removeVC(":A");
+ manager.removeVC("A:B");
+
+ vc = four.name().compareTo(five.name().toString()) < 0 ?
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, four.name() + "x", five.name()) :
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, five.name(), four.name() + "x");
+ manager.removeVC(vc);
+
+ vc = one.name().compareTo(two.name().toString()) < 0 ?
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, one.name(), two.name()) :
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, two.name(), one.name());
+ manager.removeVC(vc);
+ }
+
+ @Test
+ public void testSdxL2NameChecks() {
+ String sdxL2 = "";
+ String sdxL2Aux = "test3,4";
+
+ exceptionSdxL2Name.expect(NullPointerException.class);
+ exceptionSdxL2Name.expectMessage("name cannot be null");
+ manager.createSdxL2(null);
+
+ manager.createSdxL2(sdxL2);
+
+ exceptionSdxL2Name.expect(IllegalStateException.class);
+ exceptionSdxL2Name.expectMessage("names cannot contain commas");
+ manager.createSdxL2(sdxL2Aux);
+ }
+
+ @Test
+ public void testDeleteSdxL2NameChecks() {
+ String sdxL2 = "";
+ exceptionDelSdxL2Name.expect(NullPointerException.class);
+ exceptionDelSdxL2Name.expectMessage("name cannot be null");
+ manager.deleteSdxL2(null);
+ manager.createSdxL2(sdxL2);
+ manager.deleteSdxL2(sdxL2);
+ }
+
+ @Test
+ public void testGetVC() {
+ manager.createSdxL2(SDXL2);
+ manager.createSdxL2(SDXL2_2);
+
+ SdxL2ConnectionPoint one = SdxL2ConnectionPoint.sdxl2ConnectionPoint("ROM1", CP1, VLANS1, CEMAC1);
+ SdxL2ConnectionPoint two = SdxL2ConnectionPoint.sdxl2ConnectionPoint("ROM2", CP2, VLANS2, CEMAC2);
+ SdxL2ConnectionPoint three = SdxL2ConnectionPoint.sdxl2ConnectionPoint("ROM3", CP1, VLANS7, CEMAC3);
+ SdxL2ConnectionPoint four = SdxL2ConnectionPoint.sdxl2ConnectionPoint("MI3", CP3, VLANS3, CEMAC4);
+ SdxL2ConnectionPoint five = SdxL2ConnectionPoint.sdxl2ConnectionPoint("FI1", CP4, VLANS8, CEMAC5);
+ SdxL2ConnectionPoint six = SdxL2ConnectionPoint.sdxl2ConnectionPoint("FI2", CP5, VLANS2, CEMAC6);
+ SdxL2ConnectionPoint seven = SdxL2ConnectionPoint.sdxl2ConnectionPoint("FI23", CP6, VLANS6, CEMAC7);
+ SdxL2ConnectionPoint eight = SdxL2ConnectionPoint.sdxl2ConnectionPoint("FI24", CP7, VLANS5, CEMAC8);
+ SdxL2ConnectionPoint nine = SdxL2ConnectionPoint.sdxl2ConnectionPoint("FI25", CP8, VLANS5, CEMAC8);
+
+ String vc;
+ VirtualCircuit expectedVC;
+ VirtualCircuit actualVC;
+
+ manager.addSdxL2ConnectionPoint(SDXL2, one);
+ manager.addSdxL2ConnectionPoint(SDXL2, two);
+ manager.addSdxL2ConnectionPoint(SDXL2_2, three);
+ manager.addSdxL2ConnectionPoint(SDXL2, four);
+ manager.addSdxL2ConnectionPoint(SDXL2_2, five);
+ manager.addSdxL2ConnectionPoint(SDXL2, six);
+ manager.addSdxL2ConnectionPoint(SDXL2, seven);
+ manager.addSdxL2ConnectionPoint(SDXL2, eight);
+ manager.addSdxL2ConnectionPoint(SDXL2, nine);
+
+ // VC created using the manager, check against manually generates
+ manager.addVC(SDXL2, two.name(), six.name());
+ vc = two.name().compareTo(six.name().toString()) < 0 ?
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, two.name(), six.name()) :
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, six.name(), two.name());
+ expectedVC = new VirtualCircuit(two, six);
+ actualVC = manager.getVirtualCircuit(vc);
+ assertEquals(expectedVC, actualVC);
+
+ // VC not created, check that getVC returns null if VC does not exist
+ vc = one.name().compareTo(two.name().toString()) < 0 ?
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, one.name(), two.name()) :
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2, two.name(), one.name());
+ expectedVC = new VirtualCircuit(one, two);
+ actualVC = manager.getVirtualCircuit(vc);
+ assertNotEquals(expectedVC, actualVC);
+ assertNull(actualVC);
+
+ // Testing illegal character
+ exceptionGetVC2.expect(IllegalStateException.class);
+ manager.getVirtualCircuit(":A");
+ manager.getVirtualCircuit("A:B");
+ }
}
diff --git a/sdx-l2/src/test/java/org/onosproject/sdxl2/SdxL2MplsVCManagerTest.java b/sdx-l2/src/test/java/org/onosproject/sdxl2/SdxL2MplsVCManagerTest.java
new file mode 100644
index 0000000..914678b
--- /dev/null
+++ b/sdx-l2/src/test/java/org/onosproject/sdxl2/SdxL2MplsVCManagerTest.java
@@ -0,0 +1,756 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.sdxl2;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.VlanId;
+import org.onosproject.TestApplicationId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.EncapsulationType;
+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.intent.AbstractIntentTest;
+import org.onosproject.net.intent.Constraint;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentUtils;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.PointToPointIntent;
+import org.onosproject.net.intent.constraint.EncapsulationConstraint;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Iterator;
+import java.util.Optional;
+
+import static java.lang.String.format;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Unit tests for SDX-L2 MPLS VC Manager.
+ */
+public class SdxL2MplsVCManagerTest extends AbstractIntentTest {
+
+ private static final String SDXL2_2 = "sdxl2_test2";
+ private static final String CP1 = "of:00000000000001/1";
+ private static final String CP2 = "of:00000000000002/1";
+ private static final String CP5 = "of:00000000000002/4";
+ private static final String CP6 = "of:00000000000004/4";
+ private static final String CP7 = "of:0000000000000a/4";
+ private static final String CP8 = "of:00000000000009/4";
+ private static final String CP9 = "of:0000000000000a/4";
+ private static final String CP10 = "of:00000000000009/4";
+ private static final String VLANS1 = "2,3,4";
+ private static final String VLANS2 = "4,5,6";
+ private static final String VLANS5 = "100";
+ private static final String VLANS6 = "1";
+ private static final String VLANS7 = "1";
+ private static final String VLANS8 = "111";
+ private static final String VLANS9 = "1";
+ private static final String VLANS10 = "1";
+ private static final String NAME_FORMAT = "%s:%s-%s";
+ private static final String KEY_FORMAT = "%s,%s";
+ private static final ApplicationId APPID = TestApplicationId.create("foo");
+ private SdxL2MplsVCManager manager;
+ private List<PointToPointIntent> intentList;
+
+ /**
+ * Prepare environment before starting testing MPLS-based VCs.
+ */
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ SdxL2DistributedStore store = new SdxL2DistributedStore();
+ store.initForTest();
+ manager = new SdxL2MplsVCManager(APPID, store, new IntentServiceTest());
+ intentList = setIntents();
+ }
+
+ /**
+ * Clean up environment after finishing testing MPLS-based VCs.
+ */
+ @After
+ public void tearDown() {
+ super.tearDown();
+ }
+
+ private List<PointToPointIntent> setIntents() {
+ List<PointToPointIntent> intents = new ArrayList<PointToPointIntent>();
+ List<Constraint> encapsulation = buildConstraints();
+ SdxL2ConnectionPoint cpOne = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST1", CP1, VLANS1);
+ SdxL2ConnectionPoint cpTwo = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST2", CP2, VLANS2);
+
+ intents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpOne, cpTwo, "1"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("2"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("4")), null, false))
+ .constraints(encapsulation)
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .priority(2000)
+ .build());
+ intents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpTwo, cpOne, "1"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("4"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("2")), null, false))
+ .constraints(encapsulation)
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .priority(2000)
+ .build());
+ intents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpOne, cpTwo, "2"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("3"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("5")), null, false))
+ .constraints(encapsulation)
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .priority(2000)
+ .build());
+ intents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpTwo, cpOne, "2"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("5"))))
+ .constraints(encapsulation)
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("3")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .priority(2000)
+ .build());
+ intents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpOne, cpTwo, "3"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("4"))))
+ .constraints(encapsulation)
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("6")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .priority(2000)
+ .build());
+ intents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpTwo, cpOne, "3"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("6"))))
+ .constraints(encapsulation)
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("4")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .priority(2000)
+ .build());
+
+ SdxL2ConnectionPoint cpFive = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST5", CP5, VLANS5);
+ SdxL2ConnectionPoint cpSix = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST6", CP6, VLANS6);
+ intents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpFive, cpSix, "1"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("100"))))
+ .treatment(buildTreatment(null, null, true))
+ .constraints(encapsulation)
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP5))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP6))
+ .priority(2000)
+ .build());
+ intents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpSix, cpFive, "1"))
+ .selector(buildSelector(null, null))
+ .constraints(encapsulation)
+ .treatment(buildTreatment(null, VlanId.vlanId(Short.parseShort("100")), false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP6))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP5))
+ .priority(2000)
+ .build());
+
+ SdxL2ConnectionPoint cpSeven = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST7", CP7, VLANS7);
+ SdxL2ConnectionPoint cpEight = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST8", CP8, VLANS8);
+ intents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpSeven, cpEight, "1"))
+ .selector(buildSelector(null, null))
+ .treatment(buildTreatment(null, VlanId.vlanId(Short.parseShort("111")), false))
+ .constraints(encapsulation)
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP7))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP8))
+ .priority(2000)
+ .build());
+ intents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpEight, cpSeven, "1"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("111"))))
+ .constraints(encapsulation)
+ .treatment(buildTreatment(null, null, true))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP8))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP7))
+ .priority(2000)
+ .build());
+
+ SdxL2ConnectionPoint cpNine = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST9", CP9, VLANS9);
+ SdxL2ConnectionPoint cpTen = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST10", CP10, VLANS10);
+ intents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpNine, cpTen, "1"))
+ .selector(buildSelector(null, null))
+ .constraints(encapsulation)
+ .treatment(buildTreatment(null, null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP9))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP10))
+ .priority(2000)
+ .build());
+ intents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpTen, cpNine, "1"))
+ .selector(buildSelector(null, null))
+ .constraints(encapsulation)
+ .treatment(buildTreatment(null, null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP10))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP9))
+ .priority(2000)
+ .build());
+
+ return intents;
+ }
+
+ private TrafficTreatment buildTreatment(VlanId setVlan,
+ VlanId pushVlan,
+ boolean popVlan) {
+
+ TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
+ if (setVlan != null) {
+ treatmentBuilder.setVlanId(setVlan);
+ }
+ if (pushVlan != null) {
+ treatmentBuilder.pushVlan();
+ treatmentBuilder.setVlanId(pushVlan);
+ }
+ if (popVlan) {
+ treatmentBuilder.popVlan();
+ }
+ return treatmentBuilder.build();
+ }
+
+ private TrafficSelector buildSelector(Short ethertype,
+ VlanId ingresstag) {
+
+ TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
+ if (ethertype != null) {
+ selectorBuilder.matchEthType(ethertype);
+ }
+ if (ingresstag != null) {
+ selectorBuilder.matchVlanId(ingresstag);
+ }
+ return selectorBuilder.build();
+ }
+
+ private List<Constraint> buildConstraints() {
+ final List<Constraint> constraints = new LinkedList<>();
+ constraints.add(new EncapsulationConstraint(EncapsulationType.MPLS));
+ return constraints;
+ }
+
+ private Key generateIntentKey(String sdxl2, SdxL2ConnectionPoint cpOne,
+ SdxL2ConnectionPoint cpTwo, String index) {
+ String cps = format(NAME_FORMAT, sdxl2, cpOne.name(), cpTwo.name());
+ String key = format(KEY_FORMAT, cps, index);
+ return Key.of(key, APPID);
+ }
+
+ @Test
+ public void testConnectionSetup() {
+ Iterator<SdxL2ConnectionPoint> lhs = setupLhsCPs().iterator();
+ Iterator<SdxL2ConnectionPoint> rhs = setupRhsCPs().iterator();
+ while (lhs.hasNext()) {
+ manager.addVC(SDXL2_2, lhs.next(), rhs.next());
+ }
+
+ assertEquals(intentList.size(), manager.intentService.getIntentCount());
+
+ for (Intent emulatedIntent : intentList) {
+ boolean found = false;
+ for (Intent realIntent : manager.intentService.getIntents()) {
+ if (emulatedIntent.key().equals(realIntent.key())) {
+ found = true;
+ assertTrue(format("Comparing %s and %s", emulatedIntent, realIntent),
+ IntentUtils.intentsAreEqual(emulatedIntent, realIntent));
+ break;
+ }
+ }
+ assertTrue(found);
+ }
+
+ }
+
+ private List<SdxL2ConnectionPoint> setupLhsCPs() {
+
+ List<SdxL2ConnectionPoint> cps = new ArrayList<>();
+ SdxL2ConnectionPoint cpOne = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST1", CP1, VLANS1);
+ cps.add(cpOne);
+ SdxL2ConnectionPoint cpFive = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST5", CP5, VLANS5);
+ cps.add(cpFive);
+ SdxL2ConnectionPoint cpSeven = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST7", CP7, VLANS7);
+ cps.add(cpSeven);
+ SdxL2ConnectionPoint cpNine = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST9", CP9, VLANS9);
+ cps.add(cpNine);
+
+ return cps;
+ }
+
+ private List<SdxL2ConnectionPoint> setupRhsCPs() {
+
+ List<SdxL2ConnectionPoint> cps = new ArrayList<SdxL2ConnectionPoint>();
+ SdxL2ConnectionPoint cpTwo = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST2", CP2, VLANS2);
+ cps.add(cpTwo);
+ SdxL2ConnectionPoint cpSix = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST6", CP6, VLANS6);
+ cps.add(cpSix);
+ SdxL2ConnectionPoint cpEight = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST8", CP8, VLANS8);
+ cps.add(cpEight);
+ SdxL2ConnectionPoint cpTen = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST10", CP10, VLANS10);
+ cps.add(cpTen);
+
+ return cps;
+ }
+
+
+ @Test
+ public void removeConnection() {
+ testConnectionSetup();
+
+ List<PointToPointIntent> removedIntents = new ArrayList<>();
+ SdxL2ConnectionPoint cpOne = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST1", CP1, VLANS1);
+ SdxL2ConnectionPoint cpTwo = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST2", CP2, VLANS2);
+
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpOne, cpTwo, "1"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("2"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("4")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpTwo, cpOne, "1"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("4"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("2")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpOne, cpTwo, "2"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("3"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("5")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpTwo, cpOne, "2"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("5"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("3")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpOne, cpTwo, "3"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("4"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("6")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpTwo, cpOne, "3"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("6"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("4")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .priority(2000)
+ .build());
+
+ SdxL2ConnectionPoint cpFive = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST5", CP5, VLANS5);
+ SdxL2ConnectionPoint cpSix = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST6", CP6, VLANS6);
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpFive, cpSix, "1"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("100"))))
+ .treatment(buildTreatment(null, null, true))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP5))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP6))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpSix, cpFive, "1"))
+ .selector(buildSelector(null, null))
+ .treatment(buildTreatment(null, VlanId.vlanId(Short.parseShort("100")), false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP6))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP5))
+ .priority(2000)
+ .build());
+
+ SdxL2ConnectionPoint cpSeven = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST7", CP7, VLANS7);
+ SdxL2ConnectionPoint cpEight = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST8", CP8, VLANS8);
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpSeven, cpEight, "1"))
+ .selector(buildSelector(null, null))
+ .treatment(buildTreatment(null, VlanId.vlanId(Short.parseShort("111")), false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP7))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP8))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpEight, cpSeven, "1"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("111"))))
+ .treatment(buildTreatment(null, null, true))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP8))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP7))
+ .priority(2000)
+ .build());
+ manager.removeVC(cpOne, cpTwo);
+ manager.removeVC(cpFive, cpSix);
+ manager.removeVC(cpSeven, cpEight);
+
+ assertEquals(2, manager.intentService.getIntentCount());
+
+ for (Intent removedIntent : removedIntents) {
+ boolean found = false;
+ for (Intent existingIntent : manager.intentService.getIntents()) {
+ if (removedIntent.key().equals(existingIntent.key())) {
+ found = true;
+ assertTrue(format("Intent %s equal %s", removedIntent, existingIntent),
+ !IntentUtils.intentsAreEqual(removedIntent, existingIntent));
+ break;
+ }
+ }
+ assertTrue(!found);
+ }
+ }
+
+
+ @Test
+ public void testremoveVCbyCP() {
+ testConnectionSetup();
+
+ List<PointToPointIntent> removedIntents = new ArrayList<PointToPointIntent>();
+ SdxL2ConnectionPoint cpOne = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST1", CP1, VLANS1);
+ SdxL2ConnectionPoint cpTwo = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST2", CP2, VLANS2);
+
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpOne, cpTwo, "1"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("2"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("4")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpTwo, cpOne, "1"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("4"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("2")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpOne, cpTwo, "2"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("3"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("5")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpTwo, cpOne, "2"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("5"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("3")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpOne, cpTwo, "3"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("4"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("6")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpTwo, cpOne, "3"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("6"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("4")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .priority(2000)
+ .build());
+
+ SdxL2ConnectionPoint cpFive = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST5", CP5, VLANS5);
+ SdxL2ConnectionPoint cpSix = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST6", CP6, VLANS6);
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpFive, cpSix, "1"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("100"))))
+ .treatment(buildTreatment(null, null, true))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP5))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP6))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpSix, cpFive, "1"))
+ .selector(buildSelector(null, null))
+ .treatment(buildTreatment(null, VlanId.vlanId(Short.parseShort("100")), false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP6))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP5))
+ .priority(2000)
+ .build());
+
+ SdxL2ConnectionPoint cpSeven = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST7", CP7, VLANS7);
+ SdxL2ConnectionPoint cpEight = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST8", CP8, VLANS8);
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpSeven, cpEight, "1"))
+ .selector(buildSelector(null, null))
+ .treatment(buildTreatment(null, VlanId.vlanId(Short.parseShort("111")), false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP7))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP8))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpEight, cpSeven, "1"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("111"))))
+ .treatment(buildTreatment(null, null, true))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP8))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP7))
+ .priority(2000)
+ .build());
+
+ SdxL2ConnectionPoint cpNine = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST9", CP9, VLANS9);
+ SdxL2ConnectionPoint cpTen = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST10", CP10, VLANS10);
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpNine, cpTen, "1"))
+ .selector(buildSelector(null, null))
+ .treatment(buildTreatment(null, null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP9))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP10))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpTen, cpNine, "1"))
+ .selector(buildSelector(null, null))
+ .treatment(buildTreatment(null, null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP10))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP9))
+ .priority(2000)
+ .build());
+
+
+ manager.removeVC(cpOne);
+ manager.removeVC(cpSix);
+ manager.removeVC(cpSeven);
+ manager.removeVC(cpTen);
+
+ assertEquals(Collections.emptySet(), manager.getVCs(Optional.ofNullable(null)));
+
+ assertEquals(0, manager.intentService.getIntentCount());
+
+ for (Intent removedIntent : removedIntents) {
+ boolean found = false;
+ for (Intent existingIntent : manager.intentService.getIntents()) {
+ if (removedIntent.key().equals(existingIntent.key())) {
+ found = true;
+ assertTrue(format("Intent %s equal %s", removedIntent, existingIntent),
+ !IntentUtils.intentsAreEqual(removedIntent, existingIntent));
+ break;
+ }
+ }
+ assertTrue(!found);
+ }
+
+ }
+
+ @Test
+ public void testremoveVCbySdx() {
+ testConnectionSetup();
+
+ List<PointToPointIntent> removedIntents = new ArrayList<>();
+ SdxL2ConnectionPoint cpOne = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST1", CP1, VLANS1);
+ SdxL2ConnectionPoint cpTwo = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST2", CP2, VLANS2);
+
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpOne, cpTwo, "1"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("2"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("4")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpTwo, cpOne, "1"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("4"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("2")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpOne, cpTwo, "2"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("3"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("5")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpTwo, cpOne, "2"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("5"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("3")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpOne, cpTwo, "3"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("4"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("6")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpTwo, cpOne, "3"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("6"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("4")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .priority(2000)
+ .build());
+
+ SdxL2ConnectionPoint cpFive = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST5", CP5, VLANS5);
+ SdxL2ConnectionPoint cpSix = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST6", CP6, VLANS6);
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpFive, cpSix, "1"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("100"))))
+ .treatment(buildTreatment(null, null, true))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP5))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP6))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpSix, cpFive, "1"))
+ .selector(buildSelector(null, null))
+ .treatment(buildTreatment(null, VlanId.vlanId(Short.parseShort("100")), false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP6))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP5))
+ .priority(2000)
+ .build());
+
+ SdxL2ConnectionPoint cpSeven = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST7", CP7, VLANS7);
+ SdxL2ConnectionPoint cpEight = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST8", CP8, VLANS8);
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpSeven, cpEight, "1"))
+ .selector(buildSelector(null, null))
+ .treatment(buildTreatment(null, VlanId.vlanId(Short.parseShort("111")), false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP7))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP8))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpEight, cpSeven, "1"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("111"))))
+ .treatment(buildTreatment(null, null, true))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP8))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP7))
+ .priority(2000)
+ .build());
+
+ SdxL2ConnectionPoint cpNine = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST9", CP9, VLANS9);
+ SdxL2ConnectionPoint cpTen = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST10", CP10, VLANS10);
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpNine, cpTen, "1"))
+ .selector(buildSelector(null, null))
+ .treatment(buildTreatment(null, null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP9))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP10))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpTen, cpNine, "1"))
+ .selector(buildSelector(null, null))
+ .treatment(buildTreatment(null, null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP10))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP9))
+ .priority(2000)
+ .build());
+
+ manager.removeVCs(SDXL2_2);
+ assertEquals(Collections.emptySet(), manager.getVCs(Optional.ofNullable(null)));
+ assertEquals(Collections.emptySet(), manager.getVCs(Optional.of(SDXL2_2)));
+
+ for (Intent removedIntent : removedIntents) {
+ boolean found = false;
+ for (Intent existingIntent : manager.intentService.getIntents()) {
+ if (removedIntent.key().equals(existingIntent.key())) {
+ found = true;
+ assertTrue(format("Intent %s equal %s", removedIntent, existingIntent),
+ !IntentUtils.intentsAreEqual(removedIntent, existingIntent));
+ break;
+ }
+ }
+ assertTrue(!found);
+ }
+ }
+}
diff --git a/sdx-l2/src/test/java/org/onosproject/sdxl2/SdxL2VCManagerTest.java b/sdx-l2/src/test/java/org/onosproject/sdxl2/SdxL2VCManagerTest.java
new file mode 100644
index 0000000..26323fb
--- /dev/null
+++ b/sdx-l2/src/test/java/org/onosproject/sdxl2/SdxL2VCManagerTest.java
@@ -0,0 +1,254 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.sdxl2;
+
+import com.google.common.collect.Sets;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.onosproject.TestApplicationId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.MockIdGenerator;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
+import static java.lang.String.format;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNull;
+
+
+public class SdxL2VCManagerTest {
+
+ private static final String SDXL2_1 = "sdxl2_test1";
+ private static final String CP1 = "of:00000000000001/1";
+ private static final String CP2 = "of:00000000000002/1";
+ private static final String VLANS1 = "2,3,4";
+ private static final String VLANS2 = "4,5,6";
+ private static final String CEMAC1 = "52:40:00:12:44:01";
+ private static final String CEMAC2 = "51:12:11:00:23:01";
+ private static final String CP3 = "of:00000000000002/2";
+ private static final String VLANS3 = "8,9,10";
+ private static final String CEMAC3 = "52:12:11:00:23:01";
+ private static final String SDXL2_2 = "sdxl2_test2";
+ private static final String CP5 = "of:00000000000002/4";
+ private static final String VLANS5 = "100";
+ private static final String CEMAC5 = "52:12:11:00:23:11";
+ private static final String CP6 = "of:00000000000004/4";
+ private static final String VLANS6 = "1";
+ private static final String CEMAC6 = "52:12:11:a0:23:11";
+ private static final String CP7 = "of:0000000000000a/4";
+ private static final String VLANS7 = "1";
+ private static final String CEMAC7 = "52:12:21:00:25:11";
+ private static final String CP8 = "of:00000000000009/4";
+ private static final String VLANS8 = "111";
+ private static final String CEMAC8 = "52:12:14:a0:23:11";
+ private static final String CP9 = "of:0000000000000a/4";
+ private static final String VLANS9 = "1";
+ private static final String CEMAC9 = "52:12:21:00:28:11";
+ private static final String CP10 = "of:00000000000009/4";
+ private static final String VLANS10 = "1";
+ private static final String CEMAC10 = "52:12:14:aa:23:11";
+ private static final ApplicationId APPID = TestApplicationId.create("foo");
+ @Rule
+ public ExpectedException exceptionAddVC = ExpectedException.none();
+ @Rule
+ public ExpectedException exceptionRemoveVC = ExpectedException.none();
+ @Rule
+ public ExpectedException exceptionGetVC = ExpectedException.none();
+ private SdxL2MacVCManager manager;
+ private IdGenerator idGenerator = new MockIdGenerator();
+
+ /**
+ * Prepare environment before starting testing VCs.
+ */
+ @Before
+ public void setUp() {
+ SdxL2DistributedStore store = new SdxL2DistributedStore();
+ store.initForTest();
+ manager = new SdxL2MacVCManager(
+ APPID, store, new IntentServiceTest());
+ Intent.bindIdGenerator(idGenerator);
+ }
+
+ /**
+ * Clean up environment after finishing testing VCs.
+ */
+ @After
+ public void tearDown() {
+ Intent.unbindIdGenerator(idGenerator);
+ }
+
+ @Test
+ public void testgenerateKey() {
+ SdxL2ConnectionPoint cpOne = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST1", CP1, VLANS1, CEMAC1);
+ SdxL2ConnectionPoint cpOneAux = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST2", CP2, VLANS2, CEMAC1);
+
+ SdxL2ConnectionPoint cpTwo = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST2", CP2, VLANS2, CEMAC1);
+ SdxL2ConnectionPoint cpTwoAux = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST1", CP1, VLANS1, CEMAC1);
+
+ Key key1 = manager.generateIntentKey(SDXL2_1, cpOne, cpTwo, "1");
+ Key key2 = manager.generateIntentKey(SDXL2_1, cpOneAux, cpTwoAux, "1");
+ assertNotEquals(key1, key2);
+
+ Key key3 = manager.generateIntentKey(SDXL2_1, cpOne, cpTwoAux, "1");
+ Key key4 = manager.generateIntentKey(SDXL2_1, cpOneAux, cpTwo, "1");
+ assertNotEquals(key3, key4);
+ }
+
+ @Test
+ public void testAddVCChecks() {
+
+ SdxL2ConnectionPoint cpFive = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST1", CP1, VLANS1, CEMAC1);
+ SdxL2ConnectionPoint cpSix = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST2", CP2, VLANS2, CEMAC2);
+ manager.addVC(SDXL2_1, cpFive, cpSix);
+
+ SdxL2ConnectionPoint cpSeven = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST2", CP2, VLANS2, CEMAC2);
+ SdxL2ConnectionPoint cpEight = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST1", CP1, VLANS1, CEMAC1);
+ manager.addVC(SDXL2_1, cpSeven, cpEight);
+
+ SdxL2ConnectionPoint cpNine = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST1", CP1, VLANS1, CEMAC1);
+ SdxL2ConnectionPoint cpTen = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST3", CP3, VLANS3, CEMAC3);
+ manager.addVC(SDXL2_1, cpNine, cpTen);
+
+ exceptionAddVC.expect(IllegalStateException.class);
+ SdxL2ConnectionPoint cpOne = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST1", CP1, VLANS1, CEMAC1);
+ SdxL2ConnectionPoint cpTwo = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST2", CP2, VLANS2, CEMAC1);
+ manager.addVC(SDXL2_1, cpOne, cpTwo);
+ }
+
+ @Test
+ public void testremoveVCChecks() {
+ SdxL2ConnectionPoint cpOne = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST1", CP1, VLANS1, CEMAC1);
+ SdxL2ConnectionPoint cpTwo = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST2", CP2, VLANS2, CEMAC1);
+
+ SdxL2ConnectionPoint cpFive = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST1", CP1, VLANS1, CEMAC1);
+ SdxL2ConnectionPoint cpSix = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST2", CP2, VLANS2, CEMAC2);
+
+ SdxL2ConnectionPoint cpSeven = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST2", CP2, VLANS2, CEMAC2);
+ SdxL2ConnectionPoint cpEight = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST1", CP1, VLANS1, CEMAC1);
+
+ SdxL2ConnectionPoint cpNine = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST1", CP1, VLANS1, CEMAC1);
+ SdxL2ConnectionPoint cpTen = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST3", CP3, VLANS3, CEMAC3);
+
+ manager.addVC(SDXL2_1, cpFive, cpSix);
+ manager.removeVC(cpFive, cpSix);
+ manager.removeVC(cpSeven, cpEight);
+ manager.removeVC(cpNine, cpTen);
+
+ exceptionRemoveVC.expect(IllegalStateException.class);
+ manager.removeVC(cpOne, cpTwo);
+ }
+
+ @Test
+ public void testGetVC() {
+ connectionSetup();
+
+ Iterator<SdxL2ConnectionPoint> lhs = setupLhsCPs().iterator();
+ Iterator<SdxL2ConnectionPoint> rhs = setupRhsCPs().iterator();
+ String vc;
+ SdxL2ConnectionPoint one;
+ SdxL2ConnectionPoint two;
+ while (lhs.hasNext()) {
+ one = lhs.next();
+ two = rhs.next();
+ vc = one.toString().compareTo(two.toString()) < 0 ?
+ format(SdxL2VCManager.SDXL2_CPS_FORMAT, one, two) :
+ format(SdxL2VCManager.SDXL2_CPS_FORMAT, two, one);
+ assertEquals(vc, manager.getVC(one, two));
+ }
+
+ SdxL2ConnectionPoint cpLeft = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST1", CP1, VLANS1, CEMAC1);
+ SdxL2ConnectionPoint cpRight = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST1", CP3, VLANS3, CEMAC1);
+
+ // This VC has not been created before
+ vc = cpLeft.toString().compareTo(cpRight.toString()) < 0 ?
+ format(SdxL2VCManager.SDXL2_CPS_FORMAT, cpLeft, cpRight) :
+ format(SdxL2VCManager.SDXL2_CPS_FORMAT, cpRight, cpLeft);
+
+ assertNull(manager.getVC(cpLeft, cpRight));
+ }
+
+ @Test
+ public void testgetVCs() {
+ connectionSetup();
+ Iterator<SdxL2ConnectionPoint> lhs = setupLhsCPs().iterator();
+ Iterator<SdxL2ConnectionPoint> rhs = setupRhsCPs().iterator();
+ Set<String> expectedVCs = Sets.newHashSet();
+ String vc;
+ String lhsName;
+ String rhsName;
+ while (lhs.hasNext()) {
+ lhsName = lhs.next().name();
+ rhsName = rhs.next().name();
+ vc = lhsName.compareTo(rhsName.toString()) < 0 ?
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2_2, lhsName, rhsName) :
+ format(SdxL2VCManager.NAME_FORMAT, SDXL2_2, rhsName, lhsName);
+ expectedVCs.add(vc);
+ }
+ Set<String> vcs = manager.getVCs(Optional.of(SDXL2_2));
+ assertEquals(expectedVCs, vcs);
+ vcs = manager.getVCs(Optional.of(SDXL2_1));
+ assertEquals(Collections.emptySet(), vcs);
+ vcs = manager.getVCs(Optional.ofNullable(null));
+ assertEquals(expectedVCs, vcs);
+ }
+
+ public List<SdxL2ConnectionPoint> setupLhsCPs() {
+ List<SdxL2ConnectionPoint> cps = new ArrayList<SdxL2ConnectionPoint>();
+ SdxL2ConnectionPoint cpone = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST1", CP1, VLANS1, CEMAC1);
+ cps.add(cpone);
+ SdxL2ConnectionPoint cpfive = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST5", CP5, VLANS5, CEMAC5);
+ cps.add(cpfive);
+ SdxL2ConnectionPoint cpseven = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST7", CP7, VLANS7, CEMAC7);
+ cps.add(cpseven);
+ SdxL2ConnectionPoint cpnine = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST9", CP9, VLANS9, CEMAC9);
+ cps.add(cpnine);
+ return cps;
+ }
+
+ public List<SdxL2ConnectionPoint> setupRhsCPs() {
+ List<SdxL2ConnectionPoint> cps = new ArrayList<SdxL2ConnectionPoint>();
+ SdxL2ConnectionPoint cptwo = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST2", CP2, VLANS2, CEMAC2);
+ cps.add(cptwo);
+ SdxL2ConnectionPoint cpsix = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST6", CP6, VLANS6, CEMAC6);
+ cps.add(cpsix);
+ SdxL2ConnectionPoint cpeight = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST8", CP8, VLANS8, CEMAC8);
+ cps.add(cpeight);
+ SdxL2ConnectionPoint cpten = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST10", CP10, VLANS10, CEMAC10);
+ cps.add(cpten);
+ return cps;
+ }
+
+ private void connectionSetup() {
+ Iterator<SdxL2ConnectionPoint> lhs = setupLhsCPs().iterator();
+ Iterator<SdxL2ConnectionPoint> rhs = setupRhsCPs().iterator();
+ while (lhs.hasNext()) {
+ manager.addVC(SDXL2_2, lhs.next(), rhs.next());
+ }
+ }
+}
diff --git a/sdx-l2/src/test/java/org/onosproject/sdxl2/SdxL2VlanVCManagerTest.java b/sdx-l2/src/test/java/org/onosproject/sdxl2/SdxL2VlanVCManagerTest.java
new file mode 100644
index 0000000..e6dd921
--- /dev/null
+++ b/sdx-l2/src/test/java/org/onosproject/sdxl2/SdxL2VlanVCManagerTest.java
@@ -0,0 +1,723 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.sdxl2;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.VlanId;
+import org.onosproject.TestApplicationId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.EncapsulationType;
+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.intent.AbstractIntentTest;
+import org.onosproject.net.intent.Constraint;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentUtils;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.PointToPointIntent;
+import org.onosproject.net.intent.constraint.EncapsulationConstraint;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Optional;
+
+import static java.lang.String.format;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Unit tests for SdxL2VlanVCManager.
+ */
+public class SdxL2VlanVCManagerTest extends AbstractIntentTest {
+
+ private static final String SDXL2_2 = "sdxl2_test2";
+ private static final String CP1 = "of:00000000000001/1";
+ private static final String CP2 = "of:00000000000002/1";
+ private static final String CP5 = "of:00000000000002/4";
+ private static final String CP6 = "of:00000000000004/4";
+ private static final String CP7 = "of:0000000000000a/4";
+ private static final String CP8 = "of:00000000000009/4";
+ private static final String CP9 = "of:0000000000000a/4";
+ private static final String CP10 = "of:00000000000009/4";
+ private static final String VLANS1 = "2,3,4";
+ private static final ArrayList<String> VLANS1_ARRAY =
+ new ArrayList<String>(Arrays.asList(VLANS1.split(",")));;
+ private static final String VLANS2 = "4,5,6";
+ private static final ArrayList<String> VLANS2_ARRAY =
+ new ArrayList<String>(Arrays.asList(VLANS2.split(",")));;
+ private static final String VLANS5 = "100";
+ private static final String VLANS6 = "1";
+ private static final String VLANS7 = "1";
+ private static final String VLANS8 = "111";
+ private static final String VLANS9 = "1";
+ private static final String VLANS10 = "1";
+ private static final String NAME_FORMAT = "%s:%s-%s";
+ private static final String KEY_FORMAT = "%s,%s";
+ private static final ApplicationId APPID = TestApplicationId.create("foo");
+ private static final int POINT_TO_POINT_INDEXES = 3;
+ private SdxL2VlanVCManager manager;
+ private List<PointToPointIntent> intentList;
+
+ /**
+ * Prepare environment before starting testing VLAN-based VCs.
+ */
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ SdxL2DistributedStore store = new SdxL2DistributedStore();
+ store.initForTest();
+ manager = new SdxL2VlanVCManager(
+ APPID, store, new IntentServiceTest());
+ intentList = setIntents();
+ }
+
+ /**
+ * Clean up environment after finishing testing VLAN-based VCs.
+ */
+ @After
+ public void tearDown() {
+ super.tearDown();
+ }
+
+ public List<PointToPointIntent> setIntents() {
+ List<PointToPointIntent> intents = new ArrayList<PointToPointIntent>();
+ List<Constraint> encapsulation = buildConstraints();
+
+ SdxL2ConnectionPoint cpone = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST1", CP1, VLANS1);
+ SdxL2ConnectionPoint cptwo = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST2", CP2, VLANS2);
+ for (int i = 0; i < POINT_TO_POINT_INDEXES; i++) {
+ intents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpone, cptwo, Integer.toString(i + 1))) // 1
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort(VLANS1_ARRAY.get(i)))))
+ .treatment(buildTreatment(
+ VlanId.vlanId(Short.parseShort(VLANS2_ARRAY.get(i))), null, false))
+ .constraints(encapsulation)
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .priority(2000)
+ .build());
+ intents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cptwo, cpone, Integer.toString(i + 1)))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort(VLANS2_ARRAY.get(i)))))
+ .treatment(buildTreatment(
+ VlanId.vlanId(Short.parseShort(VLANS1_ARRAY.get(i))), null, false))
+ .constraints(encapsulation)
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .priority(2000)
+ .build());
+ }
+
+ SdxL2ConnectionPoint cpfive = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST5", CP5, VLANS5);
+ SdxL2ConnectionPoint cpsix = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST6", CP6, VLANS6);
+ intents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpfive, cpsix, "1"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("100"))))
+ .treatment(buildTreatment(null, null, true))
+ .constraints(encapsulation)
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP5))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP6))
+ .priority(2000)
+ .build());
+ intents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpsix, cpfive, "1"))
+ .selector(buildSelector(null, null))
+ .constraints(encapsulation)
+ .treatment(buildTreatment(null, VlanId.vlanId(Short.parseShort("100")), false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP6))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP5))
+ .priority(2000)
+ .build());
+
+ SdxL2ConnectionPoint cpseven = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST7", CP7, VLANS7);
+ SdxL2ConnectionPoint cpeight = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST8", CP8, VLANS8);
+ intents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpseven, cpeight, "1"))
+ .selector(buildSelector(null, null))
+ .treatment(buildTreatment(null, VlanId.vlanId(Short.parseShort("111")), false))
+ .constraints(encapsulation)
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP7))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP8))
+ .priority(2000)
+ .build());
+ intents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpeight, cpseven, "1"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("111"))))
+ .constraints(encapsulation)
+ .treatment(buildTreatment(null, null, true))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP8))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP7))
+ .priority(2000)
+ .build());
+
+ SdxL2ConnectionPoint cpnine = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST9", CP9, VLANS9);
+ SdxL2ConnectionPoint cpten = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST10", CP10, VLANS10);
+ intents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpnine, cpten, "1"))
+ .selector(buildSelector(null, null))
+ .constraints(encapsulation)
+ .treatment(buildTreatment(null, null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP9))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP10))
+ .priority(2000)
+ .build());
+ intents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpten, cpnine, "1"))
+ .selector(buildSelector(null, null))
+ .constraints(encapsulation)
+ .treatment(buildTreatment(null, null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP10))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP9))
+ .priority(2000)
+ .build());
+
+ return intents;
+ }
+
+ private TrafficTreatment buildTreatment(VlanId setVlan,
+ VlanId pushVlan,
+ boolean popVlan) {
+
+ TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
+ if (setVlan != null) {
+ treatmentBuilder.setVlanId(setVlan);
+ }
+ if (pushVlan != null) {
+ treatmentBuilder.pushVlan();
+ treatmentBuilder.setVlanId(pushVlan);
+ }
+ if (popVlan) {
+ treatmentBuilder.popVlan();
+ }
+ return treatmentBuilder.build();
+ }
+
+ private TrafficSelector buildSelector(Short ethertype,
+ VlanId ingresstag) {
+
+ TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
+ if (ethertype != null) {
+ selectorBuilder.matchEthType(ethertype);
+ }
+ if (ingresstag != null) {
+ selectorBuilder.matchVlanId(ingresstag);
+ }
+ return selectorBuilder.build();
+ }
+
+ protected List<Constraint> buildConstraints() {
+ final List<Constraint> constraints = new LinkedList<>();
+ constraints.add(new EncapsulationConstraint(EncapsulationType.VLAN));
+ return constraints;
+ }
+
+ private Key generateIntentKey(String sdxl2, SdxL2ConnectionPoint cpone, SdxL2ConnectionPoint cptwo, String index) {
+ String cps = format(NAME_FORMAT, sdxl2, cpone.name(), cptwo.name());
+ String key = format(KEY_FORMAT, cps, index);
+ return Key.of(key, APPID);
+ }
+
+ @Test
+ public void testConnectionSetup() {
+ Iterator<SdxL2ConnectionPoint> lhs = setupLhsCPs().iterator();
+ Iterator<SdxL2ConnectionPoint> rhs = setupRhsCPs().iterator();
+ while (lhs.hasNext() && rhs.hasNext()) {
+ manager.addVC(SDXL2_2, lhs.next(), rhs.next());
+ }
+
+ assertEquals(intentList.size(), manager.intentService.getIntentCount());
+
+ for (Intent emulatedIntent : intentList) {
+ boolean found = false;
+ for (Intent realIntent : manager.intentService.getIntents()) {
+ if (emulatedIntent.key().equals(realIntent.key())) {
+ found = true;
+ assertTrue(format("Comparing %s and %s", emulatedIntent, realIntent),
+ IntentUtils.intentsAreEqual(emulatedIntent, realIntent));
+ break;
+ }
+ }
+ assertTrue(found);
+ }
+ }
+
+ public List<SdxL2ConnectionPoint> setupLhsCPs() {
+ List<SdxL2ConnectionPoint> cps = new ArrayList<SdxL2ConnectionPoint>();
+ SdxL2ConnectionPoint cpone = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST1", CP1, VLANS1);
+ cps.add(cpone);
+ SdxL2ConnectionPoint cpfive = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST5", CP5, VLANS5);
+ cps.add(cpfive);
+ SdxL2ConnectionPoint cpseven = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST7", CP7, VLANS7);
+ cps.add(cpseven);
+ SdxL2ConnectionPoint cpnine = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST9", CP9, VLANS9);
+ cps.add(cpnine);
+ return cps;
+ }
+
+ public List<SdxL2ConnectionPoint> setupRhsCPs() {
+ List<SdxL2ConnectionPoint> cps = new ArrayList<SdxL2ConnectionPoint>();
+ SdxL2ConnectionPoint cptwo = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST2", CP2, VLANS2);
+ cps.add(cptwo);
+ SdxL2ConnectionPoint cpsix = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST6", CP6, VLANS6);
+ cps.add(cpsix);
+ SdxL2ConnectionPoint cpeight = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST8", CP8, VLANS8);
+ cps.add(cpeight);
+ SdxL2ConnectionPoint cpten = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST10", CP10, VLANS10);
+ cps.add(cpten);
+ return cps;
+ }
+
+
+ @Test
+ public void removeConnection() {
+ testConnectionSetup();
+
+ List<PointToPointIntent> removedIntents = new ArrayList<PointToPointIntent>();
+ SdxL2ConnectionPoint cpone = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST1", CP1, VLANS1);
+ SdxL2ConnectionPoint cptwo = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST2", CP2, VLANS2);
+
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpone, cptwo, "1"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("2"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("4")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cptwo, cpone, "1"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("4"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("2")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpone, cptwo, "2"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("3"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("5")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cptwo, cpone, "2"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("5"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("3")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpone, cptwo, "3"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("4"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("6")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cptwo, cpone, "3"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("6"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("4")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .priority(2000)
+ .build());
+
+ SdxL2ConnectionPoint cpfive = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST5", CP5, VLANS5);
+ SdxL2ConnectionPoint cpsix = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST6", CP6, VLANS6);
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpfive, cpsix, "1"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("100"))))
+ .treatment(buildTreatment(null, null, true))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP5))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP6))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpsix, cpfive, "1"))
+ .selector(buildSelector(null, null))
+ .treatment(buildTreatment(null, VlanId.vlanId(Short.parseShort("100")), false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP6))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP5))
+ .priority(2000)
+ .build());
+
+ SdxL2ConnectionPoint cpseven = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST7", CP7, VLANS7);
+ SdxL2ConnectionPoint cpeight = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST8", CP8, VLANS8);
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpseven, cpeight, "1"))
+ .selector(buildSelector(null, null))
+ .treatment(buildTreatment(null, VlanId.vlanId(Short.parseShort("111")), false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP7))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP8))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpeight, cpseven, "1"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("111"))))
+ .treatment(buildTreatment(null, null, true))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP8))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP7))
+ .priority(2000)
+ .build());
+
+ manager.removeVC(cpone, cptwo);
+ manager.removeVC(cpfive, cpsix);
+ manager.removeVC(cpseven, cpeight);
+
+ assertEquals(2, manager.intentService.getIntentCount());
+
+ for (Intent removedIntent : removedIntents) {
+ boolean found = false;
+ for (Intent existingIntent : manager.intentService.getIntents()) {
+ if (removedIntent.key().equals(existingIntent.key())) {
+ found = true;
+ assertTrue(format("Intent %s equal %s", removedIntent, existingIntent),
+ !IntentUtils.intentsAreEqual(removedIntent, existingIntent));
+ break;
+ }
+ }
+ assertTrue(!found);
+ }
+
+ }
+
+
+ @Test
+ public void testRemoveVCbyCP() {
+ testConnectionSetup();
+
+ List<PointToPointIntent> removedIntents = new ArrayList<PointToPointIntent>();
+ SdxL2ConnectionPoint cpone = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST1", CP1, VLANS1);
+ SdxL2ConnectionPoint cptwo = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST2", CP2, VLANS2);
+
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpone, cptwo, "1"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("2"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("4")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cptwo, cpone, "1"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("4"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("2")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpone, cptwo, "2"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("3"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("5")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cptwo, cpone, "2"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("5"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("3")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpone, cptwo, "3"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("4"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("6")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cptwo, cpone, "3"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("6"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("4")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .priority(2000)
+ .build());
+
+ SdxL2ConnectionPoint cpfive = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST5", CP5, VLANS5);
+ SdxL2ConnectionPoint cpsix = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST6", CP6, VLANS6);
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpfive, cpsix, "1"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("100"))))
+ .treatment(buildTreatment(null, null, true))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP5))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP6))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpsix, cpfive, "1"))
+ .selector(buildSelector(null, null))
+ .treatment(buildTreatment(null, VlanId.vlanId(Short.parseShort("100")), false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP6))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP5))
+ .priority(2000)
+ .build());
+
+ SdxL2ConnectionPoint cpseven = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST7", CP7, VLANS7);
+ SdxL2ConnectionPoint cpeight = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST8", CP8, VLANS8);
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpseven, cpeight, "1"))
+ .selector(buildSelector(null, null))
+ .treatment(buildTreatment(null, VlanId.vlanId(Short.parseShort("111")), false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP7))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP8))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpeight, cpseven, "1"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("111"))))
+ .treatment(buildTreatment(null, null, true))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP8))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP7))
+ .priority(2000)
+ .build());
+
+ SdxL2ConnectionPoint cpnine = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST9", CP9, VLANS9);
+ SdxL2ConnectionPoint cpten = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST10", CP10, VLANS10);
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpnine, cpten, "1"))
+ .selector(buildSelector(null, null))
+ .treatment(buildTreatment(null, null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP9))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP10))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpten, cpnine, "1"))
+ .selector(buildSelector(null, null))
+ .treatment(buildTreatment(null, null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP10))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP9))
+ .priority(2000)
+ .build());
+
+ manager.removeVC(cpone);
+ manager.removeVC(cpsix);
+ manager.removeVC(cpseven);
+ manager.removeVC(cpten);
+
+ assertEquals(Collections.emptySet(), manager.getVCs(Optional.ofNullable(null)));
+
+ assertEquals(0, manager.intentService.getIntentCount());
+
+ for (Intent removedIntent : removedIntents) {
+ boolean found = false;
+ for (Intent existingIntent : manager.intentService.getIntents()) {
+ if (removedIntent.key().equals(existingIntent.key())) {
+ found = true;
+ assertTrue(format("Intent %s equal %s", removedIntent, existingIntent),
+ !IntentUtils.intentsAreEqual(removedIntent, existingIntent));
+ break;
+ }
+ }
+ assertTrue(!found);
+ }
+
+ }
+
+ @Test
+ public void testremoveVCbySdx() {
+ testConnectionSetup();
+
+ List<PointToPointIntent> removedIntents = new ArrayList<PointToPointIntent>();
+ SdxL2ConnectionPoint cpone = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST1", CP1, VLANS1);
+ SdxL2ConnectionPoint cptwo = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST2", CP2, VLANS2);
+
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpone, cptwo, "1"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("2"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("4")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cptwo, cpone, "1"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("4"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("2")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpone, cptwo, "2"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("3"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("5")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cptwo, cpone, "2"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("5"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("3")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpone, cptwo, "3"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("4"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("6")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cptwo, cpone, "3"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("6"))))
+ .treatment(buildTreatment(VlanId.vlanId(Short.parseShort("4")), null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP2))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP1))
+ .priority(2000)
+ .build());
+
+ SdxL2ConnectionPoint cpfive = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST5", CP5, VLANS5);
+ SdxL2ConnectionPoint cpsix = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST6", CP6, VLANS6);
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpfive, cpsix, "1"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("100"))))
+ .treatment(buildTreatment(null, null, true))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP5))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP6))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpsix, cpfive, "1"))
+ .selector(buildSelector(null, null))
+ .treatment(buildTreatment(null, VlanId.vlanId(Short.parseShort("100")), false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP6))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP5))
+ .priority(2000)
+ .build());
+
+ SdxL2ConnectionPoint cpseven = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST7", CP7, VLANS7);
+ SdxL2ConnectionPoint cpeight = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST8", CP8, VLANS8);
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpseven, cpeight, "1"))
+ .selector(buildSelector(null, null))
+ .treatment(buildTreatment(null, VlanId.vlanId(Short.parseShort("111")), false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP7))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP8))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpeight, cpseven, "1"))
+ .selector(buildSelector(null, VlanId.vlanId(Short.parseShort("111"))))
+ .treatment(buildTreatment(null, null, true))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP8))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP7))
+ .priority(2000)
+ .build());
+
+ SdxL2ConnectionPoint cpnine = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST9", CP9, VLANS9);
+ SdxL2ConnectionPoint cpten = SdxL2ConnectionPoint.sdxl2ConnectionPoint("TEST10", CP10, VLANS10);
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpnine, cpten, "1"))
+ .selector(buildSelector(null, null))
+ .treatment(buildTreatment(null, null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP9))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP10))
+ .priority(2000)
+ .build());
+ removedIntents.add(PointToPointIntent.builder()
+ .appId(APPID)
+ .key(generateIntentKey(SDXL2_2, cpten, cpnine, "1"))
+ .selector(buildSelector(null, null))
+ .treatment(buildTreatment(null, null, false))
+ .ingressPoint(ConnectPoint.deviceConnectPoint(CP10))
+ .egressPoint(ConnectPoint.deviceConnectPoint(CP9))
+ .priority(2000)
+ .build());
+
+ manager.removeVCs(SDXL2_2);
+ assertEquals(Collections.emptySet(), manager.getVCs(Optional.ofNullable(null)));
+ assertEquals(Collections.emptySet(), manager.getVCs(Optional.of(SDXL2_2)));
+
+ for (Intent removedIntent : removedIntents) {
+ boolean found = false;
+ for (Intent existingIntent : manager.intentService.getIntents()) {
+ if (removedIntent.key().equals(existingIntent.key())) {
+ found = true;
+ assertTrue(format("Intent %s equal %s", removedIntent, existingIntent),
+ !IntentUtils.intentsAreEqual(removedIntent, existingIntent));
+ break;
+ }
+ }
+ assertTrue(!found);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/sdx-l2/src/test/java/org/onosproject/sdxl2/VirtualCircuitTest.java b/sdx-l2/src/test/java/org/onosproject/sdxl2/VirtualCircuitTest.java
new file mode 100644
index 0000000..97dadcb
--- /dev/null
+++ b/sdx-l2/src/test/java/org/onosproject/sdxl2/VirtualCircuitTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.sdxl2;
+
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+/**
+ * Tests VirtualCircuit functionalities.
+ */
+public class VirtualCircuitTest {
+
+
+ public static final String CP1 = "of:00000000000001/1";
+ public static final String CP2 = "of:00000000000002/1";
+ public static final String VLANS1 = "1,2,3,4";
+ public static final String VLANS3 = "1,2,3";
+ public static final String CEMAC1 = "52:40:00:12:44:01";
+ public static final String CEMAC6 = "52:40:00:12:44:02";
+
+ /*
+ * Tests VC with different VLANs.
+ */
+ @Test
+ public void testVC1() {
+ SdxL2ConnectionPoint scp1 = SdxL2ConnectionPoint.sdxl2ConnectionPoint("FI1", CP1, VLANS1, CEMAC1);
+ SdxL2ConnectionPoint scp2 = SdxL2ConnectionPoint.sdxl2ConnectionPoint("GE4", CP2, VLANS3, CEMAC6);
+ VirtualCircuit vc1 = new VirtualCircuit(scp1, scp2);
+ }
+
+ /*
+ Tests creating VC with the same VLANs.
+ */
+ @Test
+ public void testVCEquality() {
+ SdxL2ConnectionPoint scp1 = SdxL2ConnectionPoint.sdxl2ConnectionPoint("FI1", CP1, VLANS1, CEMAC1);
+ SdxL2ConnectionPoint scp2 = SdxL2ConnectionPoint.sdxl2ConnectionPoint("GE4", CP2, VLANS3, CEMAC6);
+ VirtualCircuit vc1 = new VirtualCircuit(scp1, scp2);
+ VirtualCircuit vc2 = new VirtualCircuit(scp2, scp1);
+ assertEquals(vc1, vc2);
+ SdxL2ConnectionPoint scp3 = SdxL2ConnectionPoint.sdxl2ConnectionPoint("FI2", CP1, VLANS1, CEMAC1);
+ VirtualCircuit vc3 = new VirtualCircuit(scp1, scp3);
+ assertNotEquals(vc1, vc3);
+ }
+
+}