blob: 73878484daca845eb097f87fd6d0e8ea7f092b1a [file] [log] [blame]
/*
* Copyright 2016-present Open Networking Foundation
*
* 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 org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onosproject.net.ConnectPoint;
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 ids; MAC address (optional).
*/
public class SdxL2ConnectionPoint {
private final ConnectPoint cPoint;
private final List<VlanId> vlanIds;
private final MacAddress ceMac;
private String name;
/**
* Creates a new SDX-L2 Connection Point.
*
* @param name SDX-L2 connection point name
* @param cPoint connect point
* @param vlans the customer edge VLANs
* @param ceMac the customer edge router MAC address
*/
public SdxL2ConnectionPoint(String name, ConnectPoint cPoint, List<VlanId> vlans, MacAddress ceMac) {
this.name = name;
this.cPoint = cPoint;
this.vlanIds = vlans;
this.ceMac = ceMac;
}
/**
* 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
*
* @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[] 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<>();
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 Connection Point.
*
* @return Connection Point object
*/
public ConnectPoint connectPoint() {
return cPoint;
}
/**
* Returns the set of VLANs that are used by the customer edge.
*
* @return a set of VLAN ids
*/
public List<VlanId> vlanIds() {
return vlanIds;
}
/**
* Returns the customer edge MAC address.
*
* @return a MAC address object
*/
public MacAddress macAddress() {
return ceMac;
}
@Override
public int hashCode() {
return Objects.hash(name, cPoint, vlanIds, ceMac);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof SdxL2ConnectionPoint) {
final SdxL2ConnectionPoint other = (SdxL2ConnectionPoint) obj;
return Objects.equals(this.name, other.name) &&
Objects.equals(this.cPoint, other.cPoint) &&
Objects.equals(this.vlanIds, other.vlanIds) &&
Objects.equals(this.ceMac, other.ceMac);
}
return false;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("name", name)
.add("connectionPoint", cPoint)
.add("vlanIds", vlanIds)
.add("ceMac", ceMac)
.toString();
}
}