OpenDaylight Controller functional modules.
[controller.git] / opendaylight / switchmanager / src / main / java / org / opendaylight / controller / switchmanager / SubnetConfig.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.switchmanager;
11
12 import java.io.Serializable;
13 import java.lang.reflect.Field;
14 import java.net.Inet6Address;
15 import java.net.InetAddress;
16 import java.net.UnknownHostException;
17 import java.util.ArrayList;
18 import java.util.HashSet;
19 import java.util.List;
20 import java.util.Set;
21 import javax.xml.bind.annotation.XmlRootElement;
22 import javax.xml.bind.annotation.XmlAccessType;
23 import javax.xml.bind.annotation.XmlAccessorType;
24 import javax.xml.bind.annotation.XmlElement;
25 import javax.xml.bind.annotation.XmlAttribute;
26 import org.opendaylight.controller.sal.core.Node;
27 import org.opendaylight.controller.sal.core.NodeConnector;
28 import org.opendaylight.controller.sal.utils.GUIField;
29 import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
30
31 /**
32  * The class represents a subnet configuration.
33  */
34 @XmlRootElement
35 @XmlAccessorType(XmlAccessType.NONE)
36 public class SubnetConfig implements Serializable {
37     //static fields are by default excluded by Gson parser
38     private static final long serialVersionUID = 1L;
39     private static final String regexIP = "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
40             + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
41             + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
42             + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])[/](\\d|[12]\\d|3[0-2])$";
43     private static final String prettyFields[] = { GUIField.NAME.toString(),
44             GUIField.GATEWAYIP.toString(), GUIField.NODEPORTS.toString() };
45
46     // Order matters: JSP file expects following fields in the
47     // following order
48     @XmlAttribute
49     private String name;
50     @XmlAttribute
51     private String subnet; // A.B.C.D/MM  Where A.B.C.D is the Default
52                            // Gateway IP (L3) or ARP Querier IP (L2
53     @XmlElement
54     private List<String> nodePorts; // datapath ID/port list:
55                                     // xx:xx:xx:xx:xx:xx:xx:xx/a,b,c-m,r-t,y
56
57     public SubnetConfig() {
58     }
59
60     public SubnetConfig(String desc, String sub, List<String> sp) {
61         name = desc;
62         subnet = sub;
63         nodePorts = sp;
64     }
65
66     public String getName() {
67         return name;
68     }
69
70     public List<String> getNodePorts() {
71         return nodePorts;
72     }
73
74     public String getSubnet() {
75         return subnet;
76     }
77
78     public InetAddress getIPnum() {
79         InetAddress ip = null;
80         try {
81             ip = InetAddress.getByName(subnet.split("/")[0]);
82         } catch (UnknownHostException e1) {
83             return null;
84         }
85         return ip;
86     }
87
88     public Short getIPMaskLen() {
89         Short maskLen = 0;
90         if (hasValidIP()) {
91             String[] s = subnet.split("/");
92             maskLen = (s.length == 2) ? Short.valueOf(s[1]) : 32;
93         }
94         return maskLen;
95     }
96
97     public boolean isIPv6AddressValid() {
98         if (subnet == null)
99             return false;
100         String values[] = subnet.split("/");
101         try {
102             //when given an IP address, InetAddress.getByName validates the ip address
103             InetAddress addr = InetAddress.getByName(values[0]);
104             if (!(addr instanceof Inet6Address)) {
105                 return false;
106             }
107         } catch (UnknownHostException ex) {
108             return false;
109         }
110         if (values.length >= 2) {
111             int prefix = Integer.valueOf(values[1]);
112             if ((prefix < 0) || (prefix > 128)) {
113                 return false;
114             }
115         }
116         return true;
117     }
118
119     private Set<Short> getPortList(String ports) {
120         /*
121          * example:
122          *     ports = "1,3,5-12"
123          *     elemArray = ["1" "3" "5-12"]
124          *     elem[2] = "5-12" --> limits = ["5" "12"]
125          *     portList = [1 3 5 6 7 8 9 10 11 12]
126          */
127         Set<Short> portList = new HashSet<Short>();
128         String[] elemArray = ports.split(",");
129         for (String elem : elemArray) {
130             if (elem.contains("-")) {
131                 String[] limits = elem.split("-");
132                 for (short j = Short.valueOf(limits[0]); j <= Short
133                         .valueOf(limits[1]); j++) {
134                     portList.add(Short.valueOf(j));
135                 }
136             } else {
137                 portList.add(Short.valueOf(elem));
138             }
139         }
140         return portList;
141     }
142
143     private boolean hasValidIP() {
144         if (subnet != null) {
145             if (subnet.matches(regexIP)) {
146                 return true;
147             } else if (isIPv6AddressValid()) {
148                 return true;
149             }
150         }
151         return false;
152     }
153
154     private boolean hasValidPorts() {
155         for (String portSet : nodePorts) {
156             if (!portSet.contains("/")) {
157                 return false;
158             }
159         }
160         return true;
161     }
162
163     public boolean isValidSwitchPort(String sp) {
164         return sp.contains("/");
165     }
166
167     public boolean isValidConfig() {
168         return hasValidIP() && hasValidPorts();
169     }
170
171     @Override
172     public int hashCode() {
173         return name.hashCode();
174     }
175
176     @Override
177     public boolean equals(Object obj) {
178         /*
179          * Configuration will be stored in collection only if it is valid
180          * Hence we don't check here for uninitialized fields
181          */
182         if (this == obj)
183             return true;
184         if (obj == null)
185             return false;
186         if (getClass() != obj.getClass())
187             return false;
188         SubnetConfig that = (SubnetConfig) obj;
189         if (this.subnet.equals(that.subnet)) {
190             return true;
191         }
192         return false;
193     }
194
195     public static List<String> getFieldsNames() {
196         List<String> fieldList = new ArrayList<String>();
197         for (Field fld : SubnetConfig.class.getDeclaredFields()) {
198             fieldList.add(fld.getName());
199         }
200         //remove the four static fields
201         for (short i = 0; i < 3; i++) {
202             fieldList.remove(0);
203         }
204         return fieldList;
205     }
206
207     public static List<String> getGuiFieldsNames() {
208         List<String> fieldList = new ArrayList<String>();
209         for (String str : prettyFields) {
210             fieldList.add(str);
211         }
212         return fieldList;
213     }
214
215     //Utility method useful for adding to a passed Set all the
216     //NodeConnectors learnt from a string
217     private void getNodeConnectorsFromString(String codedNodeConnectors,
218             Set<NodeConnector> sp) {
219         if (codedNodeConnectors == null) {
220             return;
221         }
222         if (sp == null) {
223             return;
224         }
225         // codedNodeConnectors = xx:xx:xx:xx:xx:xx:xx:xx/a,b,c-m,r-t,y
226         String pieces[] = codedNodeConnectors.split("/");
227         for (Short port : getPortList(pieces[1])) {
228             Node n = Node.fromString(pieces[0]);
229             if (n == null) {
230                 continue;
231             }
232             NodeConnector p = NodeConnectorCreator.createOFNodeConnector(port,
233                     n);
234             if (p == null) {
235                 continue;
236             }
237             sp.add(p);
238         }
239     }
240
241     public Set<NodeConnector> getSubnetNodeConnectors() {
242         Set<NodeConnector> sp = new HashSet<NodeConnector>();
243         if (isGlobal())
244             return sp;
245         for (String str : nodePorts) {
246             getNodeConnectorsFromString(str, sp);
247         }
248         return sp;
249     }
250
251     public Set<NodeConnector> getNodeConnectors(String codedNodeConnectors) {
252         // codedNodeConnectors = xx:xx:xx:xx:xx:xx:xx:xx/a,b,c-m,r-t,y
253         Set<NodeConnector> sp = new HashSet<NodeConnector>();
254         getNodeConnectorsFromString(codedNodeConnectors, sp);
255         return sp;
256     }
257
258     public boolean isGlobal() {
259         // If no ports are specified to be part of the domain, then it's a global domain IP
260         return (nodePorts == null || nodePorts.isEmpty());
261     }
262
263     public void addNodeConnectors(String sp) {
264         nodePorts.add(sp);
265     }
266
267     public void removeNodeConnectors(String sp) {
268         nodePorts.remove(sp);
269     }
270
271     public String toString() {
272         return ("Subnet Config [Description=" + name + " Subnet=" + subnet
273                 + " NodeConnectors=" + nodePorts + "]");
274     }
275 }