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