Merge "Refactor Subnet.isSubnetOf - reduce number of 'if' statements. Added unitests."
[controller.git] / opendaylight / switchmanager / api / src / main / java / org / opendaylight / controller / switchmanager / Subnet.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.HashSet;
16 import java.util.Set;
17
18 import org.opendaylight.controller.sal.core.NodeConnector;
19
20 /**
21  * The class describes subnet information including L3 address, vlan and set of
22  * ports associated with the subnet.
23  */
24 public class Subnet implements Cloneable, Serializable {
25     private static final long serialVersionUID = 1L;
26     // Key fields
27     private InetAddress networkAddress;
28     private short subnetMaskLength;
29     // Property fields
30     private short vlan;
31     private final Set<NodeConnector> nodeConnectors;
32
33     public Subnet(InetAddress ip, short maskLen, short vlan) {
34         this.networkAddress = ip;
35         this.subnetMaskLength = maskLen;
36         this.vlan = vlan;
37         this.nodeConnectors = new HashSet<NodeConnector>();
38     }
39
40     public Subnet(SubnetConfig conf) {
41         networkAddress = conf.getIPAddress();
42         subnetMaskLength = conf.getIPMaskLen();
43         nodeConnectors = conf.getNodeConnectors();
44     }
45
46     public Subnet(Subnet subnet) {
47         networkAddress = subnet.networkAddress;
48         subnetMaskLength = subnet.subnetMaskLength;
49         vlan = subnet.vlan;
50         nodeConnectors = new HashSet<NodeConnector>(subnet.nodeConnectors);
51     }
52
53     /**
54      * Add NodeConnectors to a subnet
55      *
56      * @param sp Set of NodeConnectors to add to the subnet
57      */
58     public void addNodeConnectors(Set<NodeConnector> sp) {
59         if (sp != null) {
60             this.nodeConnectors.addAll(sp);
61         }
62     }
63
64     /**
65      * Delete NodeConnectors from subnet
66      *
67      * @param sp Set of NodeConnectors to add to the subnet
68      */
69     public void deleteNodeConnectors(Set<NodeConnector> sp) {
70         if (sp == null) {
71             return;
72         }
73         for (NodeConnector p : sp) {
74             this.nodeConnectors.remove(p);
75         }
76     }
77
78     /**
79      * Return the list of NodeConnectors configured for this subnet,
80      * could be also an empty set in case of all the known
81      * nodeconnectors.
82      *
83      *
84      * @return The list of NodeConnectors attached to the subnet
85      */
86     public Set<NodeConnector> getNodeConnectors() {
87         return this.nodeConnectors;
88     }
89
90     /**
91      * If the subnet has no node connectors attached to it then it
92      * means that is a whole L2 flat domain
93      *
94      *
95      * @return true if there are no node connectors configured for the
96      * subnet else false
97      */
98     public boolean isFlatLayer2() {
99         return nodeConnectors.isEmpty();
100     }
101
102     /**
103      * getter method
104      *
105      *
106      * @return the Network Address part of the subnet
107      */
108     public InetAddress getNetworkAddress() {
109         return networkAddress;
110     }
111
112     /**
113      * @param networkAddress the networkAddress to set
114      */
115     public Subnet setNetworkAddress(InetAddress networkAddress) {
116         this.networkAddress = networkAddress;
117         return this;
118     }
119
120     /**
121      * getter method
122      *
123      *
124      * @return the subnet mask length
125      */
126     public short getSubnetMaskLength() {
127         return this.subnetMaskLength;
128     }
129
130     public Subnet setSubnetMaskLength(short m) {
131         this.subnetMaskLength = m;
132         return this;
133     }
134
135     /*
136      * returns the prefix of a given IP by applying this subnet's mask
137      */
138     private InetAddress getPrefixForAddress(InetAddress ip) {
139         int bytes = this.subnetMaskLength / 8;
140         int bits = this.subnetMaskLength % 8;
141         byte modifiedByte;
142         byte[] sn = ip.getAddress();
143         if (bits > 0) {
144             modifiedByte = (byte) (sn[bytes] >> (8 - bits));
145             sn[bytes] = (byte) (modifiedByte << (8 - bits));
146             bytes++;
147         }
148         for (; bytes < sn.length; bytes++) {
149             sn[bytes] = (byte) (0);
150         }
151         try {
152             return InetAddress.getByAddress(sn);
153         } catch (UnknownHostException e) {
154             return null;
155         }
156     }
157
158     public boolean isSubnetOf(InetAddress ip) {
159         if (ip == null) {
160             return false;
161         }
162         InetAddress thisPrefix = getPrefixForAddress(this.networkAddress);
163         InetAddress otherPrefix = getPrefixForAddress(ip);
164         boolean isSubnetOf = true;
165         if (((thisPrefix == null) || (otherPrefix == null)) || (!thisPrefix.equals(otherPrefix)) ) {
166             isSubnetOf = false;
167         }
168         return isSubnetOf;
169     }
170
171     public short getVlan() {
172         return this.vlan;
173     }
174
175     public Subnet setVlan(short i) {
176         this.vlan = i;
177         return this;
178     }
179
180     @Override
181     public int hashCode() {
182         final int prime = 31;
183         int result = 1;
184         result = prime * result
185                 + ((networkAddress == null) ? 0 : networkAddress.hashCode());
186         result = prime * result
187                 + ((nodeConnectors == null) ? 0 : nodeConnectors.hashCode());
188         result = prime * result + subnetMaskLength;
189         result = prime * result + vlan;
190         return result;
191     }
192
193     @Override
194     public boolean equals(Object obj) {
195         if (this == obj) {
196             return true;
197         }
198         if (obj == null) {
199             return false;
200         }
201         if (getClass() != obj.getClass()) {
202             return false;
203         }
204         Subnet other = (Subnet) obj;
205         if (networkAddress == null) {
206             if (other.networkAddress != null) {
207                 return false;
208             }
209         } else if (!networkAddress.equals(other.networkAddress)) {
210             return false;
211         }
212         if (nodeConnectors == null) {
213             if (other.nodeConnectors != null) {
214                 return false;
215             }
216         } else if (!nodeConnectors.equals(other.nodeConnectors)) {
217             return false;
218         }
219         if (subnetMaskLength != other.subnetMaskLength) {
220             return false;
221         }
222         if (vlan != other.vlan) {
223             return false;
224         }
225         return true;
226     }
227
228     /* (non-Javadoc)
229      * @see java.lang.Object#toString()
230      */
231     @Override
232     public String toString() {
233         return ("Subnet [networkAddress=" + networkAddress.getHostAddress()
234                 + "/" + subnetMaskLength
235                 + ((vlan == 0) ? "" : (", vlan=" + vlan)) + ", "
236                 + ((isFlatLayer2()) ? "{[*, *]}" : nodeConnectors.toString()) + "]");
237     }
238
239     public boolean hasNodeConnector(NodeConnector p) {
240         if (p == null) {
241             return false;
242         }
243         return isFlatLayer2() || nodeConnectors.contains(p);
244     }
245
246     public boolean isMutualExclusive(Subnet otherSubnet) {
247         if (this.networkAddress.getClass() != otherSubnet.networkAddress
248                 .getClass()) {
249             return true;
250         }
251         if (this.isSubnetOf(otherSubnet.getNetworkAddress())) {
252             return false;
253         }
254         if (otherSubnet.isSubnetOf(this.getNetworkAddress())) {
255             return false;
256         }
257         return true;
258     }
259
260     /**
261      * Implement clonable interface
262      */
263     @Override
264     public Subnet clone() {
265         return new Subnet(this);
266     }
267
268 }

©2013 OpenDaylight, A Linux Foundation Collaborative Project. All Rights Reserved.
OpenDaylight is a registered trademark of The OpenDaylight Project, Inc.
Linux Foundation and OpenDaylight are registered trademarks of the Linux Foundation.
Linux is a registered trademark of Linus Torvalds.