tom

Merge remote-tracking branch 'origin/master'

package org.onlab.onos.net.host;
import java.util.Collections;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import org.onlab.onos.net.ConnectPoint;
......@@ -29,7 +31,7 @@ public class PortAddresses {
public PortAddresses(ConnectPoint connectPoint,
Set<IpPrefix> ips, MacAddress mac) {
this.connectPoint = connectPoint;
this.ipAddresses = (ips == null) ? null : new HashSet<>(ips);
this.ipAddresses = (ips == null) ? Collections.<IpPrefix>emptySet() : new HashSet<>(ips);
this.macAddress = mac;
}
......@@ -60,4 +62,25 @@ public class PortAddresses {
return macAddress;
}
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof PortAddresses)) {
return false;
}
PortAddresses otherPa = (PortAddresses) other;
return Objects.equals(this.connectPoint, otherPa.connectPoint)
&& Objects.equals(this.ipAddresses, otherPa.ipAddresses)
&& Objects.equals(this.macAddress, otherPa.macAddress);
}
@Override
public int hashCode() {
return Objects.hash(connectPoint, ipAddresses, macAddress);
}
}
......
......@@ -2,9 +2,13 @@ package org.onlab.onos.net.host.impl;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.onlab.onos.net.host.HostEvent.Type.HOST_ADDED;
import static org.onlab.onos.net.host.HostEvent.Type.HOST_MOVED;
import static org.onlab.onos.net.host.HostEvent.Type.HOST_REMOVED;
import static org.onlab.onos.net.host.HostEvent.Type.HOST_UPDATED;
import java.util.List;
import java.util.Set;
......@@ -14,6 +18,7 @@ import org.junit.Before;
import org.junit.Test;
import org.onlab.onos.event.Event;
import org.onlab.onos.event.impl.TestEventDispatcher;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.Host;
import org.onlab.onos.net.HostId;
......@@ -26,6 +31,7 @@ import org.onlab.onos.net.host.HostListener;
import org.onlab.onos.net.host.HostProvider;
import org.onlab.onos.net.host.HostProviderRegistry;
import org.onlab.onos.net.host.HostProviderService;
import org.onlab.onos.net.host.PortAddresses;
import org.onlab.onos.net.provider.AbstractProvider;
import org.onlab.onos.net.provider.ProviderId;
import org.onlab.onos.net.trivial.impl.SimpleHostStore;
......@@ -36,8 +42,6 @@ import org.onlab.packet.VlanId;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import static org.onlab.onos.net.host.HostEvent.Type.*;
/**
* Test codifying the host service & host provider service contracts.
*/
......@@ -63,6 +67,12 @@ public class HostManagerTest {
private static final PortNumber P2 = PortNumber.portNumber(200);
private static final HostLocation LOC1 = new HostLocation(DID1, P1, 123L);
private static final HostLocation LOC2 = new HostLocation(DID1, P2, 123L);
private static final ConnectPoint CP1 = new ConnectPoint(DID1, P1);
private static final ConnectPoint CP2 = new ConnectPoint(DID2, P2);
private static final IpPrefix PREFIX1 = IpPrefix.valueOf("10.0.1.0/24");
private static final IpPrefix PREFIX2 = IpPrefix.valueOf("10.1.0.0/16");
private static final IpPrefix PREFIX3 = IpPrefix.valueOf("5.8.2.0/23");
private HostManager mgr;
......@@ -196,4 +206,130 @@ public class HostManagerTest {
}
}
@Test
public void bindAddressesToPort() {
PortAddresses add1 = new PortAddresses(CP1,
Sets.newHashSet(PREFIX1, PREFIX2), MAC1);
mgr.bindAddressesToPort(add1);
PortAddresses storedAddresses = mgr.getAddressBindingsForPort(CP1);
assertTrue(add1.ips().equals(storedAddresses.ips()));
assertTrue(add1.mac().equals(storedAddresses.mac()));
// Add some more addresses and check that they're added correctly
PortAddresses add2 = new PortAddresses(CP1, Sets.newHashSet(PREFIX3), null);
mgr.bindAddressesToPort(add2);
storedAddresses = mgr.getAddressBindingsForPort(CP1);
assertTrue(storedAddresses.ips().equals(
Sets.newHashSet(PREFIX1, PREFIX2, PREFIX3)));
assertTrue(storedAddresses.mac().equals(MAC1));
PortAddresses add3 = new PortAddresses(CP1, null, MAC2);
mgr.bindAddressesToPort(add3);
storedAddresses = mgr.getAddressBindingsForPort(CP1);
assertTrue(storedAddresses.ips().equals(
Sets.newHashSet(PREFIX1, PREFIX2, PREFIX3)));
assertTrue(storedAddresses.mac().equals(MAC2));
}
@Test
public void unbindAddressesFromPort() {
PortAddresses add1 = new PortAddresses(CP1,
Sets.newHashSet(PREFIX1, PREFIX2), MAC1);
mgr.bindAddressesToPort(add1);
PortAddresses storedAddresses = mgr.getAddressBindingsForPort(CP1);
assertTrue(storedAddresses.ips().size() == 2);
assertNotNull(storedAddresses.mac());
PortAddresses rem1 = new PortAddresses(CP1,
Sets.newHashSet(PREFIX1), null);
mgr.unbindAddressesFromPort(rem1);
storedAddresses = mgr.getAddressBindingsForPort(CP1);
assertTrue(storedAddresses.ips().equals(Sets.newHashSet(PREFIX2)));
assertTrue(storedAddresses.mac().equals(MAC1));
PortAddresses rem2 = new PortAddresses(CP1, null, MAC1);
mgr.unbindAddressesFromPort(rem2);
storedAddresses = mgr.getAddressBindingsForPort(CP1);
assertTrue(storedAddresses.ips().equals(Sets.newHashSet(PREFIX2)));
assertNull(storedAddresses.mac());
PortAddresses rem3 = new PortAddresses(CP1,
Sets.newHashSet(PREFIX2), MAC1);
mgr.unbindAddressesFromPort(rem3);
storedAddresses = mgr.getAddressBindingsForPort(CP1);
assertTrue(storedAddresses.ips().isEmpty());
assertNull(storedAddresses.mac());
}
@Test
public void clearAddresses() {
PortAddresses add1 = new PortAddresses(CP1,
Sets.newHashSet(PREFIX1, PREFIX2), MAC1);
mgr.bindAddressesToPort(add1);
PortAddresses storedAddresses = mgr.getAddressBindingsForPort(CP1);
assertTrue(storedAddresses.ips().size() == 2);
assertNotNull(storedAddresses.mac());
mgr.clearAddresses(CP1);
storedAddresses = mgr.getAddressBindingsForPort(CP1);
assertTrue(storedAddresses.ips().isEmpty());
assertNull(storedAddresses.mac());
}
@Test
public void getAddressBindingsForPort() {
PortAddresses add1 = new PortAddresses(CP1,
Sets.newHashSet(PREFIX1, PREFIX2), MAC1);
mgr.bindAddressesToPort(add1);
PortAddresses storedAddresses = mgr.getAddressBindingsForPort(CP1);
assertTrue(storedAddresses.connectPoint().equals(CP1));
assertTrue(storedAddresses.ips().equals(Sets.newHashSet(PREFIX1, PREFIX2)));
assertTrue(storedAddresses.mac().equals(MAC1));
}
@Test
public void getAddressBindings() {
Set<PortAddresses> storedAddresses = mgr.getAddressBindings();
assertTrue(storedAddresses.isEmpty());
PortAddresses add1 = new PortAddresses(CP1,
Sets.newHashSet(PREFIX1, PREFIX2), MAC1);
mgr.bindAddressesToPort(add1);
storedAddresses = mgr.getAddressBindings();
assertTrue(storedAddresses.size() == 1);
PortAddresses add2 = new PortAddresses(CP2,
Sets.newHashSet(PREFIX3), MAC2);
mgr.bindAddressesToPort(add2);
storedAddresses = mgr.getAddressBindings();
assertTrue(storedAddresses.size() == 2);
assertTrue(storedAddresses.equals(Sets.newHashSet(add1, add2)));
}
}
......
......@@ -36,6 +36,7 @@ import org.slf4j.Logger;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
/**
* Manages inventory of end-station hosts using trivial in-memory
......@@ -202,29 +203,75 @@ public class SimpleHostStore
@Override
public void updateAddressBindings(PortAddresses addresses) {
// TODO portAddresses.put(addresses.connectPoint(), addresses);
synchronized (portAddresses) {
PortAddresses existing = portAddresses.get(addresses.connectPoint());
if (existing == null) {
portAddresses.put(addresses.connectPoint(), addresses);
} else {
Set<IpPrefix> union = Sets.union(existing.ips(), addresses.ips())
.immutableCopy();
MacAddress newMac = (addresses.mac() == null) ? existing.mac()
: addresses.mac();
PortAddresses newAddresses =
new PortAddresses(addresses.connectPoint(), union, newMac);
portAddresses.put(newAddresses.connectPoint(), newAddresses);
}
}
}
@Override
public void removeAddressBindings(PortAddresses addresses) {
// TODO Auto-generated method stub
synchronized (portAddresses) {
PortAddresses existing = portAddresses.get(addresses.connectPoint());
if (existing != null) {
Set<IpPrefix> difference =
Sets.difference(existing.ips(), addresses.ips()).immutableCopy();
// If they removed the existing mac, set the new mac to null.
// Otherwise, keep the existing mac.
MacAddress newMac = existing.mac();
if (addresses.mac() != null && addresses.mac().equals(existing.mac())) {
newMac = null;
}
PortAddresses newAddresses =
new PortAddresses(addresses.connectPoint(), difference, newMac);
portAddresses.put(newAddresses.connectPoint(), newAddresses);
}
}
}
@Override
public void clearAddressBindings(ConnectPoint connectPoint) {
// TODO Auto-generated method stub
synchronized (portAddresses) {
portAddresses.remove(connectPoint);
}
}
@Override
public Set<PortAddresses> getAddressBindings() {
synchronized (portAddresses) {
return new HashSet<>(portAddresses.values());
}
}
@Override
public PortAddresses getAddressBindingsForPort(ConnectPoint connectPoint) {
return portAddresses.get(connectPoint);
PortAddresses addresses;
synchronized (portAddresses) {
addresses = portAddresses.get(connectPoint);
}
if (addresses == null) {
addresses = new PortAddresses(connectPoint, null, null);
}
return addresses;
}
}
......