BUG-2218: Keep existing link augmentations during discovery process
[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.opendaylight.controller.configuration.ConfigurationObject;
22 import org.opendaylight.controller.sal.utils.GUIField;
23 import org.opendaylight.controller.sal.utils.Status;
24 import org.opendaylight.controller.sal.utils.StatusCode;
25
26 /**
27  * This class defines all the necessary configuration information for a static route.
28  */
29 public class StaticRouteConfig extends ConfigurationObject implements Serializable {
30     private static final long serialVersionUID = 1L;
31     private static final String regexSubnet = "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
32             + "([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])[/](\\d|[12]\\d|3[0-2])$";
35     private static final String regexIP = "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
36             + "([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     private static final String regexDatapathID = "^([0-9a-fA-F]{1,2}[:-]){7}[0-9a-fA-F]{1,2}$";
40     private static final String regexDatapathIDLong = "^[0-9a-fA-F]{1,16}$";
41     private static final String prettyFields[] = { GUIField.NAME.toString(),
42             GUIField.STATICROUTE.toString(), GUIField.NEXTHOP.toString() };
43     private transient String nextHopType; // Ignoring NextHopType for now. Supporting just the next-hop IP-Address feature for now.
44     // Order matters: JSP file expects following fields in the following order
45     private String name;
46     private String staticRoute; // A.B.C.D/MM  Where A.B.C.D is the Default Gateway IP (L3) or ARP Querier IP (L2)
47     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
48
49     /**
50      * Create a static route configuration  with no specific information.
51      */
52     public StaticRouteConfig() {
53         super();
54         nextHopType = StaticRoute.NextHopType.IPADDRESS.toString();
55     }
56
57     /**
58      * Create a static route configuration with all the information.
59      * @param name The name (String) of the static route config
60      * @param staticRoute The string representation of the route. e.g. 192.168.1.1/24
61      * @param nextHop The string representation of the next hop IP address. e.g. 10.10.1.1
62      */
63     public StaticRouteConfig(String name, String staticRoute, String nextHop) {
64         super();
65         this.name = name;
66         this.staticRoute = staticRoute;
67         this.nextHop = nextHop;
68     }
69
70     /**
71      * Get the name of the StaticRouteConfig.
72      * @return: The name
73      */
74     public String getName() {
75         return name;
76     }
77
78     /**
79      * Set the name of the StaticRouteConfig.
80      * @param name The name to set
81      */
82     public void setName(String name) {
83         this.name = name;
84     }
85
86     /**
87      * Get the string representation of the static route.
88      * @return The string representation of the static route
89      */
90     public String getStaticRoute() {
91         return staticRoute;
92     }
93
94     /**
95      * Set the static route of the StaticRouteConfig.
96      * @param staticRoute The string representation of the static route
97      */
98     public void setStaticRoute(String staticRoute) {
99         this.staticRoute = staticRoute;
100     }
101
102     /**
103      * Get the string representation of the next hop address type.
104      * @return The string representation of the next hop address type
105      */
106     public String getNextHopType() {
107         if (nextHopType == null) {
108             return StaticRoute.NextHopType.IPADDRESS.toString();
109         }
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 (!isValidResourceName(name)) {
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             }
214             return isValidSwitchId(pieces[0]);
215         }
216         return false;
217     }
218
219     /**
220      * Return the IP address of the static route.
221      * @return The IP address
222      */
223     public InetAddress getStaticRouteIP() {
224         if (!isValidStaticRouteEntry()) {
225             return null;
226         }
227         InetAddress ip = null;
228         try {
229             ip = InetAddress.getByName(staticRoute.split("/")[0]);
230         } catch (UnknownHostException e1) {
231             return null;
232         }
233         return ip;
234     }
235
236     /**
237      * Return the bit-mask length of the static route.
238      * @return The bit-mask length
239      */
240     public Short getStaticRouteMask() {
241         Short maskLen = 0;
242         if (isValidStaticRouteEntry()) {
243             String[] s = staticRoute.split("/");
244             maskLen = (s.length == 2) ? Short.valueOf(s[1]) : 32;
245         }
246         return maskLen;
247     }
248
249     /**
250      * Return the IP address of the next hop.
251      * @return the IP address
252      */
253     public InetAddress getNextHopIP() {
254         if ((getNextHopType()
255                 .equalsIgnoreCase(StaticRoute.NextHopType.IPADDRESS.toString()))
256                 && isValidNextHopIP()) {
257             InetAddress ip = null;
258             try {
259                 ip = InetAddress.getByName(nextHop);
260             } catch (UnknownHostException e1) {
261                 return null;
262             }
263             return ip;
264         }
265         return null;
266     }
267
268 /**
269  * Return the switch ID and the port ID of the next hop address.
270  * @return The switchID (Long) and PortID (Short) in the map
271  */
272     public Map<Long, Short> getNextHopSwitchPorts() {
273         // codedSwitchPorts = xx:xx:xx:xx:xx:xx:xx:xx/port-number
274         if (getNextHopType().equalsIgnoreCase(
275                 StaticRoute.NextHopType.SWITCHPORT.toString())) {
276             Map<Long, Short> sp = new HashMap<Long, Short>(1);
277             String pieces[] = nextHop.split("/");
278             sp.put(getSwitchIDLong(pieces[0]), Short.valueOf(pieces[1]));
279             return sp;
280         }
281         return null;
282     }
283
284     private long getSwitchIDLong(String switchId) {
285         int radix = 16;
286         String switchString = "0";
287
288         if (isValidSwitchId(switchId)) {
289             if (switchId.contains(":")) {
290                 // Handle the 00:00:AA:BB:CC:DD:EE:FF notation
291                 switchString = switchId.replace(":", "");
292             } else if (switchId.contains("-")) {
293                 // Handle the 00-00-AA-BB-CC-DD-EE-FF notation
294                 switchString = switchId.replace("-", "");
295             } else {
296                 // Handle the 0123456789ABCDEF notation
297                 switchString = switchId;
298             }
299         }
300         return Long.parseLong(switchString, radix);
301     }
302
303     /**
304      * Return all the field names of the config.
305      * @return The list containing all the field names
306      */
307     public static List<String> getFieldsNames() {
308         List<String> fieldList = new ArrayList<String>();
309         for (Field fld : StaticRouteConfig.class.getDeclaredFields()) {
310             fieldList.add(fld.getName());
311         }
312         //remove the 6 static fields + NextHopType
313         for (short i = 0; i < 7; i++) {
314             fieldList.remove(0);
315         }
316         return fieldList;
317     }
318
319     /**
320      * Return all the GUI field names of the config.
321      * @return The list containing all the GUI field names
322      */
323     public static List<String> getGuiFieldsNames() {
324         List<String> fieldList = new ArrayList<String>();
325         for (String str : prettyFields) {
326             fieldList.add(str);
327         }
328         return fieldList;
329     }
330
331     @Override
332     public int hashCode() {
333         final int prime = 31;
334         int result = 1;
335         result = prime * result + ((name == null) ? 0 : name.hashCode());
336         result = prime * result + ((nextHop == null) ? 0 : nextHop.hashCode());
337         result = prime * result
338                 + ((staticRoute == null) ? 0 : staticRoute.hashCode());
339         return result;
340     }
341
342     @Override
343     public boolean equals(Object obj) {
344         if (this == obj) {
345             return true;
346         }
347         if (obj == null) {
348             return false;
349         }
350         if (getClass() != obj.getClass()) {
351             return false;
352         }
353         StaticRouteConfig other = (StaticRouteConfig) obj;
354         if (name == null) {
355             if (other.name != null) {
356                 return false;
357             }
358         } else if (!name.equals(other.name)) {
359             return false;
360         }
361         if (nextHop == null) {
362             if (other.nextHop != null) {
363                 return false;
364             }
365         } else if (!nextHop.equals(other.nextHop)) {
366             return false;
367         }
368         if (staticRoute == null) {
369             if (other.staticRoute != null) {
370                 return false;
371             }
372         } else if (!staticRoute.equals(other.staticRoute)) {
373             return false;
374         }
375         return true;
376     }
377
378     @Override
379     public String toString() {
380         return "StaticRouteConfig [name=" + name + ", staticRoute="
381                 + staticRoute + ", nextHopType=" + nextHopType + ", nextHop="
382                 + nextHop + "]";
383     }
384 }