Make sure invokeOperation is set once
[controller.git] / opendaylight / adsal / switchmanager / api / src / main / java / org / opendaylight / controller / switchmanager / SubnetConfig.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.controller.switchmanager;
10
11 import java.io.Serializable;
12 import java.net.InetAddress;
13 import java.net.UnknownHostException;
14 import java.util.ArrayList;
15 import java.util.List;
16 import java.util.Set;
17
18 import javax.xml.bind.annotation.XmlAccessType;
19 import javax.xml.bind.annotation.XmlAccessorType;
20 import javax.xml.bind.annotation.XmlElement;
21 import javax.xml.bind.annotation.XmlRootElement;
22
23 import org.opendaylight.controller.configuration.ConfigurationObject;
24 import org.opendaylight.controller.sal.core.NodeConnector;
25 import org.opendaylight.controller.sal.packet.BitBufferHelper;
26 import org.opendaylight.controller.sal.utils.GUIField;
27 import org.opendaylight.controller.sal.utils.NetUtils;
28 import org.opendaylight.controller.sal.utils.Status;
29 import org.opendaylight.controller.sal.utils.StatusCode;
30
31 /**
32  * The class represents a subnet configuration.
33  */
34 @XmlRootElement
35 @XmlAccessorType(XmlAccessType.NONE)
36 public class SubnetConfig extends ConfigurationObject implements Cloneable, Serializable {
37     private static final long serialVersionUID = 1L;
38     private static final String prettyFields[] = { GUIField.NAME.toString(), GUIField.GATEWAYIP.toString(),
39             GUIField.NODEPORTS.toString() };
40
41     /**
42      * Name of the subnet
43      */
44     @XmlElement
45     private String name;
46     /**
47      * A.B.C.D/MM Where A.B.C.D is the Default Gateway IP (L3) or ARP Querier IP
48      * (L2)
49      */
50     @XmlElement
51     private String subnet;
52     /**
53      * Set of node connectors in the format: Port Type|Port Id@Node Type|Node Id
54      */
55     @XmlElement
56     private List<String> nodeConnectors;
57
58     public SubnetConfig() {
59     }
60
61     public SubnetConfig(String name, String subnet, List<String> nodeConnectors) {
62         this.name = name;
63         this.subnet = subnet;
64         this.nodeConnectors = nodeConnectors;
65     }
66
67     public SubnetConfig(SubnetConfig subnetConfig) {
68         name = subnetConfig.name;
69         subnet = subnetConfig.subnet;
70         nodeConnectors = (subnetConfig.nodeConnectors == null) ? null : new ArrayList<String>(
71                 subnetConfig.nodeConnectors);
72     }
73
74     public String getName() {
75         return name;
76     }
77
78     public List<String> getNodePorts() {
79         return (nodeConnectors == null) ? new ArrayList<String>(0) : new ArrayList<String>(nodeConnectors);
80     }
81
82     public String getSubnet() {
83         return subnet;
84     }
85
86     public InetAddress getIPAddress() {
87         InetAddress ip = null;
88         try {
89             ip = InetAddress.getByName(subnet.split("/")[0]);
90         } catch (UnknownHostException e1) {
91             return null;
92         }
93         return ip;
94     }
95
96     public Short getIPMaskLen() {
97         Short maskLen = 0;
98         String[] s = subnet.split("/");
99
100         try {
101             maskLen = (s.length == 2) ? Short.valueOf(s[1]) : 32;
102         } catch (NumberFormatException e) {
103             maskLen = 32;
104         }
105         return maskLen;
106     }
107
108     private Status validateSubnetAddress() {
109         if (!NetUtils.isIPAddressValid(subnet)) {
110             return new Status(StatusCode.BADREQUEST, String.format("Invalid Subnet configuration: Invalid address: %s",
111                     subnet));
112         }
113         if ((this.getIPMaskLen() == 0) || (this.getIPMaskLen() == 32)) {
114             return new Status(StatusCode.BADREQUEST, String.format("Invalid Subnet configuration: Invalid mask: /%s",
115                     this.getIPMaskLen()));
116         }
117
118         //checks that address doesn't start with 0 or 255
119         String address = subnet.split("/")[0];
120         if (address.startsWith("0.") || address.startsWith("255.")) {
121             return  new Status(StatusCode.BADREQUEST, String.format("Invalid Subnet configuration: Invalid address: %s", address));
122         }
123
124         byte[] bytePrefix = NetUtils.getSubnetPrefix(this.getIPAddress(), this.getIPMaskLen()).getAddress();
125         long prefix = BitBufferHelper.getLong(bytePrefix);
126         if (prefix == 0) {
127             return new Status(StatusCode.BADREQUEST, "Invalid network source address: subnet zero");
128         }
129
130         //check that host is not set to all 0's or 1's
131         long hostAddress = BitBufferHelper.getLong(this.getIPAddress().getAddress()) - prefix;
132         if (hostAddress == 0 || hostAddress == Math.pow(2, 32-this.getIPMaskLen()) - 1) {
133             return new Status(StatusCode.BADREQUEST, String.format("Invalid subnet gateway address: /%s", subnet));
134         }
135
136         return new Status(StatusCode.SUCCESS);
137     }
138
139     public static Status validatePorts(List<String> nodeConnectors) {
140         if (nodeConnectors != null) {
141             for (String port : nodeConnectors) {
142                 if (null == NodeConnector.fromString(port)) {
143                     return new Status(StatusCode.BADREQUEST,
144                             "Invalid Subnet configuration: Not parsable node connector: " + port);
145                 }
146             }
147         }
148         return new Status(StatusCode.SUCCESS);
149     }
150
151     private Status validateName() {
152         if (!isValidResourceName(name)) {
153             return new Status(StatusCode.BADREQUEST, "Invalid name");
154         }
155         return new Status(StatusCode.SUCCESS);
156     }
157
158     public Status validate() {
159         Status status = validateName();
160         if (status.isSuccess()) {
161             status = validateSubnetAddress();
162             if (status.isSuccess()) {
163                 status = validatePorts(this.nodeConnectors);
164             }
165         }
166         return status;
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     public Set<NodeConnector> getNodeConnectors() {
178         return NodeConnector.fromString(this.nodeConnectors);
179     }
180
181     public boolean isGlobal() {
182         // If no ports are specified to be part of the domain, then it's a
183         // global domain IP
184         return (nodeConnectors == null || nodeConnectors.isEmpty());
185     }
186
187     public void addNodeConnectors(List<String> nc) {
188         if (nc != null) {
189             if (nodeConnectors == null) {
190                 nodeConnectors = new ArrayList<String>(nc);
191             } else {
192                 nodeConnectors.addAll(nc);
193             }
194         }
195     }
196
197     public void removeNodeConnectors(List<String> nc) {
198         if (nc != null && nodeConnectors != null) {
199             nodeConnectors.removeAll(nc);
200         }
201     }
202
203     @Override
204     public String toString() {
205         return ("SubnetConfig [Name=" + name + ", Subnet=" + subnet + ", NodeConnectors=" + nodeConnectors + "]");
206     }
207
208     /**
209      * Implement clonable interface
210      */
211     @Override
212     public SubnetConfig clone() {
213         return new SubnetConfig(this);
214     }
215
216     @Override
217     public int hashCode() {
218         final int prime = 31;
219         int result = 1;
220         result = prime * result + ((name == null) ? 0 : name.hashCode());
221         result = prime * result + ((nodeConnectors == null) ? 0 : nodeConnectors.hashCode());
222         result = prime * result + ((subnet == null) ? 0 : subnet.hashCode());
223         return result;
224     }
225
226     @Override
227     public boolean equals(Object obj) {
228         if (this == obj) {
229             return true;
230         }
231         if (obj == null) {
232             return false;
233         }
234         if (getClass() != obj.getClass()) {
235             return false;
236         }
237         SubnetConfig other = (SubnetConfig) obj;
238         if (name == null) {
239             if (other.name != null) {
240                 return false;
241             }
242         } else if (!name.equals(other.name)) {
243             return false;
244         }
245         if (nodeConnectors == null) {
246             if (other.nodeConnectors != null) {
247                 return false;
248             }
249         } else if (!nodeConnectors.equals(other.nodeConnectors)) {
250             return false;
251         }
252         if (subnet == null) {
253             if (other.subnet != null) {
254                 return false;
255             }
256         } else if (!subnet.equals(other.subnet)) {
257             return false;
258         }
259         return true;
260     }
261 }