Merge "Fix for cache cleanup in protocol plugin on container deletion"
[controller.git] / opendaylight / switchmanager / api / 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.net.InetAddress;
14 import java.net.UnknownHostException;
15 import java.util.ArrayList;
16 import java.util.List;
17 import java.util.Set;
18
19 import javax.xml.bind.annotation.XmlAccessType;
20 import javax.xml.bind.annotation.XmlAccessorType;
21 import javax.xml.bind.annotation.XmlElement;
22 import javax.xml.bind.annotation.XmlRootElement;
23
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 implements Cloneable, Serializable {
37     private static final long serialVersionUID = 1L;
38     private static final String prettyFields[] = { GUIField.NAME.toString(),
39             GUIField.GATEWAYIP.toString(), 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
48      * Gateway IP (L3) or ARP Querier IP (L2)
49      */
50     @XmlElement
51     private String subnet;
52     /**
53      * Set of node connectors in the format:
54      * Port Type|Port Id@Node Type|Node Id
55      */
56     @XmlElement
57     private List<String> nodeConnectors;
58
59     public SubnetConfig() {
60     }
61
62     public SubnetConfig(String name, String subnet, List<String> nodeConnectors) {
63         this.name = name;
64         this.subnet = subnet;
65         this.nodeConnectors = nodeConnectors;
66     }
67
68     public SubnetConfig(SubnetConfig subnetConfig) {
69         name = subnetConfig.name;
70         subnet = subnetConfig.subnet;
71         nodeConnectors = (subnetConfig.nodeConnectors == null) ? null : new ArrayList<String>(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         maskLen = (s.length == 2) ? Short.valueOf(s[1]) : 32;
100         return maskLen;
101     }
102
103     private Status validateSubnetAddress() {
104         if (!NetUtils.isIPAddressValid(subnet)) {
105             return new Status(StatusCode.BADREQUEST, String.format("Invalid Subnet configuration: Invalid address: %s", subnet));
106         }
107         byte[] bytePrefix = NetUtils.getSubnetPrefix(this.getIPAddress(), this.getIPMaskLen()).getAddress();
108         long prefix = BitBufferHelper.getLong(bytePrefix);
109         if (prefix == 0) {
110             return new Status(StatusCode.BADREQUEST, "Invalid network source address: subnet zero");
111         }
112         return new Status(StatusCode.SUCCESS);
113     }
114
115     public static Status validatePorts(List<String> nodeConnectors) {
116         if (nodeConnectors != null) {
117             for (String port : nodeConnectors) {
118                 if (null == NodeConnector.fromString(port)) {
119                     return new Status(StatusCode.BADREQUEST,
120                             "Invalid Subnet configuration: Not parsable node connector: " + port);
121                 }
122             }
123         }
124         return new Status(StatusCode.SUCCESS);
125     }
126
127     public Status validate() {
128         Status status = validateSubnetAddress();
129         if (status.isSuccess()) {
130             status = validatePorts(this.nodeConnectors);
131         }
132         return status;
133     }
134
135     public static List<String> getGuiFieldsNames() {
136         List<String> fieldList = new ArrayList<String>();
137         for (String str : prettyFields) {
138             fieldList.add(str);
139         }
140         return fieldList;
141     }
142
143     public Set<NodeConnector> getNodeConnectors() {
144         return NodeConnector.fromString(this.nodeConnectors);
145     }
146
147     public boolean isGlobal() {
148         // If no ports are specified to be part of the domain, then it's a global domain IP
149         return (nodeConnectors == null || nodeConnectors.isEmpty());
150     }
151
152     public void addNodeConnectors(List<String> nc) {
153         if (nc != null) {
154             if (nodeConnectors == null) {
155                 nodeConnectors = new ArrayList<String>(nc);
156             } else {
157                 nodeConnectors.addAll(nc);
158             }
159         }
160     }
161
162     public void removeNodeConnectors(List<String> nc) {
163         if (nc != null && nodeConnectors != null) {
164             nodeConnectors.removeAll(nc);
165         }
166     }
167
168     @Override
169     public String toString() {
170         return ("SubnetConfig [Name=" + name + ", Subnet=" + subnet
171                 + ", NodeConnectors=" + nodeConnectors + "]");
172     }
173
174     /**
175      * Implement clonable interface
176      */
177     @Override
178     public SubnetConfig clone() {
179         return new SubnetConfig(this);
180     }
181
182     @Override
183     public int hashCode() {
184         final int prime = 31;
185         int result = 1;
186         result = prime * result + ((name == null) ? 0 : name.hashCode());
187         result = prime * result + ((nodeConnectors == null) ? 0 : nodeConnectors.hashCode());
188         result = prime * result + ((subnet == null) ? 0 : subnet.hashCode());
189         return result;
190     }
191
192     @Override
193     public boolean equals(Object obj) {
194         if (this == obj) {
195             return true;
196         }
197         if (obj == null) {
198             return false;
199         }
200         if (getClass() != obj.getClass()) {
201             return false;
202         }
203         SubnetConfig other = (SubnetConfig) obj;
204         if (name == null) {
205             if (other.name != null) {
206                 return false;
207             }
208         } else if (!name.equals(other.name)) {
209             return false;
210         }
211         if (nodeConnectors == null) {
212             if (other.nodeConnectors != null) {
213                 return false;
214             }
215         } else if (!nodeConnectors.equals(other.nodeConnectors)) {
216             return false;
217         }
218         if (subnet == null) {
219             if (other.subnet != null) {
220                 return false;
221             }
222         } else if (!subnet.equals(other.subnet)) {
223             return false;
224         }
225         return true;
226     }
227 }