Extend host structures to store multiple locations
Also update host location format in CLI and REST API
Change-Id: I0fbd655f642627dd3eb8a2925f83a3ee016fe4aa
diff --git a/core/api/src/main/java/org/onosproject/net/DefaultHost.java b/core/api/src/main/java/org/onosproject/net/DefaultHost.java
index d9cfa25..defb5a3 100644
--- a/core/api/src/main/java/org/onosproject/net/DefaultHost.java
+++ b/core/api/src/main/java/org/onosproject/net/DefaultHost.java
@@ -21,6 +21,7 @@
import org.onlab.packet.VlanId;
import java.util.Collections;
+import java.util.Comparator;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
@@ -34,7 +35,7 @@
private final MacAddress mac;
private final VlanId vlan;
- private final HostLocation location;
+ private final Set<HostLocation> locations;
private final Set<IpAddress> ips;
private final boolean configured;
@@ -70,10 +71,29 @@
public DefaultHost(ProviderId providerId, HostId id, MacAddress mac,
VlanId vlan, HostLocation location, Set<IpAddress> ips,
boolean configured, Annotations... annotations) {
+ this(providerId, id, mac, vlan, Collections.singleton(location), ips,
+ configured, annotations);
+ }
+
+ /**
+ * Creates an end-station host using the supplied information.
+ *
+ * @param providerId provider identity
+ * @param id host identifier
+ * @param mac host MAC address
+ * @param vlan host VLAN identifier
+ * @param locations set of host locations
+ * @param ips host IP addresses
+ * @param configured true if configured via NetworkConfiguration
+ * @param annotations optional key/value annotations
+ */
+ public DefaultHost(ProviderId providerId, HostId id, MacAddress mac,
+ VlanId vlan, Set<HostLocation> locations, Set<IpAddress> ips,
+ boolean configured, Annotations... annotations) {
super(providerId, id, annotations);
this.mac = mac;
this.vlan = vlan;
- this.location = location;
+ this.locations = new HashSet<>(locations);
this.ips = new HashSet<>(ips);
this.configured = configured;
}
@@ -99,7 +119,14 @@
@Override
public HostLocation location() {
- return location;
+ return locations.stream()
+ .sorted(Comparator.comparingLong(HostLocation::time).reversed())
+ .findFirst().orElse(null);
+ }
+
+ @Override
+ public Set<HostLocation> locations() {
+ return locations;
}
@Override
@@ -114,7 +141,7 @@
@Override
public int hashCode() {
- return Objects.hash(id, mac, vlan, location);
+ return Objects.hash(id, mac, vlan, locations);
}
@Override
@@ -127,7 +154,7 @@
return Objects.equals(this.id, other.id) &&
Objects.equals(this.mac, other.mac) &&
Objects.equals(this.vlan, other.vlan) &&
- Objects.equals(this.location, other.location) &&
+ Objects.equals(this.locations, other.locations) &&
Objects.equals(this.ipAddresses(), other.ipAddresses()) &&
Objects.equals(this.annotations(), other.annotations());
}
@@ -140,7 +167,7 @@
.add("id", id())
.add("mac", mac())
.add("vlan", vlan())
- .add("location", location())
+ .add("locations", locations())
.add("ipAddresses", ipAddresses())
.add("annotations", annotations())
.add("configured", configured())
diff --git a/core/api/src/main/java/org/onosproject/net/Host.java b/core/api/src/main/java/org/onosproject/net/Host.java
index 5094727..86ef79f 100644
--- a/core/api/src/main/java/org/onosproject/net/Host.java
+++ b/core/api/src/main/java/org/onosproject/net/Host.java
@@ -59,11 +59,18 @@
* Returns the most recent host location where the host attaches to the
* network edge.
*
- * @return host location
+ * @return the most recent host location
*/
HostLocation location();
/**
+ * Returns all host locations where the host attaches to the network edge.
+ *
+ * @return all host locations
+ */
+ Set<HostLocation> locations();
+
+ /**
* Returns true if configured by NetworkConfiguration.
* @return configured/learnt dynamically
*/
@@ -73,4 +80,3 @@
// TODO: explore capturing list of recent locations to aid in mobility
}
-
diff --git a/core/api/src/main/java/org/onosproject/net/HostLocation.java b/core/api/src/main/java/org/onosproject/net/HostLocation.java
index f7868c6..94409b6 100644
--- a/core/api/src/main/java/org/onosproject/net/HostLocation.java
+++ b/core/api/src/main/java/org/onosproject/net/HostLocation.java
@@ -64,4 +64,8 @@
return time;
}
+ @Override
+ public String toString() {
+ return deviceId() + "/" + port();
+ }
}
diff --git a/core/api/src/main/java/org/onosproject/net/host/DefaultHostDescription.java b/core/api/src/main/java/org/onosproject/net/host/DefaultHostDescription.java
index 5f9cfd8..c2531f6 100644
--- a/core/api/src/main/java/org/onosproject/net/host/DefaultHostDescription.java
+++ b/core/api/src/main/java/org/onosproject/net/host/DefaultHostDescription.java
@@ -16,6 +16,8 @@
package org.onosproject.net.host;
import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
import java.util.Set;
import org.onosproject.net.AbstractDescription;
@@ -38,7 +40,7 @@
private final MacAddress mac;
private final VlanId vlan;
- private final HostLocation location;
+ private final Set<HostLocation> locations;
private final Set<IpAddress> ip;
private final boolean configured;
@@ -53,8 +55,7 @@
public DefaultHostDescription(MacAddress mac, VlanId vlan,
HostLocation location,
SparseAnnotations... annotations) {
- this(mac, vlan, location, Collections.emptySet(),
- annotations);
+ this(mac, vlan, location, Collections.emptySet(), annotations);
}
/**
@@ -100,8 +101,7 @@
HostLocation location,
boolean configured,
SparseAnnotations... annotations) {
- this(mac, vlan, location, Collections.<IpAddress>emptySet(),
- configured, annotations);
+ this(mac, vlan, location, Collections.emptySet(), configured, annotations);
}
/**
@@ -118,11 +118,28 @@
HostLocation location, Set<IpAddress> ip,
boolean configured,
SparseAnnotations... annotations) {
+ this(mac, vlan, Collections.singleton(location), ip, configured, annotations);
+ }
+
+ /**
+ * Creates a host description using the supplied information.
+ *
+ * @param mac host MAC address
+ * @param vlan host VLAN identifier
+ * @param locations host locations
+ * @param ip host IP address
+ * @param configured true if configured via NetworkConfiguration
+ * @param annotations optional key/value annotations map
+ */
+ public DefaultHostDescription(MacAddress mac, VlanId vlan,
+ Set<HostLocation> locations,
+ Set<IpAddress> ip, boolean configured,
+ SparseAnnotations... annotations) {
super(annotations);
this.mac = mac;
this.vlan = vlan;
- this.location = location;
- this.ip = ImmutableSet.copyOf(ip);
+ this.locations = new HashSet<>(locations);
+ this.ip = new HashSet<>(ip);
this.configured = configured;
}
@@ -138,7 +155,14 @@
@Override
public HostLocation location() {
- return location;
+ return locations.stream()
+ .sorted(Comparator.comparingLong(HostLocation::time).reversed())
+ .findFirst().orElse(null);
+ }
+
+ @Override
+ public Set<HostLocation> locations() {
+ return locations;
}
@Override
@@ -156,7 +180,7 @@
return toStringHelper(this)
.add("mac", mac)
.add("vlan", vlan)
- .add("location", location)
+ .add("locations", locations)
.add("ipAddress", ip)
.add("configured", configured)
.toString();
@@ -164,7 +188,7 @@
@Override
public int hashCode() {
- return Objects.hashCode(super.hashCode(), mac, vlan, location, ip);
+ return Objects.hashCode(super.hashCode(), mac, vlan, locations, ip);
}
@Override
@@ -176,7 +200,7 @@
DefaultHostDescription that = (DefaultHostDescription) object;
return Objects.equal(this.mac, that.mac)
&& Objects.equal(this.vlan, that.vlan)
- && Objects.equal(this.location, that.location)
+ && Objects.equal(this.locations, that.locations)
&& Objects.equal(this.ip, that.ip);
}
return false;
diff --git a/core/api/src/main/java/org/onosproject/net/host/HostDescription.java b/core/api/src/main/java/org/onosproject/net/host/HostDescription.java
index d7687ac..bba9dc9 100644
--- a/core/api/src/main/java/org/onosproject/net/host/HostDescription.java
+++ b/core/api/src/main/java/org/onosproject/net/host/HostDescription.java
@@ -43,13 +43,20 @@
VlanId vlan();
/**
- * Returns the location of the host on the network edge.
+ * Returns the most recent location of the host on the network edge.
*
- * @return the network location
+ * @return the most recent host location
*/
HostLocation location();
/**
+ * Returns all locations of the host on the network edge.
+ *
+ * @return all host locations
+ */
+ Set<HostLocation> locations();
+
+ /**
* Returns the IP address associated with this host's MAC.
*
* @return host IP address
diff --git a/core/api/src/test/java/org/onosproject/net/DefaultHostTest.java b/core/api/src/test/java/org/onosproject/net/DefaultHostTest.java
index 62012ba..e36d0e2 100644
--- a/core/api/src/test/java/org/onosproject/net/DefaultHostTest.java
+++ b/core/api/src/test/java/org/onosproject/net/DefaultHostTest.java
@@ -16,12 +16,19 @@
package org.onosproject.net;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.testing.EqualsTester;
+import java.util.Set;
import org.junit.Test;
-import com.google.common.testing.EqualsTester;
-
-public class DefaultHostTest extends TestDeviceParams {
+public class DefaultHostTest extends TestDeviceParams {
+ private static final Set<HostLocation> LOCATIONS = ImmutableSet.of(LOC1, LOC2, LOC3);
+ private static final Host SINGLE_HOMED_HOST =
+ new DefaultHost(PID, HID1, MAC1, VLAN1, LOC1, IPSET1);
+ private static final Host MULTI_HOMED_HOST =
+ new DefaultHost(PID, HID1, MAC1, VLAN1, LOCATIONS, IPSET1, false);
@Test
public void testEquality() {
@@ -39,13 +46,27 @@
@Test
public void basics() {
- Host host = new DefaultHost(PID, HID1, MAC1, VLAN1, LOC1, IPSET1);
- assertEquals("incorrect provider", PID, host.providerId());
- assertEquals("incorrect id", HID1, host.id());
- assertEquals("incorrect type", MAC1, host.mac());
- assertEquals("incorrect VLAN", VLAN1, host.vlan());
- assertEquals("incorrect location", LOC1, host.location());
- assertEquals("incorrect IP's", IPSET1, host.ipAddresses());
+ assertEquals("incorrect provider", PID, SINGLE_HOMED_HOST.providerId());
+ assertEquals("incorrect id", HID1, SINGLE_HOMED_HOST.id());
+ assertEquals("incorrect type", MAC1, SINGLE_HOMED_HOST.mac());
+ assertEquals("incorrect VLAN", VLAN1, SINGLE_HOMED_HOST.vlan());
+ assertEquals("incorrect location", LOC1, SINGLE_HOMED_HOST.location());
+ assertEquals("incorrect IPs", IPSET1, SINGLE_HOMED_HOST.ipAddresses());
+ }
+
+ @Test
+ public void testLocation() {
+ assertEquals("Latest location should be LOC3", LOC3, MULTI_HOMED_HOST.location());
+ }
+
+ @Test
+ public void testLocations() {
+ Set<HostLocation> locations = MULTI_HOMED_HOST.locations();
+
+ assertEquals("There should be 3 locations", locations.size(), 3);
+ assertTrue("Host location contains 1st location", locations.contains(LOC1));
+ assertTrue("Host location contains 2nd location", locations.contains(LOC2));
+ assertTrue("Host location contains 3rd location", locations.contains(LOC3));
}
}
diff --git a/core/api/src/test/java/org/onosproject/net/TestDeviceParams.java b/core/api/src/test/java/org/onosproject/net/TestDeviceParams.java
index 2de364a..4fa7baf 100644
--- a/core/api/src/test/java/org/onosproject/net/TestDeviceParams.java
+++ b/core/api/src/test/java/org/onosproject/net/TestDeviceParams.java
@@ -51,7 +51,8 @@
protected static final HostId HID1 = HostId.hostId(MAC1, VLAN1);
protected static final HostId HID2 = HostId.hostId(MAC2, VLAN2);
protected static final HostLocation LOC1 = new HostLocation(DID1, P1, 123L);
- protected static final HostLocation LOC2 = new HostLocation(DID2, P2, 123L);
+ protected static final HostLocation LOC2 = new HostLocation(DID2, P2, 456L);
+ protected static final HostLocation LOC3 = new HostLocation(DID3, P1, 789L);
protected static final Set<IpAddress> IPSET1 = Sets.newHashSet(IP1, IP2);
protected static final Set<IpAddress> IPSET2 = Sets.newHashSet(IP1, IP3);
diff --git a/core/api/src/test/java/org/onosproject/net/host/DefaultHostDecriptionTest.java b/core/api/src/test/java/org/onosproject/net/host/DefaultHostDecriptionTest.java
index 26a1cde..0b36035 100644
--- a/core/api/src/test/java/org/onosproject/net/host/DefaultHostDecriptionTest.java
+++ b/core/api/src/test/java/org/onosproject/net/host/DefaultHostDecriptionTest.java
@@ -16,14 +16,12 @@
package org.onosproject.net.host;
import org.junit.Test;
-import org.onosproject.net.DeviceId;
import org.onosproject.net.HostLocation;
-import org.onosproject.net.PortNumber;
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.MacAddress;
-import org.onlab.packet.VlanId;
import com.google.common.collect.ImmutableSet;
+import org.onosproject.net.TestDeviceParams;
+
+import java.util.Set;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -31,27 +29,34 @@
/**
* Test for the default host description.
*/
-public class DefaultHostDecriptionTest {
-
- private static final MacAddress MAC = MacAddress.valueOf("00:00:11:00:00:01");
- private static final VlanId VLAN = VlanId.vlanId((short) 10);
- private static final IpAddress IP = IpAddress.valueOf("10.0.0.1");
-
- private static final HostLocation LOC = new HostLocation(
- DeviceId.deviceId("of:foo"),
- PortNumber.portNumber(100),
- 123L
- );
+public class DefaultHostDecriptionTest extends TestDeviceParams {
+ private static final Set<HostLocation> LOCATIONS = ImmutableSet.of(LOC1, LOC2, LOC3);
+ private static final HostDescription SINGLE_HOMED_HOST_DESCR =
+ new DefaultHostDescription(MAC1, VLAN1, LOC1, IP1);
+ private static final HostDescription MULTI_HOMED_HOST_DESCR =
+ new DefaultHostDescription(MAC1, VLAN1, LOCATIONS, IPSET1, false);
@Test
public void basics() {
- HostDescription host =
- new DefaultHostDescription(MAC, VLAN, LOC, IP);
- assertEquals("incorrect mac", MAC, host.hwAddress());
- assertEquals("incorrect vlan", VLAN, host.vlan());
- assertEquals("incorrect location", LOC, host.location());
- assertEquals("incorrect ip's", ImmutableSet.of(IP), host.ipAddress());
- assertTrue("incorrect toString", host.toString().contains("vlan=10"));
+ assertEquals("incorrect mac", MAC1, SINGLE_HOMED_HOST_DESCR.hwAddress());
+ assertEquals("incorrect vlan", VLAN1, SINGLE_HOMED_HOST_DESCR.vlan());
+ assertEquals("incorrect location", LOC1, SINGLE_HOMED_HOST_DESCR.location());
+ assertEquals("incorrect IPs", ImmutableSet.of(IP1), SINGLE_HOMED_HOST_DESCR.ipAddress());
+ assertTrue("incorrect toString", SINGLE_HOMED_HOST_DESCR.toString().contains("vlan=11"));
}
+ @Test
+ public void testLocation() {
+ assertEquals("Latest location should be LOC3", LOC3, MULTI_HOMED_HOST_DESCR.location());
+ }
+
+ @Test
+ public void testLocations() {
+ Set<HostLocation> locations = MULTI_HOMED_HOST_DESCR.locations();
+
+ assertEquals("There should be 3 locations", locations.size(), 3);
+ assertTrue("Host location contains 1st location", locations.contains(LOC1));
+ assertTrue("Host location contains 2nd location", locations.contains(LOC2));
+ assertTrue("Host location contains 3rd location", locations.contains(LOC3));
+ }
}
diff --git a/core/api/src/test/java/org/onosproject/ui/topo/NodeSelectionTest.java b/core/api/src/test/java/org/onosproject/ui/topo/NodeSelectionTest.java
index 97f9843..63a4444 100644
--- a/core/api/src/test/java/org/onosproject/ui/topo/NodeSelectionTest.java
+++ b/core/api/src/test/java/org/onosproject/ui/topo/NodeSelectionTest.java
@@ -53,7 +53,7 @@
private static class FakeHost extends DefaultHost {
FakeHost(HostId id) {
- super(null, id, null, null, null, ImmutableSet.of());
+ super(null, id, null, null, ImmutableSet.of(), ImmutableSet.of(), false);
}
}