Yuta HIGUCHI

GossipHostStore: add AE support

- modified HostDescription family to hold Set of IpAddresses

Change-Id: Id920fdc83817802885e8528af185a5ad590bf999
1 package org.onlab.onos.net.host; 1 package org.onlab.onos.net.host;
2 2
3 +import java.util.Collections;
4 +import java.util.Set;
5 +
3 import org.onlab.onos.net.AbstractDescription; 6 import org.onlab.onos.net.AbstractDescription;
4 import org.onlab.onos.net.HostLocation; 7 import org.onlab.onos.net.HostLocation;
5 import org.onlab.onos.net.SparseAnnotations; 8 import org.onlab.onos.net.SparseAnnotations;
...@@ -7,6 +10,8 @@ import org.onlab.packet.IpPrefix; ...@@ -7,6 +10,8 @@ import org.onlab.packet.IpPrefix;
7 import org.onlab.packet.MacAddress; 10 import org.onlab.packet.MacAddress;
8 import org.onlab.packet.VlanId; 11 import org.onlab.packet.VlanId;
9 12
13 +import com.google.common.collect.ImmutableSet;
14 +
10 import static com.google.common.base.MoreObjects.toStringHelper; 15 import static com.google.common.base.MoreObjects.toStringHelper;
11 16
12 /** 17 /**
...@@ -18,7 +23,7 @@ public class DefaultHostDescription extends AbstractDescription ...@@ -18,7 +23,7 @@ public class DefaultHostDescription extends AbstractDescription
18 private final MacAddress mac; 23 private final MacAddress mac;
19 private final VlanId vlan; 24 private final VlanId vlan;
20 private final HostLocation location; 25 private final HostLocation location;
21 - private final IpPrefix ip; 26 + private final Set<IpPrefix> ip;
22 27
23 /** 28 /**
24 * Creates a host description using the supplied information. 29 * Creates a host description using the supplied information.
...@@ -31,7 +36,7 @@ public class DefaultHostDescription extends AbstractDescription ...@@ -31,7 +36,7 @@ public class DefaultHostDescription extends AbstractDescription
31 public DefaultHostDescription(MacAddress mac, VlanId vlan, 36 public DefaultHostDescription(MacAddress mac, VlanId vlan,
32 HostLocation location, 37 HostLocation location,
33 SparseAnnotations... annotations) { 38 SparseAnnotations... annotations) {
34 - this(mac, vlan, location, null, annotations); 39 + this(mac, vlan, location, Collections.<IpPrefix>emptySet(), annotations);
35 } 40 }
36 41
37 /** 42 /**
...@@ -46,11 +51,26 @@ public class DefaultHostDescription extends AbstractDescription ...@@ -46,11 +51,26 @@ public class DefaultHostDescription extends AbstractDescription
46 public DefaultHostDescription(MacAddress mac, VlanId vlan, 51 public DefaultHostDescription(MacAddress mac, VlanId vlan,
47 HostLocation location, IpPrefix ip, 52 HostLocation location, IpPrefix ip,
48 SparseAnnotations... annotations) { 53 SparseAnnotations... annotations) {
54 + this(mac, vlan, location, ImmutableSet.of(ip), annotations);
55 + }
56 +
57 + /**
58 + * Creates a host description using the supplied information.
59 + *
60 + * @param mac host MAC address
61 + * @param vlan host VLAN identifier
62 + * @param location host location
63 + * @param ip host IP addresses
64 + * @param annotations optional key/value annotations map
65 + */
66 + public DefaultHostDescription(MacAddress mac, VlanId vlan,
67 + HostLocation location, Set<IpPrefix> ip,
68 + SparseAnnotations... annotations) {
49 super(annotations); 69 super(annotations);
50 this.mac = mac; 70 this.mac = mac;
51 this.vlan = vlan; 71 this.vlan = vlan;
52 this.location = location; 72 this.location = location;
53 - this.ip = ip; 73 + this.ip = ImmutableSet.copyOf(ip);
54 } 74 }
55 75
56 @Override 76 @Override
...@@ -69,7 +89,7 @@ public class DefaultHostDescription extends AbstractDescription ...@@ -69,7 +89,7 @@ public class DefaultHostDescription extends AbstractDescription
69 } 89 }
70 90
71 @Override 91 @Override
72 - public IpPrefix ipAddress() { 92 + public Set<IpPrefix> ipAddress() {
73 return ip; 93 return ip;
74 } 94 }
75 95
......
1 package org.onlab.onos.net.host; 1 package org.onlab.onos.net.host;
2 2
3 +import java.util.Set;
4 +
3 import org.onlab.onos.net.Description; 5 import org.onlab.onos.net.Description;
4 import org.onlab.onos.net.HostLocation; 6 import org.onlab.onos.net.HostLocation;
5 import org.onlab.packet.IpPrefix; 7 import org.onlab.packet.IpPrefix;
...@@ -38,6 +40,6 @@ public interface HostDescription extends Description { ...@@ -38,6 +40,6 @@ public interface HostDescription extends Description {
38 * @return host IP address 40 * @return host IP address
39 */ 41 */
40 // FIXME: Switch to IpAddress 42 // FIXME: Switch to IpAddress
41 - IpPrefix ipAddress(); 43 + Set<IpPrefix> ipAddress();
42 44
43 } 45 }
......
...@@ -8,6 +8,8 @@ import org.onlab.packet.IpPrefix; ...@@ -8,6 +8,8 @@ import org.onlab.packet.IpPrefix;
8 import org.onlab.packet.MacAddress; 8 import org.onlab.packet.MacAddress;
9 import org.onlab.packet.VlanId; 9 import org.onlab.packet.VlanId;
10 10
11 +import com.google.common.collect.ImmutableSet;
12 +
11 import static org.junit.Assert.assertEquals; 13 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertTrue; 14 import static org.junit.Assert.assertTrue;
13 15
...@@ -33,7 +35,7 @@ public class DefualtHostDecriptionTest { ...@@ -33,7 +35,7 @@ public class DefualtHostDecriptionTest {
33 assertEquals("incorrect mac", MAC, host.hwAddress()); 35 assertEquals("incorrect mac", MAC, host.hwAddress());
34 assertEquals("incorrect vlan", VLAN, host.vlan()); 36 assertEquals("incorrect vlan", VLAN, host.vlan());
35 assertEquals("incorrect location", LOC, host.location()); 37 assertEquals("incorrect location", LOC, host.location());
36 - assertEquals("incorrect ip's", IP, host.ipAddress()); 38 + assertEquals("incorrect ip's", ImmutableSet.of(IP), host.ipAddress());
37 assertTrue("incorrect toString", host.toString().contains("vlan=10")); 39 assertTrue("incorrect toString", host.toString().contains("vlan=10"));
38 } 40 }
39 41
......
...@@ -4,6 +4,11 @@ import org.onlab.onos.store.cluster.messaging.MessageSubject; ...@@ -4,6 +4,11 @@ import org.onlab.onos.store.cluster.messaging.MessageSubject;
4 4
5 public final class GossipHostStoreMessageSubjects { 5 public final class GossipHostStoreMessageSubjects {
6 private GossipHostStoreMessageSubjects() {} 6 private GossipHostStoreMessageSubjects() {}
7 - public static final MessageSubject HOST_UPDATED = new MessageSubject("peer-host-updated"); 7 +
8 - public static final MessageSubject HOST_REMOVED = new MessageSubject("peer-host-removed"); 8 + public static final MessageSubject HOST_UPDATED
9 + = new MessageSubject("peer-host-updated");
10 + public static final MessageSubject HOST_REMOVED
11 + = new MessageSubject("peer-host-removed");
12 + public static final MessageSubject HOST_ANTI_ENTROPY_ADVERTISEMENT
13 + = new MessageSubject("host-enti-entropy-advertisement");;
9 } 14 }
......
1 +package org.onlab.onos.store.host.impl;
2 +
3 +import static com.google.common.base.Preconditions.checkNotNull;
4 +
5 +import java.util.Map;
6 +
7 +import org.onlab.onos.cluster.NodeId;
8 +import org.onlab.onos.net.HostId;
9 +import org.onlab.onos.store.Timestamp;
10 +
11 +/**
12 + * Host AE Advertisement message.
13 + */
14 +public final class HostAntiEntropyAdvertisement {
15 +
16 + private final NodeId sender;
17 + private final Map<HostFragmentId, Timestamp> timestamps;
18 + private final Map<HostId, Timestamp> tombstones;
19 +
20 +
21 + public HostAntiEntropyAdvertisement(NodeId sender,
22 + Map<HostFragmentId, Timestamp> timestamps,
23 + Map<HostId, Timestamp> tombstones) {
24 + this.sender = checkNotNull(sender);
25 + this.timestamps = checkNotNull(timestamps);
26 + this.tombstones = checkNotNull(tombstones);
27 + }
28 +
29 + public NodeId sender() {
30 + return sender;
31 + }
32 +
33 + public Map<HostFragmentId, Timestamp> timestamps() {
34 + return timestamps;
35 + }
36 +
37 + public Map<HostId, Timestamp> tombstones() {
38 + return tombstones;
39 + }
40 +
41 + // For serializer
42 + @SuppressWarnings("unused")
43 + private HostAntiEntropyAdvertisement() {
44 + this.sender = null;
45 + this.timestamps = null;
46 + this.tombstones = null;
47 + }
48 +}
1 +package org.onlab.onos.store.host.impl;
2 +
3 +import java.util.Objects;
4 +
5 +import org.onlab.onos.net.HostId;
6 +import org.onlab.onos.net.provider.ProviderId;
7 +
8 +import com.google.common.base.MoreObjects;
9 +
10 +/**
11 + * Identifier for HostDescription from a Provider.
12 + */
13 +public final class HostFragmentId {
14 + public final ProviderId providerId;
15 + public final HostId hostId;
16 +
17 + public HostFragmentId(HostId hostId, ProviderId providerId) {
18 + this.providerId = providerId;
19 + this.hostId = hostId;
20 + }
21 +
22 + public HostId hostId() {
23 + return hostId;
24 + }
25 +
26 + public ProviderId providerId() {
27 + return providerId;
28 + }
29 +
30 + @Override
31 + public int hashCode() {
32 + return Objects.hash(providerId, hostId);
33 + }
34 +
35 + @Override
36 + public boolean equals(Object obj) {
37 + if (this == obj) {
38 + return true;
39 + }
40 + if (!(obj instanceof HostFragmentId)) {
41 + return false;
42 + }
43 + HostFragmentId that = (HostFragmentId) obj;
44 + return Objects.equals(this.hostId, that.hostId) &&
45 + Objects.equals(this.providerId, that.providerId);
46 + }
47 +
48 + @Override
49 + public String toString() {
50 + return MoreObjects.toStringHelper(getClass())
51 + .add("providerId", providerId)
52 + .add("hostId", hostId)
53 + .toString();
54 + }
55 +
56 + // for serializer
57 + @SuppressWarnings("unused")
58 + private HostFragmentId() {
59 + this.providerId = null;
60 + this.hostId = null;
61 + }
62 +}
...@@ -84,7 +84,7 @@ public class DistributedHostStore ...@@ -84,7 +84,7 @@ public class DistributedHostStore
84 descr.hwAddress(), 84 descr.hwAddress(),
85 descr.vlan(), 85 descr.vlan(),
86 descr.location(), 86 descr.location(),
87 - ImmutableSet.of(descr.ipAddress())); 87 + ImmutableSet.copyOf(descr.ipAddress()));
88 synchronized (this) { 88 synchronized (this) {
89 hosts.put(hostId, newhost); 89 hosts.put(hostId, newhost);
90 locations.put(descr.location(), newhost); 90 locations.put(descr.location(), newhost);
...@@ -101,12 +101,12 @@ public class DistributedHostStore ...@@ -101,12 +101,12 @@ public class DistributedHostStore
101 return new HostEvent(HOST_MOVED, host); 101 return new HostEvent(HOST_MOVED, host);
102 } 102 }
103 103
104 - if (host.ipAddresses().contains(descr.ipAddress())) { 104 + if (host.ipAddresses().containsAll(descr.ipAddress())) {
105 return null; 105 return null;
106 } 106 }
107 107
108 Set<IpPrefix> addresses = new HashSet<>(host.ipAddresses()); 108 Set<IpPrefix> addresses = new HashSet<>(host.ipAddresses());
109 - addresses.add(descr.ipAddress()); 109 + addresses.addAll(descr.ipAddress());
110 StoredHost updated = new StoredHost(providerId, host.id(), 110 StoredHost updated = new StoredHost(providerId, host.id(),
111 host.mac(), host.vlan(), 111 host.mac(), host.vlan(),
112 descr.location(), addresses); 112 descr.location(), addresses);
......
1 +package org.onlab.onos.store.serializers;
2 +
3 +import org.onlab.onos.net.DeviceId;
4 +import org.onlab.onos.net.HostLocation;
5 +import org.onlab.onos.net.PortNumber;
6 +
7 +import com.esotericsoftware.kryo.Kryo;
8 +import com.esotericsoftware.kryo.Serializer;
9 +import com.esotericsoftware.kryo.io.Input;
10 +import com.esotericsoftware.kryo.io.Output;
11 +
12 +/**
13 +* Kryo Serializer for {@link HostLocation}.
14 +*/
15 +public class HostLocationSerializer extends Serializer<HostLocation> {
16 +
17 + /**
18 + * Creates {@link HostLocation} serializer instance.
19 + */
20 + public HostLocationSerializer() {
21 + // non-null, immutable
22 + super(false, true);
23 + }
24 +
25 + @Override
26 + public void write(Kryo kryo, Output output, HostLocation object) {
27 + kryo.writeClassAndObject(output, object.deviceId());
28 + kryo.writeClassAndObject(output, object.port());
29 + output.writeLong(object.time());
30 + }
31 +
32 + @Override
33 + public HostLocation read(Kryo kryo, Input input, Class<HostLocation> type) {
34 + DeviceId deviceId = (DeviceId) kryo.readClassAndObject(input);
35 + PortNumber portNumber = (PortNumber) kryo.readClassAndObject(input);
36 + long time = input.readLong();
37 + return new HostLocation(deviceId, portNumber, time);
38 + }
39 +
40 +}
...@@ -17,6 +17,8 @@ import org.onlab.onos.net.DefaultPort; ...@@ -17,6 +17,8 @@ import org.onlab.onos.net.DefaultPort;
17 import org.onlab.onos.net.Device; 17 import org.onlab.onos.net.Device;
18 import org.onlab.onos.net.DeviceId; 18 import org.onlab.onos.net.DeviceId;
19 import org.onlab.onos.net.Element; 19 import org.onlab.onos.net.Element;
20 +import org.onlab.onos.net.HostId;
21 +import org.onlab.onos.net.HostLocation;
20 import org.onlab.onos.net.Link; 22 import org.onlab.onos.net.Link;
21 import org.onlab.onos.net.LinkKey; 23 import org.onlab.onos.net.LinkKey;
22 import org.onlab.onos.net.MastershipRole; 24 import org.onlab.onos.net.MastershipRole;
...@@ -24,15 +26,20 @@ import org.onlab.onos.net.Port; ...@@ -24,15 +26,20 @@ import org.onlab.onos.net.Port;
24 import org.onlab.onos.net.PortNumber; 26 import org.onlab.onos.net.PortNumber;
25 import org.onlab.onos.net.device.DefaultDeviceDescription; 27 import org.onlab.onos.net.device.DefaultDeviceDescription;
26 import org.onlab.onos.net.device.DefaultPortDescription; 28 import org.onlab.onos.net.device.DefaultPortDescription;
29 +import org.onlab.onos.net.host.DefaultHostDescription;
30 +import org.onlab.onos.net.host.HostDescription;
27 import org.onlab.onos.net.link.DefaultLinkDescription; 31 import org.onlab.onos.net.link.DefaultLinkDescription;
28 import org.onlab.onos.net.provider.ProviderId; 32 import org.onlab.onos.net.provider.ProviderId;
29 import org.onlab.onos.store.Timestamp; 33 import org.onlab.onos.store.Timestamp;
30 import org.onlab.packet.IpAddress; 34 import org.onlab.packet.IpAddress;
31 import org.onlab.packet.IpPrefix; 35 import org.onlab.packet.IpPrefix;
36 +import org.onlab.packet.MacAddress;
37 +import org.onlab.packet.VlanId;
32 import org.onlab.util.KryoPool; 38 import org.onlab.util.KryoPool;
33 39
34 import com.google.common.collect.ImmutableList; 40 import com.google.common.collect.ImmutableList;
35 import com.google.common.collect.ImmutableMap; 41 import com.google.common.collect.ImmutableMap;
42 +import com.google.common.collect.ImmutableSet;
36 43
37 public final class KryoPoolUtil { 44 public final class KryoPoolUtil {
38 45
...@@ -42,6 +49,8 @@ public final class KryoPoolUtil { ...@@ -42,6 +49,8 @@ public final class KryoPoolUtil {
42 public static final KryoPool MISC = KryoPool.newBuilder() 49 public static final KryoPool MISC = KryoPool.newBuilder()
43 .register(IpPrefix.class, new IpPrefixSerializer()) 50 .register(IpPrefix.class, new IpPrefixSerializer())
44 .register(IpAddress.class, new IpAddressSerializer()) 51 .register(IpAddress.class, new IpAddressSerializer())
52 + .register(MacAddress.class, new MacAddressSerializer())
53 + .register(VlanId.class)
45 .build(); 54 .build();
46 55
47 // TODO: Populate other classes 56 // TODO: Populate other classes
...@@ -52,6 +61,7 @@ public final class KryoPoolUtil { ...@@ -52,6 +61,7 @@ public final class KryoPoolUtil {
52 .register(MISC) 61 .register(MISC)
53 .register(ImmutableMap.class, new ImmutableMapSerializer()) 62 .register(ImmutableMap.class, new ImmutableMapSerializer())
54 .register(ImmutableList.class, new ImmutableListSerializer()) 63 .register(ImmutableList.class, new ImmutableListSerializer())
64 + .register(ImmutableSet.class, new ImmutableSetSerializer())
55 .register( 65 .register(
56 // 66 //
57 ArrayList.class, 67 ArrayList.class,
...@@ -71,8 +81,10 @@ public final class KryoPoolUtil { ...@@ -71,8 +81,10 @@ public final class KryoPoolUtil {
71 DefaultPortDescription.class, 81 DefaultPortDescription.class,
72 Element.class, 82 Element.class,
73 Link.Type.class, 83 Link.Type.class,
74 - Timestamp.class 84 + Timestamp.class,
75 - 85 + HostId.class,
86 + HostDescription.class,
87 + DefaultHostDescription.class
76 ) 88 )
77 .register(URI.class, new URISerializer()) 89 .register(URI.class, new URISerializer())
78 .register(NodeId.class, new NodeIdSerializer()) 90 .register(NodeId.class, new NodeIdSerializer())
...@@ -85,6 +97,7 @@ public final class KryoPoolUtil { ...@@ -85,6 +97,7 @@ public final class KryoPoolUtil {
85 .register(DefaultLink.class, new DefaultLinkSerializer()) 97 .register(DefaultLink.class, new DefaultLinkSerializer())
86 .register(MastershipTerm.class, new MastershipTermSerializer()) 98 .register(MastershipTerm.class, new MastershipTermSerializer())
87 .register(MastershipRole.class, new MastershipRoleSerializer()) 99 .register(MastershipRole.class, new MastershipRoleSerializer())
100 + .register(HostLocation.class, new HostLocationSerializer())
88 101
89 .build(); 102 .build();
90 103
......
1 +package org.onlab.onos.store.serializers;
2 +
3 +import org.onlab.packet.MacAddress;
4 +
5 +import com.esotericsoftware.kryo.Kryo;
6 +import com.esotericsoftware.kryo.Serializer;
7 +import com.esotericsoftware.kryo.io.Input;
8 +import com.esotericsoftware.kryo.io.Output;
9 +
10 +/**
11 + * Kryo Serializer for {@link MacAddress}.
12 + */
13 +public class MacAddressSerializer extends Serializer<MacAddress> {
14 +
15 + /**
16 + * Creates {@link MacAddress} serializer instance.
17 + */
18 + public MacAddressSerializer() {
19 + super(false, true);
20 + }
21 +
22 + @Override
23 + public void write(Kryo kryo, Output output, MacAddress object) {
24 + output.writeBytes(object.getAddress());
25 + }
26 +
27 + @Override
28 + public MacAddress read(Kryo kryo, Input input, Class<MacAddress> type) {
29 + return MacAddress.valueOf(input.readBytes(MacAddress.MAC_ADDRESS_LENGTH));
30 + }
31 +
32 +}
...@@ -84,7 +84,7 @@ public class SimpleHostStore ...@@ -84,7 +84,7 @@ public class SimpleHostStore
84 descr.hwAddress(), 84 descr.hwAddress(),
85 descr.vlan(), 85 descr.vlan(),
86 descr.location(), 86 descr.location(),
87 - ImmutableSet.of(descr.ipAddress())); 87 + ImmutableSet.copyOf(descr.ipAddress()));
88 synchronized (this) { 88 synchronized (this) {
89 hosts.put(hostId, newhost); 89 hosts.put(hostId, newhost);
90 locations.put(descr.location(), newhost); 90 locations.put(descr.location(), newhost);
...@@ -101,12 +101,12 @@ public class SimpleHostStore ...@@ -101,12 +101,12 @@ public class SimpleHostStore
101 return new HostEvent(HOST_MOVED, host); 101 return new HostEvent(HOST_MOVED, host);
102 } 102 }
103 103
104 - if (host.ipAddresses().contains(descr.ipAddress())) { 104 + if (host.ipAddresses().containsAll(descr.ipAddress())) {
105 return null; 105 return null;
106 } 106 }
107 107
108 Set<IpPrefix> addresses = new HashSet<>(host.ipAddresses()); 108 Set<IpPrefix> addresses = new HashSet<>(host.ipAddresses());
109 - addresses.add(descr.ipAddress()); 109 + addresses.addAll(descr.ipAddress());
110 StoredHost updated = new StoredHost(providerId, host.id(), 110 StoredHost updated = new StoredHost(providerId, host.id(),
111 host.mac(), host.vlan(), 111 host.mac(), host.vlan(),
112 descr.location(), addresses); 112 descr.location(), addresses);
......