OpenDaylight Controller functional modules.
[controller.git] / opendaylight / forwarding / staticrouting / src / main / java / org / opendaylight / controller / forwarding / staticrouting / StaticRouteConfig.java
1
2 /*
3  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
4  *
5  * This program and the accompanying materials are made available under the
6  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
7  * and is available at http://www.eclipse.org/legal/epl-v10.html
8  */
9
10 package org.opendaylight.controller.forwarding.staticrouting;
11
12 import java.io.Serializable;
13 import java.lang.reflect.Field;
14 import java.net.InetAddress;
15 import java.net.UnknownHostException;
16 import java.util.ArrayList;
17 import java.util.HashMap;
18 import java.util.List;
19 import java.util.Map;
20
21 import org.apache.commons.lang3.builder.EqualsBuilder;
22 import org.apache.commons.lang3.builder.HashCodeBuilder;
23 import org.opendaylight.controller.sal.utils.GUIField;
24 import org.opendaylight.controller.sal.utils.Status;
25 import org.opendaylight.controller.sal.utils.StatusCode;
26
27 /**
28  * This class defines all the necessary configuration information for a static route.
29  */
30 public class StaticRouteConfig implements Serializable {
31     private static final long serialVersionUID = 1L;
32     private static final String regexSubnet = "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
33             + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
34             + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
35             + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])[/](\\d|[12]\\d|3[0-2])$";
36     private static final String regexIP = "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
37             + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
38             + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
39             + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])$";
40     private static final String regexDatapathID = "^([0-9a-fA-F]{1,2}[:-]){7}[0-9a-fA-F]{1,2}$";
41     private static final String regexDatapathIDLong = "^[0-9a-fA-F]{1,16}$";
42     private static final String prettyFields[] = { GUIField.NAME.toString(),
43             GUIField.STATICROUTE.toString(), GUIField.NEXTHOP.toString() };
44     private transient String nextHopType; // Ignoring NextHopType for now. Supporting just the next-hop IP-Address feature for now.
45     // Order matters: JSP file expects following fields in the following order
46     private String name;
47     private String staticRoute; // A.B.C.D/MM  Where A.B.C.D is the Default Gateway IP (L3) or ARP Querier IP (L2)
48     private String nextHop; // NextHop IP-Address (or) datapath ID/port list: xx:xx:xx:xx:xx:xx:xx:xx/a,b,c-m,r-t,y
49
50     /**
51      * Create a static route configuration  with no specific information.
52      */
53     public StaticRouteConfig() {
54         super();
55         nextHopType = StaticRoute.NextHopType.IPADDRESS.toString();
56     }
57
58     /**
59      * Create a static route configuration with all the information.
60      * @param name The name (String) of the static route config
61      * @param staticRoute The string representation of the route. e.g. 192.168.1.1/24
62      * @param nextHop The string representation of the next hop IP address. e.g. 10.10.1.1
63      */
64     public StaticRouteConfig(String name, String staticRoute, String nextHop) {
65         super();
66         this.name = name;
67         this.staticRoute = staticRoute;
68         this.nextHop = nextHop;
69     }
70
71     /**
72      * Get the name of the StaticRouteConfig.
73      * @return: The name
74      */
75     public String getName() {
76         return name;
77     }
78
79     /**
80      * Set the name of the StaticRouteConfig.
81      * @param name The name to set
82      */
83     public void setName(String name) {
84         this.name = name;
85     }
86
87     /**
88      * Get the string representation of the static route.
89      * @return The string representation of the static route
90      */
91     public String getStaticRoute() {
92         return staticRoute;
93     }
94
95     /**
96      * Set the static route of the StaticRouteConfig.
97      * @param staticRoute The string representation of the static route
98      */
99     public void setStaticRoute(String staticRoute) {
100         this.staticRoute = staticRoute;
101     }
102
103     /**
104      * Get the string representation of the next hop address type.
105      * @return The string representation of the next hop address type
106      */
107     public String getNextHopType() {
108         if (nextHopType == null)
109             return StaticRoute.NextHopType.IPADDRESS.toString();
110         return nextHopType;
111     }
112
113     /**
114      * Set the next hop address type.
115      * @param nextHopType The string representation of the next hop address type
116      */
117     public void setNextHopType(String nextHopType) {
118         this.nextHopType = nextHopType;
119     }
120
121     /**
122      * Get all the supported next hop address types.
123      * @return The list of supported next hop address types
124      */
125     public static List<String> getSupportedNextHopTypes() {
126         List<String> s = new ArrayList<String>();
127         for (StaticRoute.NextHopType nh : StaticRoute.NextHopType.values()) {
128             s.add(nh.toString());
129         }
130         return s;
131     }
132
133     /**
134      * Get the next hop address
135      * @return The string represenation of the next hop address
136      */
137     public String getNextHop() {
138         return nextHop;
139     }
140
141     /**
142      * Set the next hop address.
143      * @param nextHop: The string representation of the next hop address to be set
144      */
145     public void setNextHop(String nextHop) {
146         this.nextHop = nextHop;
147     }
148
149     /**
150      * Return a string with text indicating if the config is valid.
151      * @return SUCCESS if the config is valid
152      */
153     public Status isValid() {
154         if ((name == null) || (name.trim().length() < 1)) {
155             return new Status(StatusCode.BADREQUEST,
156                         "Invalid Static Route name");
157         }
158         if (!isValidStaticRouteEntry()) {
159             return new Status(StatusCode.BADREQUEST,
160                         "Invalid Static Route entry. Please use the " +
161                         "IPAddress/mask format. Default gateway " +
162                         "(0.0.0.0/0) is NOT supported.");
163         }
164         if (!isValidNextHop()) {
165             return new Status(StatusCode.BADREQUEST,
166                         "Invalid NextHop IP Address configuration. " +
167                                         "Please use the X.X.X.X format.");
168         }
169
170         return new Status(StatusCode.SUCCESS, null);
171     }
172
173     private boolean isValidAddress(String address) {
174         if ((address != null) && address.matches(regexIP)) {
175             return true;
176         }
177         return false;
178     }
179
180     private boolean isValidStaticRouteEntry() {
181         if ((staticRoute != null) && staticRoute.matches(regexSubnet)) {
182             return true;
183         }
184         return false;
185     }
186
187     private boolean isValidNextHop() {
188         if (getNextHopType().equalsIgnoreCase(
189                 StaticRoute.NextHopType.IPADDRESS.toString())) {
190             return isValidNextHopIP();
191         } else if (getNextHopType().equalsIgnoreCase(
192                 StaticRoute.NextHopType.SWITCHPORT.toString())) {
193             return isValidSwitchId();
194         }
195         return false;
196     }
197
198     private boolean isValidNextHopIP() {
199         return isValidAddress(nextHop);
200     }
201
202     private boolean isValidSwitchId(String switchId) {
203         return (switchId != null && (switchId.matches(regexDatapathID) || switchId
204                 .matches(regexDatapathIDLong)));
205     }
206
207     private boolean isValidSwitchId() {
208         if (getNextHopType().equalsIgnoreCase(
209                 StaticRoute.NextHopType.SWITCHPORT.toString())) {
210             String pieces[] = nextHop.split("/");
211             if (pieces.length < 2)
212                 return false;
213             return isValidSwitchId(pieces[0]);
214         }
215         return false;
216     }
217
218     /**
219      * Return the IP address of the static route.
220      * @return The IP address
221      */
222     public InetAddress getStaticRouteIP() {
223         if (!isValidStaticRouteEntry())
224             return null;
225         InetAddress ip = null;
226         try {
227             ip = InetAddress.getByName(staticRoute.split("/")[0]);
228         } catch (UnknownHostException e1) {
229             return null;
230         }
231         return ip;
232     }
233
234     /**
235      * Return the bit-mask length of the static route.
236      * @return The bit-mask length
237      */
238     public Short getStaticRouteMask() {
239         Short maskLen = 0;
240         if (isValidStaticRouteEntry()) {
241             String[] s = staticRoute.split("/");
242             maskLen = (s.length == 2) ? Short.valueOf(s[1]) : 32;
243         }
244         return maskLen;
245     }
246
247     /**
248      * Return the IP address of the next hop.
249      * @return the IP address
250      */
251     public InetAddress getNextHopIP() {
252         if ((getNextHopType()
253                 .equalsIgnoreCase(StaticRoute.NextHopType.IPADDRESS.toString()))
254                 && isValidNextHopIP()) {
255             InetAddress ip = null;
256             try {
257                 ip = InetAddress.getByName(nextHop);
258             } catch (UnknownHostException e1) {
259                 return null;
260             }
261             return ip;
262         }
263         return null;
264     }
265
266 /**
267  * Return the switch ID and the port ID of the next hop address.
268  * @return The switchID (Long) and PortID (Short) in the map
269  */
270     public Map<Long, Short> getNextHopSwitchPorts() {
271         // codedSwitchPorts = xx:xx:xx:xx:xx:xx:xx:xx/port-number
272         if (getNextHopType().equalsIgnoreCase(
273                 StaticRoute.NextHopType.SWITCHPORT.toString())) {
274             Map<Long, Short> sp = new HashMap<Long, Short>(1);
275             String pieces[] = nextHop.split("/");
276             sp.put(getSwitchIDLong(pieces[0]), Short.valueOf(pieces[1]));
277             return sp;
278         }
279         return null;
280     }
281
282     private long getSwitchIDLong(String switchId) {
283         int radix = 16;
284         String switchString = "0";
285
286         if (isValidSwitchId(switchId)) {
287             if (switchId.contains(":")) {
288                 // Handle the 00:00:AA:BB:CC:DD:EE:FF notation
289                 switchString = switchId.replace(":", "");
290             } else if (switchId.contains("-")) {
291                 // Handle the 00-00-AA-BB-CC-DD-EE-FF notation
292                 switchString = switchId.replace("-", "");
293             } else {
294                 // Handle the 0123456789ABCDEF notation
295                 switchString = switchId;
296             }
297         }
298         return Long.parseLong(switchString, radix);
299     }
300
301     /**
302      * Return all the field names of the config.
303      * @return The list containing all the field names
304      */
305     public static List<String> getFieldsNames() {
306         List<String> fieldList = new ArrayList<String>();
307         for (Field fld : StaticRouteConfig.class.getDeclaredFields()) {
308             fieldList.add(fld.getName());
309         }
310         //remove the 6 static fields + NextHopType
311         for (short i = 0; i < 7; i++) {
312             fieldList.remove(0);
313         }
314         return fieldList;
315     }
316
317     /**
318      * Return all the GUI field names of the config.
319      * @return The list containing all the GUI field names
320      */
321     public static List<String> getGuiFieldsNames() {
322         List<String> fieldList = new ArrayList<String>();
323         for (String str : prettyFields) {
324             fieldList.add(str);
325         }
326         return fieldList;
327     }
328
329     @Override
330     public int hashCode() {
331         return HashCodeBuilder.reflectionHashCode(this);
332     }
333
334     @Override
335     public boolean equals(Object obj) {
336         return EqualsBuilder.reflectionEquals(this, obj);
337     }
338
339     @Override
340     public String toString() {
341         return "StaticRouteConfig [name=" + name + ", staticRoute="
342                 + staticRoute + ", nextHopType=" + nextHopType + ", nextHop="
343                 + nextHop + "]";
344     }
345 }