Implemented adding and removing address bindings in the store, along with unit tests.
Showing
3 changed files
with
217 additions
and
11 deletions
1 | package org.onlab.onos.net.host; | 1 | package org.onlab.onos.net.host; |
2 | 2 | ||
3 | +import java.util.Collections; | ||
3 | import java.util.HashSet; | 4 | import java.util.HashSet; |
5 | +import java.util.Objects; | ||
4 | import java.util.Set; | 6 | import java.util.Set; |
5 | 7 | ||
6 | import org.onlab.onos.net.ConnectPoint; | 8 | import org.onlab.onos.net.ConnectPoint; |
... | @@ -29,7 +31,7 @@ public class PortAddresses { | ... | @@ -29,7 +31,7 @@ public class PortAddresses { |
29 | public PortAddresses(ConnectPoint connectPoint, | 31 | public PortAddresses(ConnectPoint connectPoint, |
30 | Set<IpPrefix> ips, MacAddress mac) { | 32 | Set<IpPrefix> ips, MacAddress mac) { |
31 | this.connectPoint = connectPoint; | 33 | this.connectPoint = connectPoint; |
32 | - this.ipAddresses = (ips == null) ? null : new HashSet<>(ips); | 34 | + this.ipAddresses = (ips == null) ? Collections.<IpPrefix>emptySet() : new HashSet<>(ips); |
33 | this.macAddress = mac; | 35 | this.macAddress = mac; |
34 | } | 36 | } |
35 | 37 | ||
... | @@ -60,4 +62,25 @@ public class PortAddresses { | ... | @@ -60,4 +62,25 @@ public class PortAddresses { |
60 | return macAddress; | 62 | return macAddress; |
61 | } | 63 | } |
62 | 64 | ||
65 | + @Override | ||
66 | + public boolean equals(Object other) { | ||
67 | + if (this == other) { | ||
68 | + return true; | ||
69 | + } | ||
70 | + | ||
71 | + if (!(other instanceof PortAddresses)) { | ||
72 | + return false; | ||
73 | + } | ||
74 | + | ||
75 | + PortAddresses otherPa = (PortAddresses) other; | ||
76 | + | ||
77 | + return Objects.equals(this.connectPoint, otherPa.connectPoint) | ||
78 | + && Objects.equals(this.ipAddresses, otherPa.ipAddresses) | ||
79 | + && Objects.equals(this.macAddress, otherPa.macAddress); | ||
80 | + } | ||
81 | + | ||
82 | + @Override | ||
83 | + public int hashCode() { | ||
84 | + return Objects.hash(connectPoint, ipAddresses, macAddress); | ||
85 | + } | ||
63 | } | 86 | } | ... | ... |
... | @@ -2,9 +2,13 @@ package org.onlab.onos.net.host.impl; | ... | @@ -2,9 +2,13 @@ package org.onlab.onos.net.host.impl; |
2 | 2 | ||
3 | import static org.junit.Assert.assertEquals; | 3 | import static org.junit.Assert.assertEquals; |
4 | import static org.junit.Assert.assertFalse; | 4 | import static org.junit.Assert.assertFalse; |
5 | -import static org.junit.Assert.assertNull; | ||
6 | import static org.junit.Assert.assertNotNull; | 5 | import static org.junit.Assert.assertNotNull; |
6 | +import static org.junit.Assert.assertNull; | ||
7 | import static org.junit.Assert.assertTrue; | 7 | import static org.junit.Assert.assertTrue; |
8 | +import static org.onlab.onos.net.host.HostEvent.Type.HOST_ADDED; | ||
9 | +import static org.onlab.onos.net.host.HostEvent.Type.HOST_MOVED; | ||
10 | +import static org.onlab.onos.net.host.HostEvent.Type.HOST_REMOVED; | ||
11 | +import static org.onlab.onos.net.host.HostEvent.Type.HOST_UPDATED; | ||
8 | 12 | ||
9 | import java.util.List; | 13 | import java.util.List; |
10 | import java.util.Set; | 14 | import java.util.Set; |
... | @@ -14,6 +18,7 @@ import org.junit.Before; | ... | @@ -14,6 +18,7 @@ import org.junit.Before; |
14 | import org.junit.Test; | 18 | import org.junit.Test; |
15 | import org.onlab.onos.event.Event; | 19 | import org.onlab.onos.event.Event; |
16 | import org.onlab.onos.event.impl.TestEventDispatcher; | 20 | import org.onlab.onos.event.impl.TestEventDispatcher; |
21 | +import org.onlab.onos.net.ConnectPoint; | ||
17 | import org.onlab.onos.net.DeviceId; | 22 | import org.onlab.onos.net.DeviceId; |
18 | import org.onlab.onos.net.Host; | 23 | import org.onlab.onos.net.Host; |
19 | import org.onlab.onos.net.HostId; | 24 | import org.onlab.onos.net.HostId; |
... | @@ -26,6 +31,7 @@ import org.onlab.onos.net.host.HostListener; | ... | @@ -26,6 +31,7 @@ import org.onlab.onos.net.host.HostListener; |
26 | import org.onlab.onos.net.host.HostProvider; | 31 | import org.onlab.onos.net.host.HostProvider; |
27 | import org.onlab.onos.net.host.HostProviderRegistry; | 32 | import org.onlab.onos.net.host.HostProviderRegistry; |
28 | import org.onlab.onos.net.host.HostProviderService; | 33 | import org.onlab.onos.net.host.HostProviderService; |
34 | +import org.onlab.onos.net.host.PortAddresses; | ||
29 | import org.onlab.onos.net.provider.AbstractProvider; | 35 | import org.onlab.onos.net.provider.AbstractProvider; |
30 | import org.onlab.onos.net.provider.ProviderId; | 36 | import org.onlab.onos.net.provider.ProviderId; |
31 | import org.onlab.onos.net.trivial.impl.SimpleHostStore; | 37 | import org.onlab.onos.net.trivial.impl.SimpleHostStore; |
... | @@ -36,8 +42,6 @@ import org.onlab.packet.VlanId; | ... | @@ -36,8 +42,6 @@ import org.onlab.packet.VlanId; |
36 | import com.google.common.collect.Lists; | 42 | import com.google.common.collect.Lists; |
37 | import com.google.common.collect.Sets; | 43 | import com.google.common.collect.Sets; |
38 | 44 | ||
39 | -import static org.onlab.onos.net.host.HostEvent.Type.*; | ||
40 | - | ||
41 | /** | 45 | /** |
42 | * Test codifying the host service & host provider service contracts. | 46 | * Test codifying the host service & host provider service contracts. |
43 | */ | 47 | */ |
... | @@ -63,6 +67,12 @@ public class HostManagerTest { | ... | @@ -63,6 +67,12 @@ public class HostManagerTest { |
63 | private static final PortNumber P2 = PortNumber.portNumber(200); | 67 | private static final PortNumber P2 = PortNumber.portNumber(200); |
64 | private static final HostLocation LOC1 = new HostLocation(DID1, P1, 123L); | 68 | private static final HostLocation LOC1 = new HostLocation(DID1, P1, 123L); |
65 | private static final HostLocation LOC2 = new HostLocation(DID1, P2, 123L); | 69 | private static final HostLocation LOC2 = new HostLocation(DID1, P2, 123L); |
70 | + private static final ConnectPoint CP1 = new ConnectPoint(DID1, P1); | ||
71 | + private static final ConnectPoint CP2 = new ConnectPoint(DID2, P2); | ||
72 | + | ||
73 | + private static final IpPrefix PREFIX1 = IpPrefix.valueOf("10.0.1.0/24"); | ||
74 | + private static final IpPrefix PREFIX2 = IpPrefix.valueOf("10.1.0.0/16"); | ||
75 | + private static final IpPrefix PREFIX3 = IpPrefix.valueOf("5.8.2.0/23"); | ||
66 | 76 | ||
67 | private HostManager mgr; | 77 | private HostManager mgr; |
68 | 78 | ||
... | @@ -196,4 +206,130 @@ public class HostManagerTest { | ... | @@ -196,4 +206,130 @@ public class HostManagerTest { |
196 | } | 206 | } |
197 | 207 | ||
198 | } | 208 | } |
209 | + | ||
210 | + @Test | ||
211 | + public void bindAddressesToPort() { | ||
212 | + PortAddresses add1 = new PortAddresses(CP1, | ||
213 | + Sets.newHashSet(PREFIX1, PREFIX2), MAC1); | ||
214 | + | ||
215 | + mgr.bindAddressesToPort(add1); | ||
216 | + PortAddresses storedAddresses = mgr.getAddressBindingsForPort(CP1); | ||
217 | + | ||
218 | + assertTrue(add1.ips().equals(storedAddresses.ips())); | ||
219 | + assertTrue(add1.mac().equals(storedAddresses.mac())); | ||
220 | + | ||
221 | + // Add some more addresses and check that they're added correctly | ||
222 | + PortAddresses add2 = new PortAddresses(CP1, Sets.newHashSet(PREFIX3), null); | ||
223 | + | ||
224 | + mgr.bindAddressesToPort(add2); | ||
225 | + storedAddresses = mgr.getAddressBindingsForPort(CP1); | ||
226 | + | ||
227 | + assertTrue(storedAddresses.ips().equals( | ||
228 | + Sets.newHashSet(PREFIX1, PREFIX2, PREFIX3))); | ||
229 | + assertTrue(storedAddresses.mac().equals(MAC1)); | ||
230 | + | ||
231 | + PortAddresses add3 = new PortAddresses(CP1, null, MAC2); | ||
232 | + | ||
233 | + mgr.bindAddressesToPort(add3); | ||
234 | + storedAddresses = mgr.getAddressBindingsForPort(CP1); | ||
235 | + | ||
236 | + assertTrue(storedAddresses.ips().equals( | ||
237 | + Sets.newHashSet(PREFIX1, PREFIX2, PREFIX3))); | ||
238 | + assertTrue(storedAddresses.mac().equals(MAC2)); | ||
239 | + } | ||
240 | + | ||
241 | + @Test | ||
242 | + public void unbindAddressesFromPort() { | ||
243 | + PortAddresses add1 = new PortAddresses(CP1, | ||
244 | + Sets.newHashSet(PREFIX1, PREFIX2), MAC1); | ||
245 | + | ||
246 | + mgr.bindAddressesToPort(add1); | ||
247 | + PortAddresses storedAddresses = mgr.getAddressBindingsForPort(CP1); | ||
248 | + | ||
249 | + assertTrue(storedAddresses.ips().size() == 2); | ||
250 | + assertNotNull(storedAddresses.mac()); | ||
251 | + | ||
252 | + PortAddresses rem1 = new PortAddresses(CP1, | ||
253 | + Sets.newHashSet(PREFIX1), null); | ||
254 | + | ||
255 | + mgr.unbindAddressesFromPort(rem1); | ||
256 | + storedAddresses = mgr.getAddressBindingsForPort(CP1); | ||
257 | + | ||
258 | + assertTrue(storedAddresses.ips().equals(Sets.newHashSet(PREFIX2))); | ||
259 | + assertTrue(storedAddresses.mac().equals(MAC1)); | ||
260 | + | ||
261 | + PortAddresses rem2 = new PortAddresses(CP1, null, MAC1); | ||
262 | + | ||
263 | + mgr.unbindAddressesFromPort(rem2); | ||
264 | + storedAddresses = mgr.getAddressBindingsForPort(CP1); | ||
265 | + | ||
266 | + assertTrue(storedAddresses.ips().equals(Sets.newHashSet(PREFIX2))); | ||
267 | + assertNull(storedAddresses.mac()); | ||
268 | + | ||
269 | + PortAddresses rem3 = new PortAddresses(CP1, | ||
270 | + Sets.newHashSet(PREFIX2), MAC1); | ||
271 | + | ||
272 | + mgr.unbindAddressesFromPort(rem3); | ||
273 | + storedAddresses = mgr.getAddressBindingsForPort(CP1); | ||
274 | + | ||
275 | + assertTrue(storedAddresses.ips().isEmpty()); | ||
276 | + assertNull(storedAddresses.mac()); | ||
277 | + } | ||
278 | + | ||
279 | + @Test | ||
280 | + public void clearAddresses() { | ||
281 | + PortAddresses add1 = new PortAddresses(CP1, | ||
282 | + Sets.newHashSet(PREFIX1, PREFIX2), MAC1); | ||
283 | + | ||
284 | + mgr.bindAddressesToPort(add1); | ||
285 | + PortAddresses storedAddresses = mgr.getAddressBindingsForPort(CP1); | ||
286 | + | ||
287 | + assertTrue(storedAddresses.ips().size() == 2); | ||
288 | + assertNotNull(storedAddresses.mac()); | ||
289 | + | ||
290 | + mgr.clearAddresses(CP1); | ||
291 | + storedAddresses = mgr.getAddressBindingsForPort(CP1); | ||
292 | + | ||
293 | + assertTrue(storedAddresses.ips().isEmpty()); | ||
294 | + assertNull(storedAddresses.mac()); | ||
295 | + } | ||
296 | + | ||
297 | + @Test | ||
298 | + public void getAddressBindingsForPort() { | ||
299 | + PortAddresses add1 = new PortAddresses(CP1, | ||
300 | + Sets.newHashSet(PREFIX1, PREFIX2), MAC1); | ||
301 | + | ||
302 | + mgr.bindAddressesToPort(add1); | ||
303 | + PortAddresses storedAddresses = mgr.getAddressBindingsForPort(CP1); | ||
304 | + | ||
305 | + assertTrue(storedAddresses.connectPoint().equals(CP1)); | ||
306 | + assertTrue(storedAddresses.ips().equals(Sets.newHashSet(PREFIX1, PREFIX2))); | ||
307 | + assertTrue(storedAddresses.mac().equals(MAC1)); | ||
308 | + } | ||
309 | + | ||
310 | + @Test | ||
311 | + public void getAddressBindings() { | ||
312 | + Set<PortAddresses> storedAddresses = mgr.getAddressBindings(); | ||
313 | + | ||
314 | + assertTrue(storedAddresses.isEmpty()); | ||
315 | + | ||
316 | + PortAddresses add1 = new PortAddresses(CP1, | ||
317 | + Sets.newHashSet(PREFIX1, PREFIX2), MAC1); | ||
318 | + | ||
319 | + mgr.bindAddressesToPort(add1); | ||
320 | + | ||
321 | + storedAddresses = mgr.getAddressBindings(); | ||
322 | + | ||
323 | + assertTrue(storedAddresses.size() == 1); | ||
324 | + | ||
325 | + PortAddresses add2 = new PortAddresses(CP2, | ||
326 | + Sets.newHashSet(PREFIX3), MAC2); | ||
327 | + | ||
328 | + mgr.bindAddressesToPort(add2); | ||
329 | + | ||
330 | + storedAddresses = mgr.getAddressBindings(); | ||
331 | + | ||
332 | + assertTrue(storedAddresses.size() == 2); | ||
333 | + assertTrue(storedAddresses.equals(Sets.newHashSet(add1, add2))); | ||
334 | + } | ||
199 | } | 335 | } | ... | ... |
... | @@ -36,6 +36,7 @@ import org.slf4j.Logger; | ... | @@ -36,6 +36,7 @@ import org.slf4j.Logger; |
36 | import com.google.common.collect.HashMultimap; | 36 | import com.google.common.collect.HashMultimap; |
37 | import com.google.common.collect.ImmutableSet; | 37 | import com.google.common.collect.ImmutableSet; |
38 | import com.google.common.collect.Multimap; | 38 | import com.google.common.collect.Multimap; |
39 | +import com.google.common.collect.Sets; | ||
39 | 40 | ||
40 | /** | 41 | /** |
41 | * Manages inventory of end-station hosts using trivial in-memory | 42 | * Manages inventory of end-station hosts using trivial in-memory |
... | @@ -202,29 +203,75 @@ public class SimpleHostStore | ... | @@ -202,29 +203,75 @@ public class SimpleHostStore |
202 | 203 | ||
203 | @Override | 204 | @Override |
204 | public void updateAddressBindings(PortAddresses addresses) { | 205 | public void updateAddressBindings(PortAddresses addresses) { |
205 | - // TODO portAddresses.put(addresses.connectPoint(), addresses); | 206 | + synchronized (portAddresses) { |
207 | + PortAddresses existing = portAddresses.get(addresses.connectPoint()); | ||
208 | + if (existing == null) { | ||
209 | + portAddresses.put(addresses.connectPoint(), addresses); | ||
210 | + } else { | ||
211 | + Set<IpPrefix> union = Sets.union(existing.ips(), addresses.ips()) | ||
212 | + .immutableCopy(); | ||
213 | + | ||
214 | + MacAddress newMac = (addresses.mac() == null) ? existing.mac() | ||
215 | + : addresses.mac(); | ||
216 | + | ||
217 | + PortAddresses newAddresses = | ||
218 | + new PortAddresses(addresses.connectPoint(), union, newMac); | ||
219 | + | ||
220 | + portAddresses.put(newAddresses.connectPoint(), newAddresses); | ||
221 | + } | ||
222 | + } | ||
206 | } | 223 | } |
207 | 224 | ||
208 | @Override | 225 | @Override |
209 | public void removeAddressBindings(PortAddresses addresses) { | 226 | public void removeAddressBindings(PortAddresses addresses) { |
210 | - // TODO Auto-generated method stub | 227 | + synchronized (portAddresses) { |
211 | - | 228 | + PortAddresses existing = portAddresses.get(addresses.connectPoint()); |
229 | + if (existing != null) { | ||
230 | + Set<IpPrefix> difference = | ||
231 | + Sets.difference(existing.ips(), addresses.ips()).immutableCopy(); | ||
232 | + | ||
233 | + // If they removed the existing mac, set the new mac to null. | ||
234 | + // Otherwise, keep the existing mac. | ||
235 | + MacAddress newMac = existing.mac(); | ||
236 | + if (addresses.mac() != null && addresses.mac().equals(existing.mac())) { | ||
237 | + newMac = null; | ||
238 | + } | ||
239 | + | ||
240 | + PortAddresses newAddresses = | ||
241 | + new PortAddresses(addresses.connectPoint(), difference, newMac); | ||
242 | + | ||
243 | + portAddresses.put(newAddresses.connectPoint(), newAddresses); | ||
244 | + } | ||
245 | + } | ||
212 | } | 246 | } |
213 | 247 | ||
214 | @Override | 248 | @Override |
215 | public void clearAddressBindings(ConnectPoint connectPoint) { | 249 | public void clearAddressBindings(ConnectPoint connectPoint) { |
216 | - // TODO Auto-generated method stub | 250 | + synchronized (portAddresses) { |
217 | - | 251 | + portAddresses.remove(connectPoint); |
252 | + } | ||
218 | } | 253 | } |
219 | 254 | ||
220 | @Override | 255 | @Override |
221 | public Set<PortAddresses> getAddressBindings() { | 256 | public Set<PortAddresses> getAddressBindings() { |
222 | - return new HashSet<>(portAddresses.values()); | 257 | + synchronized (portAddresses) { |
258 | + return new HashSet<>(portAddresses.values()); | ||
259 | + } | ||
223 | } | 260 | } |
224 | 261 | ||
225 | @Override | 262 | @Override |
226 | public PortAddresses getAddressBindingsForPort(ConnectPoint connectPoint) { | 263 | public PortAddresses getAddressBindingsForPort(ConnectPoint connectPoint) { |
227 | - return portAddresses.get(connectPoint); | 264 | + PortAddresses addresses; |
265 | + | ||
266 | + synchronized (portAddresses) { | ||
267 | + addresses = portAddresses.get(connectPoint); | ||
268 | + } | ||
269 | + | ||
270 | + if (addresses == null) { | ||
271 | + addresses = new PortAddresses(connectPoint, null, null); | ||
272 | + } | ||
273 | + | ||
274 | + return addresses; | ||
228 | } | 275 | } |
229 | 276 | ||
230 | } | 277 | } | ... | ... |
-
Please register or login to post a comment