Yuta HIGUCHI

Device Anti-Entropy

- create Advertisement
- handler for Advertisement
- register handler, background thread to send advertisement

Change-Id: I99e8a7d68747970c34b3c25c6d0489769d251446
Showing 28 changed files with 469 additions and 275 deletions
...@@ -4,6 +4,8 @@ import org.onlab.onos.net.AbstractDescription; ...@@ -4,6 +4,8 @@ import org.onlab.onos.net.AbstractDescription;
4 import org.onlab.onos.net.PortNumber; 4 import org.onlab.onos.net.PortNumber;
5 import org.onlab.onos.net.SparseAnnotations; 5 import org.onlab.onos.net.SparseAnnotations;
6 6
7 +import com.google.common.base.MoreObjects;
8 +
7 /** 9 /**
8 * Default implementation of immutable port description. 10 * Default implementation of immutable port description.
9 */ 11 */
...@@ -48,6 +50,15 @@ public class DefaultPortDescription extends AbstractDescription ...@@ -48,6 +50,15 @@ public class DefaultPortDescription extends AbstractDescription
48 return isEnabled; 50 return isEnabled;
49 } 51 }
50 52
53 + @Override
54 + public String toString() {
55 + return MoreObjects.toStringHelper(getClass())
56 + .add("number", number)
57 + .add("isEnabled", isEnabled)
58 + .add("annotations", annotations())
59 + .toString();
60 + }
61 +
51 // default constructor for serialization 62 // default constructor for serialization
52 private DefaultPortDescription() { 63 private DefaultPortDescription() {
53 this.number = null; 64 this.number = null;
......
1 -package org.onlab.onos.store.common.impl;
2 -
3 -import java.util.Map;
4 -
5 -import org.onlab.onos.cluster.NodeId;
6 -import org.onlab.onos.store.Timestamp;
7 -
8 -import com.google.common.collect.ImmutableMap;
9 -
10 -/**
11 - * Anti-Entropy advertisement message.
12 - * <p>
13 - * Message to advertise the information this node holds.
14 - *
15 - * @param <ID> ID type
16 - */
17 -public class AntiEntropyAdvertisement<ID> {
18 -
19 - private final NodeId sender;
20 - private final ImmutableMap<ID, Timestamp> advertisement;
21 -
22 - /**
23 - * Creates anti-entropy advertisement message.
24 - *
25 - * @param sender sender of this message
26 - * @param advertisement timestamp information of the data sender holds
27 - */
28 - public AntiEntropyAdvertisement(NodeId sender, Map<ID, Timestamp> advertisement) {
29 - this.sender = sender;
30 - this.advertisement = ImmutableMap.copyOf(advertisement);
31 - }
32 -
33 - public NodeId sender() {
34 - return sender;
35 - }
36 -
37 - public ImmutableMap<ID, Timestamp> advertisement() {
38 - return advertisement;
39 - }
40 -
41 - // Default constructor for serializer
42 - protected AntiEntropyAdvertisement() {
43 - this.sender = null;
44 - this.advertisement = null;
45 - }
46 -}
1 -package org.onlab.onos.store.common.impl;
2 -
3 -import java.util.Map;
4 -import java.util.Set;
5 -
6 -import org.onlab.onos.cluster.NodeId;
7 -import org.onlab.onos.store.device.impl.VersionedValue;
8 -
9 -import com.google.common.collect.ImmutableMap;
10 -import com.google.common.collect.ImmutableSet;
11 -
12 -/**
13 - * Anti-Entropy reply message.
14 - * <p>
15 - * Message to send in reply to advertisement or another reply.
16 - * Suggest to the sender about the more up-to-date data this node has,
17 - * and request for more recent data that the receiver has.
18 - */
19 -public class AntiEntropyReply<ID, V extends VersionedValue<?>> {
20 -
21 - private final NodeId sender;
22 - private final ImmutableMap<ID, V> suggestion;
23 - private final ImmutableSet<ID> request;
24 -
25 - /**
26 - * Creates a reply to anti-entropy message.
27 - *
28 - * @param sender sender of this message
29 - * @param suggestion collection of more recent values, sender had
30 - * @param request Collection of identifiers
31 - */
32 - public AntiEntropyReply(NodeId sender,
33 - Map<ID, V> suggestion,
34 - Set<ID> request) {
35 - this.sender = sender;
36 - this.suggestion = ImmutableMap.copyOf(suggestion);
37 - this.request = ImmutableSet.copyOf(request);
38 - }
39 -
40 - public NodeId sender() {
41 - return sender;
42 - }
43 -
44 - /**
45 - * Returns collection of values, which the recipient of this reply is likely
46 - * to be missing or has outdated version.
47 - *
48 - * @return
49 - */
50 - public ImmutableMap<ID, V> suggestion() {
51 - return suggestion;
52 - }
53 -
54 - /**
55 - * Returns collection of identifier to request.
56 - *
57 - * @return collection of identifier to request
58 - */
59 - public ImmutableSet<ID> request() {
60 - return request;
61 - }
62 -
63 - /**
64 - * Checks if reply contains any suggestion or request.
65 - *
66 - * @return true if nothing is suggested and requested
67 - */
68 - public boolean isEmpty() {
69 - return suggestion.isEmpty() && request.isEmpty();
70 - }
71 -
72 - // Default constructor for serializer
73 - protected AntiEntropyReply() {
74 - this.sender = null;
75 - this.suggestion = null;
76 - this.request = null;
77 - }
78 -}
1 +package org.onlab.onos.store.common.impl;
2 +
3 +import org.onlab.onos.cluster.ControllerNode;
4 +import org.onlab.onos.cluster.NodeId;
5 +
6 +import com.google.common.base.Function;
7 +
8 +/**
9 + * Function to convert ControllerNode to NodeId.
10 + */
11 +public final class ControllerNodeToNodeId
12 + implements Function<ControllerNode, NodeId> {
13 +
14 + private static final ControllerNodeToNodeId INSTANCE = new ControllerNodeToNodeId();
15 +
16 + @Override
17 + public NodeId apply(ControllerNode input) {
18 + return input.id();
19 + }
20 +
21 + public static ControllerNodeToNodeId toNodeId() {
22 + return INSTANCE;
23 + }
24 +}
...@@ -30,6 +30,7 @@ public final class Timestamped<T> { ...@@ -30,6 +30,7 @@ public final class Timestamped<T> {
30 30
31 /** 31 /**
32 * Returns the value. 32 * Returns the value.
33 + *
33 * @return value 34 * @return value
34 */ 35 */
35 public T value() { 36 public T value() {
...@@ -38,6 +39,7 @@ public final class Timestamped<T> { ...@@ -38,6 +39,7 @@ public final class Timestamped<T> {
38 39
39 /** 40 /**
40 * Returns the time stamp. 41 * Returns the time stamp.
42 + *
41 * @return time stamp 43 * @return time stamp
42 */ 44 */
43 public Timestamp timestamp() { 45 public Timestamp timestamp() {
...@@ -51,7 +53,16 @@ public final class Timestamped<T> { ...@@ -51,7 +53,16 @@ public final class Timestamped<T> {
51 * @return true if this instance is newer. 53 * @return true if this instance is newer.
52 */ 54 */
53 public boolean isNewer(Timestamped<T> other) { 55 public boolean isNewer(Timestamped<T> other) {
54 - return this.timestamp.compareTo(checkNotNull(other).timestamp()) > 0; 56 + return isNewer(checkNotNull(other).timestamp());
57 + }
58 +
59 + /**
60 + * Tests if this timestamp is newer thatn the specified timestamp.
61 + * @param timestamp to compare agains
62 + * @return true if this instance is newer
63 + */
64 + public boolean isNewer(Timestamp timestamp) {
65 + return this.timestamp.compareTo(checkNotNull(timestamp)) > 0;
55 } 66 }
56 67
57 @Override 68 @Override
......
1 -package org.onlab.onos.store.device.impl;
2 -
3 -import java.util.Collection;
4 -import java.util.HashMap;
5 -import java.util.Map;
6 -
7 -import org.onlab.onos.cluster.NodeId;
8 -import org.onlab.onos.net.Device;
9 -import org.onlab.onos.net.DeviceId;
10 -import org.onlab.onos.store.Timestamp;
11 -import org.onlab.onos.store.common.impl.AntiEntropyAdvertisement;
12 -
13 -// TODO DeviceID needs to be changed to something like (ProviderID, DeviceID)
14 -// TODO: Handle Port as part of these messages, or separate messages for Ports?
15 -
16 -public class DeviceAntiEntropyAdvertisement
17 - extends AntiEntropyAdvertisement<DeviceId> {
18 -
19 -
20 - public DeviceAntiEntropyAdvertisement(NodeId sender,
21 - Map<DeviceId, Timestamp> advertisement) {
22 - super(sender, advertisement);
23 - }
24 -
25 - // May need to add ProviderID, etc.
26 - public static DeviceAntiEntropyAdvertisement create(
27 - NodeId self,
28 - Collection<VersionedValue<Device>> localValues) {
29 -
30 - Map<DeviceId, Timestamp> ads = new HashMap<>(localValues.size());
31 - for (VersionedValue<Device> e : localValues) {
32 - ads.put(e.entity().id(), e.timestamp());
33 - }
34 - return new DeviceAntiEntropyAdvertisement(self, ads);
35 - }
36 -
37 - // For serializer
38 - protected DeviceAntiEntropyAdvertisement() {}
39 -}
1 -package org.onlab.onos.store.device.impl;
2 -
3 -import java.util.Collection;
4 -import java.util.HashMap;
5 -import java.util.HashSet;
6 -import java.util.Map;
7 -import java.util.Set;
8 -
9 -import org.onlab.onos.cluster.NodeId;
10 -import org.onlab.onos.net.Device;
11 -import org.onlab.onos.net.DeviceId;
12 -import org.onlab.onos.store.Timestamp;
13 -import org.onlab.onos.store.common.impl.AntiEntropyReply;
14 -
15 -import com.google.common.collect.ImmutableMap;
16 -import com.google.common.collect.ImmutableSet;
17 -
18 -public class DeviceAntiEntropyReply
19 - extends AntiEntropyReply<DeviceId, VersionedValue<Device>> {
20 -
21 -
22 - public DeviceAntiEntropyReply(NodeId sender,
23 - Map<DeviceId, VersionedValue<Device>> suggestion,
24 - Set<DeviceId> request) {
25 - super(sender, suggestion, request);
26 - }
27 -
28 - /**
29 - * Creates a reply to Anti-Entropy advertisement.
30 - *
31 - * @param advertisement to respond to
32 - * @param self node identifier representing local node
33 - * @param localValues local values held on this node
34 - * @return reply message
35 - */
36 - public static DeviceAntiEntropyReply reply(
37 - DeviceAntiEntropyAdvertisement advertisement,
38 - NodeId self,
39 - Collection<VersionedValue<Device>> localValues
40 - ) {
41 -
42 - ImmutableMap<DeviceId, Timestamp> ads = advertisement.advertisement();
43 -
44 - ImmutableMap.Builder<DeviceId, VersionedValue<Device>>
45 - sug = ImmutableMap.builder();
46 -
47 - Set<DeviceId> req = new HashSet<>(ads.keySet());
48 -
49 - for (VersionedValue<Device> e : localValues) {
50 - final DeviceId id = e.entity().id();
51 - final Timestamp local = e.timestamp();
52 - final Timestamp theirs = ads.get(id);
53 - if (theirs == null) {
54 - // they don't have it, suggest
55 - sug.put(id, e);
56 - // don't need theirs
57 - req.remove(id);
58 - } else if (local.compareTo(theirs) < 0) {
59 - // they got older one, suggest
60 - sug.put(id, e);
61 - // don't need theirs
62 - req.remove(id);
63 - } else if (local.equals(theirs)) {
64 - // same, don't need theirs
65 - req.remove(id);
66 - }
67 - }
68 -
69 - return new DeviceAntiEntropyReply(self, sug.build(), req);
70 - }
71 -
72 - /**
73 - * Creates a reply to request for values held locally.
74 - *
75 - * @param requests message containing the request
76 - * @param self node identifier representing local node
77 - * @param localValues local valeds held on this node
78 - * @return reply message
79 - */
80 - public static DeviceAntiEntropyReply reply(
81 - DeviceAntiEntropyReply requests,
82 - NodeId self,
83 - Map<DeviceId, VersionedValue<Device>> localValues
84 - ) {
85 -
86 - Set<DeviceId> reqs = requests.request();
87 -
88 - Map<DeviceId, VersionedValue<Device>> requested = new HashMap<>(reqs.size());
89 - for (DeviceId id : reqs) {
90 - final VersionedValue<Device> value = localValues.get(id);
91 - if (value != null) {
92 - requested.put(id, value);
93 - }
94 - }
95 -
96 - Set<DeviceId> empty = ImmutableSet.of();
97 - return new DeviceAntiEntropyReply(self, requested, empty);
98 - }
99 -
100 - // For serializer
101 - protected DeviceAntiEntropyReply() {}
102 -}
1 +package org.onlab.onos.store.device.impl;
2 +
3 +import static com.google.common.base.Preconditions.checkNotNull;
4 +import static org.onlab.onos.net.DefaultAnnotations.union;
5 +
6 +import java.util.Collections;
7 +import java.util.Map;
8 +import java.util.concurrent.ConcurrentHashMap;
9 +import java.util.concurrent.ConcurrentMap;
10 +
11 +import org.onlab.onos.net.PortNumber;
12 +import org.onlab.onos.net.SparseAnnotations;
13 +import org.onlab.onos.net.device.DefaultDeviceDescription;
14 +import org.onlab.onos.net.device.DefaultPortDescription;
15 +import org.onlab.onos.net.device.DeviceDescription;
16 +import org.onlab.onos.net.device.PortDescription;
17 +import org.onlab.onos.store.Timestamp;
18 +import org.onlab.onos.store.common.impl.Timestamped;
19 +
20 +/*
21 + * Collection of Description of a Device and Ports, given from a Provider.
22 + */
23 +class DeviceDescriptions {
24 +
25 + private volatile Timestamped<DeviceDescription> deviceDesc;
26 +
27 + private final ConcurrentMap<PortNumber, Timestamped<PortDescription>> portDescs;
28 +
29 + public DeviceDescriptions(Timestamped<DeviceDescription> desc) {
30 + this.deviceDesc = checkNotNull(desc);
31 + this.portDescs = new ConcurrentHashMap<>();
32 + }
33 +
34 + public Timestamp getLatestTimestamp() {
35 + Timestamp latest = deviceDesc.timestamp();
36 + for (Timestamped<PortDescription> desc : portDescs.values()) {
37 + if (desc.timestamp().compareTo(latest) > 0) {
38 + latest = desc.timestamp();
39 + }
40 + }
41 + return latest;
42 + }
43 +
44 + public Timestamped<DeviceDescription> getDeviceDesc() {
45 + return deviceDesc;
46 + }
47 +
48 + public Timestamped<PortDescription> getPortDesc(PortNumber number) {
49 + return portDescs.get(number);
50 + }
51 +
52 + public Map<PortNumber, Timestamped<PortDescription>> getPortDescs() {
53 + return Collections.unmodifiableMap(portDescs);
54 + }
55 +
56 + /**
57 + * Puts DeviceDescription, merging annotations as necessary.
58 + *
59 + * @param newDesc new DeviceDescription
60 + */
61 + public synchronized void putDeviceDesc(Timestamped<DeviceDescription> newDesc) {
62 + Timestamped<DeviceDescription> oldOne = deviceDesc;
63 + Timestamped<DeviceDescription> newOne = newDesc;
64 + if (oldOne != null) {
65 + SparseAnnotations merged = union(oldOne.value().annotations(),
66 + newDesc.value().annotations());
67 + newOne = new Timestamped<DeviceDescription>(
68 + new DefaultDeviceDescription(newDesc.value(), merged),
69 + newDesc.timestamp());
70 + }
71 + deviceDesc = newOne;
72 + }
73 +
74 + /**
75 + * Puts PortDescription, merging annotations as necessary.
76 + *
77 + * @param newDesc new PortDescription
78 + */
79 + public synchronized void putPortDesc(Timestamped<PortDescription> newDesc) {
80 + Timestamped<PortDescription> oldOne = portDescs.get(newDesc.value().portNumber());
81 + Timestamped<PortDescription> newOne = newDesc;
82 + if (oldOne != null) {
83 + SparseAnnotations merged = union(oldOne.value().annotations(),
84 + newDesc.value().annotations());
85 + newOne = new Timestamped<PortDescription>(
86 + new DefaultPortDescription(newDesc.value(), merged),
87 + newDesc.timestamp());
88 + }
89 + portDescs.put(newOne.value().portNumber(), newOne);
90 + }
91 +}
...@@ -2,6 +2,7 @@ package org.onlab.onos.store.device.impl; ...@@ -2,6 +2,7 @@ package org.onlab.onos.store.device.impl;
2 2
3 import org.onlab.onos.store.cluster.messaging.MessageSubject; 3 import org.onlab.onos.store.cluster.messaging.MessageSubject;
4 4
5 +// TODO: add prefix to assure uniqueness.
5 /** 6 /**
6 * MessageSubjects used by GossipDeviceStore peer-peer communication. 7 * MessageSubjects used by GossipDeviceStore peer-peer communication.
7 */ 8 */
...@@ -14,4 +15,8 @@ public final class GossipDeviceStoreMessageSubjects { ...@@ -14,4 +15,8 @@ public final class GossipDeviceStoreMessageSubjects {
14 public static final MessageSubject DEVICE_REMOVED = new MessageSubject("peer-device-removed"); 15 public static final MessageSubject DEVICE_REMOVED = new MessageSubject("peer-device-removed");
15 public static final MessageSubject PORT_UPDATE = new MessageSubject("peer-port-update"); 16 public static final MessageSubject PORT_UPDATE = new MessageSubject("peer-port-update");
16 public static final MessageSubject PORT_STATUS_UPDATE = new MessageSubject("peer-port-status-update"); 17 public static final MessageSubject PORT_STATUS_UPDATE = new MessageSubject("peer-port-status-update");
18 +
19 + public static final MessageSubject DEVICE_ADVERTISE = new MessageSubject("peer-device-advertisements");
20 + // to be used with 3-way anti-entropy process
21 + public static final MessageSubject DEVICE_REQUEST = new MessageSubject("peer-device-request");
17 } 22 }
......
1 +package org.onlab.onos.store.device.impl;
2 +
3 +import static com.google.common.base.Preconditions.checkNotNull;
4 +
5 +import org.apache.commons.lang3.concurrent.ConcurrentException;
6 +import org.apache.commons.lang3.concurrent.ConcurrentInitializer;
7 +import org.onlab.onos.net.device.DeviceDescription;
8 +import org.onlab.onos.store.common.impl.Timestamped;
9 +
10 +// FIXME: consider removing this class
11 +public final class InitDeviceDescs
12 + implements ConcurrentInitializer<DeviceDescriptions> {
13 +
14 + private final Timestamped<DeviceDescription> deviceDesc;
15 +
16 + public InitDeviceDescs(Timestamped<DeviceDescription> deviceDesc) {
17 + this.deviceDesc = checkNotNull(deviceDesc);
18 + }
19 + @Override
20 + public DeviceDescriptions get() throws ConcurrentException {
21 + return new DeviceDescriptions(deviceDesc);
22 + }
23 +}
...\ No newline at end of file ...\ No newline at end of file
...@@ -5,6 +5,8 @@ import org.onlab.onos.net.device.DeviceDescription; ...@@ -5,6 +5,8 @@ import org.onlab.onos.net.device.DeviceDescription;
5 import org.onlab.onos.net.provider.ProviderId; 5 import org.onlab.onos.net.provider.ProviderId;
6 import org.onlab.onos.store.common.impl.Timestamped; 6 import org.onlab.onos.store.common.impl.Timestamped;
7 7
8 +import com.google.common.base.MoreObjects;
9 +
8 /** 10 /**
9 * Information published by GossipDeviceStore to notify peers of a device 11 * Information published by GossipDeviceStore to notify peers of a device
10 * change event. 12 * change event.
...@@ -36,6 +38,15 @@ public class InternalDeviceEvent { ...@@ -36,6 +38,15 @@ public class InternalDeviceEvent {
36 return deviceDescription; 38 return deviceDescription;
37 } 39 }
38 40
41 + @Override
42 + public String toString() {
43 + return MoreObjects.toStringHelper(getClass())
44 + .add("providerId", providerId)
45 + .add("deviceId", deviceId)
46 + .add("deviceDescription", deviceDescription)
47 + .toString();
48 + }
49 +
39 // for serializer 50 // for serializer
40 protected InternalDeviceEvent() { 51 protected InternalDeviceEvent() {
41 this.providerId = null; 52 this.providerId = null;
......
...@@ -3,6 +3,8 @@ package org.onlab.onos.store.device.impl; ...@@ -3,6 +3,8 @@ package org.onlab.onos.store.device.impl;
3 import org.onlab.onos.net.DeviceId; 3 import org.onlab.onos.net.DeviceId;
4 import org.onlab.onos.store.Timestamp; 4 import org.onlab.onos.store.Timestamp;
5 5
6 +import com.google.common.base.MoreObjects;
7 +
6 /** 8 /**
7 * Information published by GossipDeviceStore to notify peers of a device 9 * Information published by GossipDeviceStore to notify peers of a device
8 * going offline. 10 * going offline.
...@@ -30,6 +32,14 @@ public class InternalDeviceOfflineEvent { ...@@ -30,6 +32,14 @@ public class InternalDeviceOfflineEvent {
30 return timestamp; 32 return timestamp;
31 } 33 }
32 34
35 + @Override
36 + public String toString() {
37 + return MoreObjects.toStringHelper(getClass())
38 + .add("deviceId", deviceId)
39 + .add("timestamp", timestamp)
40 + .toString();
41 + }
42 +
33 // for serializer 43 // for serializer
34 @SuppressWarnings("unused") 44 @SuppressWarnings("unused")
35 private InternalDeviceOfflineEvent() { 45 private InternalDeviceOfflineEvent() {
......
...@@ -3,6 +3,8 @@ package org.onlab.onos.store.device.impl; ...@@ -3,6 +3,8 @@ package org.onlab.onos.store.device.impl;
3 import org.onlab.onos.net.DeviceId; 3 import org.onlab.onos.net.DeviceId;
4 import org.onlab.onos.store.Timestamp; 4 import org.onlab.onos.store.Timestamp;
5 5
6 +import com.google.common.base.MoreObjects;
7 +
6 /** 8 /**
7 * Information published by GossipDeviceStore to notify peers of a device 9 * Information published by GossipDeviceStore to notify peers of a device
8 * being administratively removed. 10 * being administratively removed.
...@@ -30,6 +32,14 @@ public class InternalDeviceRemovedEvent { ...@@ -30,6 +32,14 @@ public class InternalDeviceRemovedEvent {
30 return timestamp; 32 return timestamp;
31 } 33 }
32 34
35 + @Override
36 + public String toString() {
37 + return MoreObjects.toStringHelper(getClass())
38 + .add("deviceId", deviceId)
39 + .add("timestamp", timestamp)
40 + .toString();
41 + }
42 +
33 // for serializer 43 // for serializer
34 @SuppressWarnings("unused") 44 @SuppressWarnings("unused")
35 private InternalDeviceRemovedEvent() { 45 private InternalDeviceRemovedEvent() {
......
...@@ -7,6 +7,8 @@ import org.onlab.onos.net.device.PortDescription; ...@@ -7,6 +7,8 @@ import org.onlab.onos.net.device.PortDescription;
7 import org.onlab.onos.net.provider.ProviderId; 7 import org.onlab.onos.net.provider.ProviderId;
8 import org.onlab.onos.store.common.impl.Timestamped; 8 import org.onlab.onos.store.common.impl.Timestamped;
9 9
10 +import com.google.common.base.MoreObjects;
11 +
10 /** 12 /**
11 * Information published by GossipDeviceStore to notify peers of a port 13 * Information published by GossipDeviceStore to notify peers of a port
12 * change event. 14 * change event.
...@@ -38,6 +40,15 @@ public class InternalPortEvent { ...@@ -38,6 +40,15 @@ public class InternalPortEvent {
38 return portDescriptions; 40 return portDescriptions;
39 } 41 }
40 42
43 + @Override
44 + public String toString() {
45 + return MoreObjects.toStringHelper(getClass())
46 + .add("providerId", providerId)
47 + .add("deviceId", deviceId)
48 + .add("portDescriptions", portDescriptions)
49 + .toString();
50 + }
51 +
41 // for serializer 52 // for serializer
42 protected InternalPortEvent() { 53 protected InternalPortEvent() {
43 this.providerId = null; 54 this.providerId = null;
......
...@@ -5,6 +5,8 @@ import org.onlab.onos.net.device.PortDescription; ...@@ -5,6 +5,8 @@ import org.onlab.onos.net.device.PortDescription;
5 import org.onlab.onos.net.provider.ProviderId; 5 import org.onlab.onos.net.provider.ProviderId;
6 import org.onlab.onos.store.common.impl.Timestamped; 6 import org.onlab.onos.store.common.impl.Timestamped;
7 7
8 +import com.google.common.base.MoreObjects;
9 +
8 /** 10 /**
9 * Information published by GossipDeviceStore to notify peers of a port 11 * Information published by GossipDeviceStore to notify peers of a port
10 * status change event. 12 * status change event.
...@@ -36,6 +38,15 @@ public class InternalPortStatusEvent { ...@@ -36,6 +38,15 @@ public class InternalPortStatusEvent {
36 return portDescription; 38 return portDescription;
37 } 39 }
38 40
41 + @Override
42 + public String toString() {
43 + return MoreObjects.toStringHelper(getClass())
44 + .add("providerId", providerId)
45 + .add("deviceId", deviceId)
46 + .add("portDescription", portDescription)
47 + .toString();
48 + }
49 +
39 // for serializer 50 // for serializer
40 protected InternalPortStatusEvent() { 51 protected InternalPortStatusEvent() {
41 this.providerId = null; 52 this.providerId = null;
......
...@@ -35,6 +35,7 @@ public class InternalPortStatusEventSerializer extends Serializer<InternalPortSt ...@@ -35,6 +35,7 @@ public class InternalPortStatusEventSerializer extends Serializer<InternalPortSt
35 Class<InternalPortStatusEvent> type) { 35 Class<InternalPortStatusEvent> type) {
36 ProviderId providerId = (ProviderId) kryo.readClassAndObject(input); 36 ProviderId providerId = (ProviderId) kryo.readClassAndObject(input);
37 DeviceId deviceId = (DeviceId) kryo.readClassAndObject(input); 37 DeviceId deviceId = (DeviceId) kryo.readClassAndObject(input);
38 + @SuppressWarnings("unchecked")
38 Timestamped<PortDescription> portDescription = (Timestamped<PortDescription>) kryo.readClassAndObject(input); 39 Timestamped<PortDescription> portDescription = (Timestamped<PortDescription>) kryo.readClassAndObject(input);
39 40
40 return new InternalPortStatusEvent(providerId, deviceId, portDescription); 41 return new InternalPortStatusEvent(providerId, deviceId, portDescription);
......
1 +package org.onlab.onos.store.device.impl.peermsg;
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.DeviceId;
9 +import org.onlab.onos.store.Timestamp;
10 +
11 +
12 +/**
13 + * Device Advertisement message.
14 + */
15 +public class DeviceAntiEntropyAdvertisement {
16 +
17 + private final NodeId sender;
18 + private final Map<DeviceFragmentId, Timestamp> deviceFingerPrints;
19 + private final Map<PortFragmentId, Timestamp> portFingerPrints;
20 + private final Map<DeviceId, Timestamp> offline;
21 +
22 +
23 + public DeviceAntiEntropyAdvertisement(NodeId sender,
24 + Map<DeviceFragmentId, Timestamp> devices,
25 + Map<PortFragmentId, Timestamp> ports,
26 + Map<DeviceId, Timestamp> offline) {
27 + this.sender = checkNotNull(sender);
28 + this.deviceFingerPrints = checkNotNull(devices);
29 + this.portFingerPrints = checkNotNull(ports);
30 + this.offline = checkNotNull(offline);
31 + }
32 +
33 + public NodeId sender() {
34 + return sender;
35 + }
36 +
37 + public Map<DeviceFragmentId, Timestamp> deviceFingerPrints() {
38 + return deviceFingerPrints;
39 + }
40 +
41 + public Map<PortFragmentId, Timestamp> ports() {
42 + return portFingerPrints;
43 + }
44 +
45 + public Map<DeviceId, Timestamp> offline() {
46 + return offline;
47 + }
48 +
49 + // For serializer
50 + @SuppressWarnings("unused")
51 + private DeviceAntiEntropyAdvertisement() {
52 + this.sender = null;
53 + this.deviceFingerPrints = null;
54 + this.portFingerPrints = null;
55 + this.offline = null;
56 + }
57 +}
1 +package org.onlab.onos.store.device.impl.peermsg;
2 +
3 +import static com.google.common.base.Preconditions.checkNotNull;
4 +
5 +import java.util.Collection;
6 +
7 +import org.onlab.onos.cluster.NodeId;
8 +
9 +/**
10 + * Message to request for other peers information.
11 + */
12 +public class DeviceAntiEntropyRequest {
13 +
14 + private final NodeId sender;
15 + private final Collection<DeviceFragmentId> devices;
16 + private final Collection<PortFragmentId> ports;
17 +
18 + public DeviceAntiEntropyRequest(NodeId sender,
19 + Collection<DeviceFragmentId> devices,
20 + Collection<PortFragmentId> ports) {
21 +
22 + this.sender = checkNotNull(sender);
23 + this.devices = checkNotNull(devices);
24 + this.ports = checkNotNull(ports);
25 + }
26 +
27 + public NodeId sender() {
28 + return sender;
29 + }
30 +
31 + public Collection<DeviceFragmentId> devices() {
32 + return devices;
33 + }
34 +
35 + public Collection<PortFragmentId> ports() {
36 + return ports;
37 + }
38 +
39 + // For serializer
40 + @SuppressWarnings("unused")
41 + private DeviceAntiEntropyRequest() {
42 + this.sender = null;
43 + this.devices = null;
44 + this.ports = null;
45 + }
46 +}
1 +package org.onlab.onos.store.device.impl.peermsg;
2 +
3 +import java.util.Objects;
4 +
5 +import org.onlab.onos.net.DeviceId;
6 +import org.onlab.onos.net.provider.ProviderId;
7 +
8 +import com.google.common.base.MoreObjects;
9 +
10 +/**
11 + * Identifier for DeviceDesctiption from a Provider.
12 + */
13 +public final class DeviceFragmentId {
14 + public final ProviderId providerId;
15 + public final DeviceId deviceId;
16 +
17 + public DeviceFragmentId(DeviceId deviceId, ProviderId providerId) {
18 + this.providerId = providerId;
19 + this.deviceId = deviceId;
20 + }
21 +
22 + @Override
23 + public int hashCode() {
24 + return Objects.hash(providerId, deviceId);
25 + }
26 +
27 + @Override
28 + public boolean equals(Object obj) {
29 + if (this == obj) {
30 + return true;
31 + }
32 + if (!(obj instanceof DeviceFragmentId)) {
33 + return false;
34 + }
35 + DeviceFragmentId that = (DeviceFragmentId) obj;
36 + return Objects.equals(this.deviceId, that.deviceId) &&
37 + Objects.equals(this.providerId, that.providerId);
38 + }
39 +
40 + @Override
41 + public String toString() {
42 + return MoreObjects.toStringHelper(getClass())
43 + .add("providerId", providerId)
44 + .add("deviceId", deviceId)
45 + .toString();
46 + }
47 +
48 + // for serializer
49 + @SuppressWarnings("unused")
50 + private DeviceFragmentId() {
51 + this.providerId = null;
52 + this.deviceId = null;
53 + }
54 +}
...\ No newline at end of file ...\ No newline at end of file
1 +package org.onlab.onos.store.device.impl.peermsg;
2 +
3 +import java.util.Objects;
4 +
5 +import org.onlab.onos.net.DeviceId;
6 +import org.onlab.onos.net.PortNumber;
7 +import org.onlab.onos.net.provider.ProviderId;
8 +
9 +import com.google.common.base.MoreObjects;
10 +
11 +/**
12 + * Identifier for PortDescription from a Provider.
13 + */
14 +public final class PortFragmentId {
15 + public final ProviderId providerId;
16 + public final DeviceId deviceId;
17 + public final PortNumber portNumber;
18 +
19 + public PortFragmentId(DeviceId deviceId, ProviderId providerId,
20 + PortNumber portNumber) {
21 + this.providerId = providerId;
22 + this.deviceId = deviceId;
23 + this.portNumber = portNumber;
24 + }
25 +
26 + @Override
27 + public int hashCode() {
28 + return Objects.hash(providerId, deviceId, portNumber);
29 + };
30 +
31 + @Override
32 + public boolean equals(Object obj) {
33 + if (this == obj) {
34 + return true;
35 + }
36 + if (!(obj instanceof PortFragmentId)) {
37 + return false;
38 + }
39 + PortFragmentId that = (PortFragmentId) obj;
40 + return Objects.equals(this.deviceId, that.deviceId) &&
41 + Objects.equals(this.portNumber, that.portNumber) &&
42 + Objects.equals(this.providerId, that.providerId);
43 + }
44 +
45 + @Override
46 + public String toString() {
47 + return MoreObjects.toStringHelper(getClass())
48 + .add("providerId", providerId)
49 + .add("deviceId", deviceId)
50 + .add("portNumber", portNumber)
51 + .toString();
52 + }
53 +
54 + // for serializer
55 + @SuppressWarnings("unused")
56 + private PortFragmentId() {
57 + this.providerId = null;
58 + this.deviceId = null;
59 + this.portNumber = null;
60 + }
61 +}
...\ No newline at end of file ...\ No newline at end of file
1 +/**
2 + * Structure and utilities used for inter-Node messaging.
3 + */
4 +package org.onlab.onos.store.device.impl.peermsg;
...@@ -31,7 +31,6 @@ import org.onlab.onos.net.provider.ProviderId; ...@@ -31,7 +31,6 @@ import org.onlab.onos.net.provider.ProviderId;
31 import org.onlab.onos.store.AbstractStore; 31 import org.onlab.onos.store.AbstractStore;
32 import org.onlab.onos.store.ClockService; 32 import org.onlab.onos.store.ClockService;
33 import org.onlab.onos.store.Timestamp; 33 import org.onlab.onos.store.Timestamp;
34 -import org.onlab.onos.store.device.impl.VersionedValue;
35 import org.slf4j.Logger; 34 import org.slf4j.Logger;
36 35
37 import com.google.common.collect.HashMultimap; 36 import com.google.common.collect.HashMultimap;
......
1 -package org.onlab.onos.store.device.impl; 1 +package org.onlab.onos.store.link.impl;
2 2
3 import java.util.Objects; 3 import java.util.Objects;
4 4
5 import org.onlab.onos.store.Timestamp; 5 import org.onlab.onos.store.Timestamp;
6 6
7 +// TODO: remove once we stop using this
7 /** 8 /**
8 * Wrapper class for a entity that is versioned 9 * Wrapper class for a entity that is versioned
9 * and can either be up or down. 10 * and can either be up or down.
......
...@@ -35,4 +35,4 @@ public final class ClusterMessageSerializer extends Serializer<ClusterMessage> { ...@@ -35,4 +35,4 @@ public final class ClusterMessageSerializer extends Serializer<ClusterMessage> {
35 byte[] payload = input.readBytes(payloadSize); 35 byte[] payload = input.readBytes(payloadSize);
36 return new ClusterMessage(sender, subject, payload); 36 return new ClusterMessage(sender, subject, payload);
37 } 37 }
38 -}
...\ No newline at end of file ...\ No newline at end of file
38 +}
......
1 +package org.onlab.onos.store.serializers;
2 +
3 +import org.onlab.onos.store.common.impl.MastershipBasedTimestamp;
4 +import org.onlab.onos.store.common.impl.Timestamped;
5 +import org.onlab.util.KryoPool;
6 +
7 +public final class DistributedStoreSerializers {
8 +
9 + /**
10 + * KryoPool which can serialize ON.lab misc classes.
11 + */
12 + public static final KryoPool COMMON = KryoPool.newBuilder()
13 + .register(KryoPoolUtil.API)
14 + .register(Timestamped.class)
15 + .register(MastershipBasedTimestamp.class, new MastershipBasedTimestampSerializer())
16 + .build();
17 +
18 + // avoid instantiation
19 + private DistributedStoreSerializers() {}
20 +}
...@@ -25,6 +25,7 @@ import org.onlab.onos.net.PortNumber; ...@@ -25,6 +25,7 @@ import org.onlab.onos.net.PortNumber;
25 import org.onlab.onos.net.device.DefaultDeviceDescription; 25 import org.onlab.onos.net.device.DefaultDeviceDescription;
26 import org.onlab.onos.net.device.DefaultPortDescription; 26 import org.onlab.onos.net.device.DefaultPortDescription;
27 import org.onlab.onos.net.provider.ProviderId; 27 import org.onlab.onos.net.provider.ProviderId;
28 +import org.onlab.onos.store.Timestamp;
28 import org.onlab.packet.IpAddress; 29 import org.onlab.packet.IpAddress;
29 import org.onlab.packet.IpPrefix; 30 import org.onlab.packet.IpPrefix;
30 import org.onlab.util.KryoPool; 31 import org.onlab.util.KryoPool;
...@@ -63,7 +64,9 @@ public final class KryoPoolUtil { ...@@ -63,7 +64,9 @@ public final class KryoPoolUtil {
63 Port.class, 64 Port.class,
64 DefaultPortDescription.class, 65 DefaultPortDescription.class,
65 Element.class, 66 Element.class,
66 - Link.Type.class 67 + Link.Type.class,
68 + Timestamp.class
69 +
67 ) 70 )
68 .register(URI.class, new URISerializer()) 71 .register(URI.class, new URISerializer())
69 .register(NodeId.class, new NodeIdSerializer()) 72 .register(NodeId.class, new NodeIdSerializer())
......
1 package org.onlab.onos.store.serializers; 1 package org.onlab.onos.store.serializers;
2 2
3 import org.onlab.util.KryoPool; 3 import org.onlab.util.KryoPool;
4 -import org.slf4j.Logger;
5 -import org.slf4j.LoggerFactory;
6 -
7 import java.nio.ByteBuffer; 4 import java.nio.ByteBuffer;
8 5
9 /** 6 /**
...@@ -11,10 +8,8 @@ import java.nio.ByteBuffer; ...@@ -11,10 +8,8 @@ import java.nio.ByteBuffer;
11 */ 8 */
12 public class KryoSerializer implements StoreSerializer { 9 public class KryoSerializer implements StoreSerializer {
13 10
14 - private final Logger log = LoggerFactory.getLogger(getClass());
15 protected KryoPool serializerPool; 11 protected KryoPool serializerPool;
16 12
17 -
18 public KryoSerializer() { 13 public KryoSerializer() {
19 setupKryoPool(); 14 setupKryoPool();
20 } 15 }
......