blob: e1075dff045c068e60aa8c2f73c6136005f25c89 [file] [log] [blame]
Pier Luigi Ventred1173a12016-03-30 15:51:03 +02001/*
Pier Luigi Ventre0a023f42016-04-30 11:03:15 +02002 * Copyright 2016-present Open Networking Laboratory
Pier Luigi Ventred1173a12016-03-30 15:51:03 +02003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.sdxl2;
18
19import com.google.common.base.MoreObjects;
20import org.onlab.packet.MacAddress;
21import org.onlab.packet.VlanId;
22import org.onosproject.net.ConnectPoint;
23
24import java.util.ArrayList;
25import java.util.List;
26import java.util.Objects;
Carolina Fernandezad893432016-07-18 11:11:34 +020027import java.util.regex.Matcher;
28import java.util.regex.Pattern;
Pier Luigi Ventred1173a12016-03-30 15:51:03 +020029
30import static com.google.common.base.Preconditions.*;
31
32/**
Carolina Fernandezad893432016-07-18 11:11:34 +020033 * SDX-L2 Connection Point expressed as composition of a:
34 * Connect Point; set of VLAN ids; MAC address (optional).
Pier Luigi Ventred1173a12016-03-30 15:51:03 +020035 */
36public class SdxL2ConnectionPoint {
37
Carolina Fernandezad893432016-07-18 11:11:34 +020038 private static final String ERROR_INVALID_VLAN = "Provide VLAN with at least value '-1' or '1'";
Pier Luigi Ventred1173a12016-03-30 15:51:03 +020039 private final ConnectPoint cPoint;
40 private final List<VlanId> vlanIds;
41 private final MacAddress ceMac;
Carolina Fernandezad893432016-07-18 11:11:34 +020042 private String name;
Pier Luigi Ventred1173a12016-03-30 15:51:03 +020043
44 /**
Carolina Fernandezad893432016-07-18 11:11:34 +020045 * Creates a new SDX-L2 Connection Point.
Pier Luigi Ventred1173a12016-03-30 15:51:03 +020046 *
pierventre3849e562016-05-11 11:47:32 +020047 * @param name SDX-L2 connection point name
48 * @param cPoint connect point
49 * @param vlans the customer edge VLANs
50 * @param ceMac the customer edge router MAC address
Pier Luigi Ventred1173a12016-03-30 15:51:03 +020051 */
52 public SdxL2ConnectionPoint(String name, ConnectPoint cPoint, List<VlanId> vlans, MacAddress ceMac) {
53 this.name = name;
54 this.cPoint = cPoint;
55 this.vlanIds = vlans;
56 this.ceMac = ceMac;
57 }
58
59 /**
Carolina Fernandezad893432016-07-18 11:11:34 +020060 * Parses a device Connection Point from a string, set of VLANs
61 * from a string and MAC from a string.
62 * The connect point should be in the format "deviceUri/portNumber".
63 * The vlans should be in the format "vlan1,vlan2,vlan3"
64 * The mac address should be in hex
Pier Luigi Ventred1173a12016-03-30 15:51:03 +020065 *
Carolina Fernandezad893432016-07-18 11:11:34 +020066 * @param name name of the SDX-L2 Connection Point
67 * @param connectPoint Connection Point to parse
68 * @param vlans VLAN IDs to parse
69 * @param mac MAC address to parse
70 * @return a Connection Point based on the information in the string
71 *
72 */
73 public static SdxL2ConnectionPoint sdxl2ConnectionPoint(
74 String name, String connectPoint, String vlans, String mac) {
75 checkNotNull(connectPoint);
76 enforceNameFormat(name);
77 ConnectPoint connectionPoint = ConnectPoint.deviceConnectPoint(connectPoint);
78 List<VlanId> vlansList = enforceVlans(vlans);
79 MacAddress macAddress = MacAddress.ZERO;
80 if (mac != null) {
81 macAddress = MacAddress.valueOf(mac);
82 }
83 return new SdxL2ConnectionPoint(name, connectionPoint, vlansList, macAddress);
84 }
85
86 /**
87 * Parses a device Connection Point from a string and set of
88 * VLANs from a string.
89 * The Connection Point should be in the format "deviceUri/portNumber".
90 * The VLANs should be in the format "vlan1,vlan2,vlan3"
91 *
92 * @param name name of the SDX-L2 CP
93 * @param connectPoint Connection Point to parse
94 * @param vlans VLAN IDs to parse
95 * @return a Connection Point based on the information in the string
96 *
97 */
98 public static SdxL2ConnectionPoint sdxl2ConnectionPoint(
99 String name, String connectPoint, String vlans) {
100 return sdxl2ConnectionPoint(name, connectPoint, vlans, null);
101 }
102
103 /**
104 * Enforces proper format on the name of the Connection Point.
105 *
106 * @param name name of the SDX-L2 Connection Point
107 */
108 private static void enforceNameFormat(String name) {
109 checkState(!(name.contains(",") ||
110 name.contains("-") ||
111 name.contains("vlanid=") ||
112 name.contains("ConnectPoint{") ||
113 name.contains("elementId=") ||
114 name.contains("portNumber=") ||
115 name.contains("{") ||
116 name.contains("}") ||
117 name.contains("|")), "Names cannot contain some special characters");
118 }
119
120 /**
121 * Enforces proper format on the requested VLANs.
122 *
123 * @param vlans VLANs expressed explicitly, as a range or in combination
124 * @return a list of VLANs to be added
125 */
126 private static List<VlanId> enforceVlans(String vlans) {
127 String[] splitted = parseVlans(vlans);
128 List<VlanId> vlansList = new ArrayList<>();
129 for (String vlan : splitted) {
130 short vlanNumber = Short.parseShort(vlan);
131 if (!vlansList.contains(VlanId.vlanId(vlanNumber)) &&
132 Short.parseShort(vlan) != -1 &&
133 Short.parseShort(vlan) != 1 &&
134 Short.parseShort(vlan) >= 0 &&
135 Short.parseShort(vlan) != 4095) {
136 vlansList.add(VlanId.vlanId(vlanNumber));
137 }
138 }
139 return vlansList;
140 }
141
142 /**
143 * Parses the VLANs requested by the user.
144 *
145 * @param vlans VLANs expressed explicitly, as a range or in combination
146 * @return an array of VLANs to add
147 */
148 private static String[] parseVlans(String vlans) {
149 if (vlans == null) {
150 vlans = "-1";
151 }
152 ArrayList<String> vlanRange = new ArrayList<String>();
153 String[] splittedVlans;
154 String commaSeparator = ",";
155 if (vlans.contains(commaSeparator)) {
156 splittedVlans = vlans.split(commaSeparator);
157 for (String vlan : splittedVlans) {
158 vlanRange.addAll(generateNumberRange(vlan));
159 }
160 } else {
161 vlanRange.addAll(generateNumberRange(vlans));
162 }
163 splittedVlans = new String[vlanRange.size()];
164 splittedVlans = vlanRange.toArray(splittedVlans);
165 return splittedVlans;
166 }
167
168 /**
169 * Generates a range of numbers, given a string of type "X-Y" ("%d-%d").
170 *
171 * @param range range of numbers to compute
172 * @return a list with numbers between "X" and "Y" (inclusive)
173 */
174 private static ArrayList<String> generateNumberRange(String range) {
175 ArrayList<String> parsedNumbers = new ArrayList<String>();
176 Pattern p = Pattern.compile("(\\d+)-(\\d+)");
177 Matcher m = p.matcher(range);
178 if (m.matches()) {
179 int start = Integer.parseInt(m.group(1));
180 int end = Integer.parseInt(m.group(2));
181 int min = Math.min(start, end);
182 int max = Math.max(start, end);
183 for (int v = min; v <= max; v++) {
184 parsedNumbers.add(Integer.toString(v));
185 }
186 } else {
187 parsedNumbers.add(range);
188 }
189 return parsedNumbers;
190 }
191
192 /**
193 * Returns the name of SDX-L2 Connection Point.
194 *
195 * @return a string representing the name of Connection Point
Pier Luigi Ventred1173a12016-03-30 15:51:03 +0200196 */
197 public String name() {
198 return name;
199 }
200
201 /**
Carolina Fernandezad893432016-07-18 11:11:34 +0200202 * Returns the Connection Point.
Pier Luigi Ventred1173a12016-03-30 15:51:03 +0200203 *
Carolina Fernandezad893432016-07-18 11:11:34 +0200204 * @return Connection Point object
Pier Luigi Ventred1173a12016-03-30 15:51:03 +0200205 */
206 public ConnectPoint connectPoint() {
207 return cPoint;
208 }
209
210 /**
pierventre3849e562016-05-11 11:47:32 +0200211 * Returns the set of VLANs that are used by the customer edge.
Pier Luigi Ventred1173a12016-03-30 15:51:03 +0200212 *
pierventre3849e562016-05-11 11:47:32 +0200213 * @return a set of VLAN ids
Pier Luigi Ventred1173a12016-03-30 15:51:03 +0200214 */
215 public List<VlanId> vlanIds() {
216 return vlanIds;
217 }
218
219 /**
pierventre3849e562016-05-11 11:47:32 +0200220 * Returns the customer edge MAC address.
Pier Luigi Ventred1173a12016-03-30 15:51:03 +0200221 *
pierventre3849e562016-05-11 11:47:32 +0200222 * @return a MAC address object
Pier Luigi Ventred1173a12016-03-30 15:51:03 +0200223 */
224 public MacAddress macAddress() {
225 return ceMac;
226 }
227
Pier Luigi Ventred1173a12016-03-30 15:51:03 +0200228 @Override
229 public int hashCode() {
230 return Objects.hash(name, cPoint, vlanIds, ceMac);
231 }
232
233 @Override
234 public boolean equals(Object obj) {
235 if (this == obj) {
236 return true;
237 }
238 if (obj instanceof SdxL2ConnectionPoint) {
239 final SdxL2ConnectionPoint other = (SdxL2ConnectionPoint) obj;
240 return Objects.equals(this.name, other.name) &&
241 Objects.equals(this.cPoint, other.cPoint) &&
242 Objects.equals(this.vlanIds, other.vlanIds) &&
243 Objects.equals(this.ceMac, other.ceMac);
244 }
245 return false;
246 }
247
248 @Override
249 public String toString() {
250 return MoreObjects.toStringHelper(this)
251 .add("name", name)
252 .add("connectionPoint", cPoint)
253 .add("vlanIds", vlanIds)
254 .add("ceMac", ceMac)
255 .toString();
256 }
257}