Madan Jampani

Preliminary checkin for implementing version aware topology state.

...@@ -16,6 +16,7 @@ import org.onlab.onos.cluster.ClusterService; ...@@ -16,6 +16,7 @@ import org.onlab.onos.cluster.ClusterService;
16 import org.onlab.onos.cluster.MastershipEvent; 16 import org.onlab.onos.cluster.MastershipEvent;
17 import org.onlab.onos.cluster.MastershipListener; 17 import org.onlab.onos.cluster.MastershipListener;
18 import org.onlab.onos.cluster.MastershipService; 18 import org.onlab.onos.cluster.MastershipService;
19 +import org.onlab.onos.cluster.MastershipTerm;
19 import org.onlab.onos.event.AbstractListenerRegistry; 20 import org.onlab.onos.event.AbstractListenerRegistry;
20 import org.onlab.onos.event.EventDeliveryService; 21 import org.onlab.onos.event.EventDeliveryService;
21 import org.onlab.onos.net.Device; 22 import org.onlab.onos.net.Device;
...@@ -36,6 +37,7 @@ import org.onlab.onos.net.device.DeviceStoreDelegate; ...@@ -36,6 +37,7 @@ import org.onlab.onos.net.device.DeviceStoreDelegate;
36 import org.onlab.onos.net.device.PortDescription; 37 import org.onlab.onos.net.device.PortDescription;
37 import org.onlab.onos.net.provider.AbstractProviderRegistry; 38 import org.onlab.onos.net.provider.AbstractProviderRegistry;
38 import org.onlab.onos.net.provider.AbstractProviderService; 39 import org.onlab.onos.net.provider.AbstractProviderService;
40 +import org.onlab.onos.store.common.ClockService;
39 import org.slf4j.Logger; 41 import org.slf4j.Logger;
40 42
41 /** 43 /**
...@@ -74,6 +76,9 @@ implements DeviceService, DeviceAdminService, DeviceProviderRegistry { ...@@ -74,6 +76,9 @@ implements DeviceService, DeviceAdminService, DeviceProviderRegistry {
74 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 76 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
75 protected MastershipService mastershipService; 77 protected MastershipService mastershipService;
76 78
79 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
80 + protected ClockService clockService;
81 +
77 @Activate 82 @Activate
78 public void activate() { 83 public void activate() {
79 store.setDelegate(delegate); 84 store.setDelegate(delegate);
...@@ -250,6 +255,8 @@ implements DeviceService, DeviceAdminService, DeviceProviderRegistry { ...@@ -250,6 +255,8 @@ implements DeviceService, DeviceAdminService, DeviceProviderRegistry {
250 @Override 255 @Override
251 public void event(MastershipEvent event) { 256 public void event(MastershipEvent event) {
252 if (event.master().equals(clusterService.getLocalNode().id())) { 257 if (event.master().equals(clusterService.getLocalNode().id())) {
258 + MastershipTerm term = mastershipService.requestTermService().getMastershipTerm(event.subject());
259 + clockService.setMastershipTerm(event.subject(), term);
253 applyRole(event.subject(), MastershipRole.MASTER); 260 applyRole(event.subject(), MastershipRole.MASTER);
254 } else { 261 } else {
255 applyRole(event.subject(), MastershipRole.STANDBY); 262 applyRole(event.subject(), MastershipRole.STANDBY);
......
1 +package org.onlab.onos.store.common;
2 +
3 +import org.onlab.onos.cluster.MastershipTerm;
4 +import org.onlab.onos.net.DeviceId;
5 +import org.onlab.onos.store.Timestamp;
6 +
7 +/**
8 + * Interface for a logical clock service that vends per device timestamps.
9 + */
10 +public interface ClockService {
11 +
12 + /**
13 + * Returns a new timestamp for the specified deviceId.
14 + * @param deviceId device identifier.
15 + * @return timestamp.
16 + */
17 + public Timestamp getTimestamp(DeviceId deviceId);
18 +
19 + /**
20 + * Updates the mastership term for the specified deviceId.
21 + * @param deviceId device identifier.
22 + * @param term mastership term.
23 + */
24 + public void setMastershipTerm(DeviceId deviceId, MastershipTerm term);
25 +}
1 +package org.onlab.onos.store.device.impl;
2 +
3 +import static org.slf4j.LoggerFactory.getLogger;
4 +
5 +import java.util.concurrent.ConcurrentHashMap;
6 +import java.util.concurrent.ConcurrentMap;
7 +import java.util.concurrent.atomic.AtomicInteger;
8 +
9 +import org.apache.felix.scr.annotations.Activate;
10 +import org.apache.felix.scr.annotations.Component;
11 +import org.apache.felix.scr.annotations.Deactivate;
12 +import org.apache.felix.scr.annotations.Service;
13 +import org.onlab.onos.cluster.MastershipTerm;
14 +import org.onlab.onos.net.DeviceId;
15 +import org.onlab.onos.store.Timestamp;
16 +import org.onlab.onos.store.common.ClockService;
17 +import org.onlab.onos.store.impl.OnosTimestamp;
18 +import org.slf4j.Logger;
19 +
20 +@Component(immediate = true)
21 +@Service
22 +public class OnosClockService implements ClockService {
23 +
24 + private final Logger log = getLogger(getClass());
25 +
26 + // TODO: Implement per device ticker that is reset to 0 at the beginning of a new term.
27 + private final AtomicInteger ticker = new AtomicInteger(0);
28 + private ConcurrentMap<DeviceId, MastershipTerm> deviceMastershipTerms = new ConcurrentHashMap<>();
29 +
30 + @Activate
31 + public void activate() {
32 + log.info("Started");
33 + }
34 +
35 + @Deactivate
36 + public void deactivate() {
37 + log.info("Stopped");
38 + }
39 +
40 + @Override
41 + public Timestamp getTimestamp(DeviceId deviceId) {
42 + MastershipTerm term = deviceMastershipTerms.get(deviceId);
43 + if (term == null) {
44 + throw new IllegalStateException("Requesting timestamp for a deviceId without mastership");
45 + }
46 + return new OnosTimestamp(term.termNumber(), ticker.incrementAndGet());
47 + }
48 +
49 + @Override
50 + public void setMastershipTerm(DeviceId deviceId, MastershipTerm term) {
51 + deviceMastershipTerms.put(deviceId, term);
52 + }
53 +}
1 +package org.onlab.onos.store.device.impl;
2 +
3 +import static com.google.common.base.Predicates.notNull;
4 +
5 +import com.google.common.base.Preconditions;
6 +import com.google.common.collect.FluentIterable;
7 +import com.google.common.collect.ImmutableSet;
8 +import com.google.common.collect.ImmutableSet.Builder;
9 +
10 +import org.apache.felix.scr.annotations.Activate;
11 +import org.apache.felix.scr.annotations.Component;
12 +import org.apache.felix.scr.annotations.Deactivate;
13 +import org.apache.felix.scr.annotations.Reference;
14 +import org.apache.felix.scr.annotations.ReferenceCardinality;
15 +import org.apache.felix.scr.annotations.Service;
16 +import org.onlab.onos.net.DefaultDevice;
17 +import org.onlab.onos.net.DefaultPort;
18 +import org.onlab.onos.net.Device;
19 +import org.onlab.onos.net.DeviceId;
20 +import org.onlab.onos.net.Port;
21 +import org.onlab.onos.net.PortNumber;
22 +import org.onlab.onos.net.device.DeviceDescription;
23 +import org.onlab.onos.net.device.DeviceEvent;
24 +import org.onlab.onos.net.device.DeviceStore;
25 +import org.onlab.onos.net.device.DeviceStoreDelegate;
26 +import org.onlab.onos.net.device.PortDescription;
27 +import org.onlab.onos.net.provider.ProviderId;
28 +import org.onlab.onos.store.Timestamp;
29 +import org.onlab.onos.store.common.ClockService;
30 +import org.onlab.onos.store.impl.AbstractDistributedStore;
31 +import org.slf4j.Logger;
32 +
33 +import java.util.ArrayList;
34 +import java.util.Collections;
35 +import java.util.HashMap;
36 +import java.util.HashSet;
37 +import java.util.Iterator;
38 +import java.util.List;
39 +import java.util.Map;
40 +import java.util.Objects;
41 +import java.util.Set;
42 +import java.util.concurrent.ConcurrentHashMap;
43 +
44 +import static com.google.common.base.Preconditions.checkArgument;
45 +import static org.onlab.onos.net.device.DeviceEvent.Type.*;
46 +import static org.slf4j.LoggerFactory.getLogger;
47 +
48 +/**
49 + * Manages inventory of infrastructure devices using a protocol that takes into consideration
50 + * the order in which device events occur.
51 + */
52 +@Component(immediate = true)
53 +@Service
54 +public class OnosDistributedDeviceStore
55 + extends AbstractDistributedStore<DeviceEvent, DeviceStoreDelegate>
56 + implements DeviceStore {
57 +
58 + private final Logger log = getLogger(getClass());
59 +
60 + public static final String DEVICE_NOT_FOUND = "Device with ID %s not found";
61 +
62 + private ConcurrentHashMap<DeviceId, VersionedValue<Device>> devices;
63 + private ConcurrentHashMap<DeviceId, Map<PortNumber, VersionedValue<Port>>> devicePorts;
64 +
65 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
66 + protected ClockService clockService;
67 +
68 + @Override
69 + @Activate
70 + public void activate() {
71 + super.activate();
72 +
73 + devices = new ConcurrentHashMap<>();
74 + devicePorts = new ConcurrentHashMap<>();
75 +
76 + log.info("Started");
77 + }
78 +
79 + @Deactivate
80 + public void deactivate() {
81 + log.info("Stopped");
82 + }
83 +
84 + @Override
85 + public int getDeviceCount() {
86 + return devices.size();
87 + }
88 +
89 + @Override
90 + public Iterable<Device> getDevices() {
91 + // TODO builder v.s. copyOf. Guava semms to be using copyOf?
92 + // FIXME: synchronize.
93 + Builder<Device> builder = ImmutableSet.builder();
94 + for (VersionedValue<? extends Device> device : devices.values()) {
95 + builder.add(device.entity());
96 + }
97 + return builder.build();
98 + }
99 +
100 + @Override
101 + public Device getDevice(DeviceId deviceId) {
102 + return devices.get(deviceId).entity();
103 + }
104 +
105 + @Override
106 + public DeviceEvent createOrUpdateDevice(ProviderId providerId, DeviceId deviceId,
107 + DeviceDescription deviceDescription) {
108 + Timestamp now = clockService.getTimestamp(deviceId);
109 + VersionedValue<Device> device = devices.get(deviceId);
110 +
111 + if (device == null) {
112 + return createDevice(providerId, deviceId, deviceDescription, now);
113 + }
114 +
115 + Preconditions.checkState(now.compareTo(device.timestamp()) > 0, "Existing device has a timestamp in the future!");
116 +
117 + return updateDevice(providerId, device.entity(), deviceDescription, now);
118 + }
119 +
120 + // Creates the device and returns the appropriate event if necessary.
121 + private DeviceEvent createDevice(ProviderId providerId, DeviceId deviceId,
122 + DeviceDescription desc, Timestamp timestamp) {
123 + DefaultDevice device = new DefaultDevice(providerId, deviceId, desc.type(),
124 + desc.manufacturer(),
125 + desc.hwVersion(), desc.swVersion(),
126 + desc.serialNumber());
127 +
128 + devices.put(deviceId, new VersionedValue<Device>(device, true, timestamp));
129 + // FIXME: broadcast a message telling peers of a device event.
130 + return new DeviceEvent(DEVICE_ADDED, device, null);
131 + }
132 +
133 + // Updates the device and returns the appropriate event if necessary.
134 + private DeviceEvent updateDevice(ProviderId providerId, Device device,
135 + DeviceDescription desc, Timestamp timestamp) {
136 + // We allow only certain attributes to trigger update
137 + if (!Objects.equals(device.hwVersion(), desc.hwVersion()) ||
138 + !Objects.equals(device.swVersion(), desc.swVersion())) {
139 +
140 + Device updated = new DefaultDevice(providerId, device.id(),
141 + desc.type(),
142 + desc.manufacturer(),
143 + desc.hwVersion(),
144 + desc.swVersion(),
145 + desc.serialNumber());
146 + devices.put(device.id(), new VersionedValue<Device>(updated, true, timestamp));
147 + // FIXME: broadcast a message telling peers of a device event.
148 + return new DeviceEvent(DeviceEvent.Type.DEVICE_UPDATED, updated, null);
149 + }
150 +
151 + // Otherwise merely attempt to change availability
152 + DefaultDevice updated = new DefaultDevice(providerId, device.id(),
153 + desc.type(),
154 + desc.manufacturer(),
155 + desc.hwVersion(),
156 + desc.swVersion(),
157 + desc.serialNumber());
158 +
159 + VersionedValue<Device> oldDevice = devices.put(device.id(), new VersionedValue<Device>(updated, true, timestamp));
160 + if (!oldDevice.isUp()) {
161 + return new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, device, null);
162 + } else {
163 + return null;
164 + }
165 + }
166 +
167 + @Override
168 + public DeviceEvent markOffline(DeviceId deviceId) {
169 + VersionedValue<Device> device = devices.get(deviceId);
170 + boolean willRemove = device != null && device.isUp();
171 + if (!willRemove) return null;
172 + Timestamp timestamp = clockService.getTimestamp(deviceId);
173 + if (replaceIfLatest(device.entity(), false, timestamp))
174 + {
175 + return new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, device.entity(), null);
176 + }
177 + return null;
178 + }
179 +
180 + // Replace existing value if its timestamp is older.
181 + private synchronized boolean replaceIfLatest(Device device, boolean isUp, Timestamp timestamp)
182 + {
183 + VersionedValue<Device> existingValue = devices.get(device.id());
184 + if (timestamp.compareTo(existingValue.timestamp()) > 0)
185 + {
186 + devices.put(device.id(), new VersionedValue<Device>(device, isUp, timestamp));
187 + return true;
188 + }
189 + return false;
190 + }
191 +
192 + @Override
193 + public List<DeviceEvent> updatePorts(DeviceId deviceId,
194 + List<PortDescription> portDescriptions) {
195 + List<DeviceEvent> events = new ArrayList<>();
196 + synchronized (this) {
197 + VersionedValue<Device> device = devices.get(deviceId);
198 + checkArgument(device != null, DEVICE_NOT_FOUND, deviceId);
199 + Map<PortNumber, VersionedValue<Port>> ports = getPortMap(deviceId);
200 + Timestamp timestamp = clockService.getTimestamp(deviceId);
201 +
202 + // Add new ports
203 + Set<PortNumber> processed = new HashSet<>();
204 + for (PortDescription portDescription : portDescriptions) {
205 + VersionedValue<Port> port = ports.get(portDescription.portNumber());
206 + if (port == null) events.add(createPort(device, portDescription, ports, timestamp));
207 + Preconditions.checkState(timestamp.compareTo(port.timestamp()) > 0, "Existing port state has a timestamp in the future!");
208 + events.add(updatePort(device, port, portDescription, ports, timestamp));
209 + processed.add(portDescription.portNumber());
210 + }
211 +
212 + updatePortMap(deviceId, ports);
213 +
214 + events.addAll(pruneOldPorts(device.entity(), ports, processed));
215 + }
216 + return FluentIterable.from(events).filter(notNull()).toList();
217 + }
218 +
219 + // Creates a new port based on the port description adds it to the map and
220 + // Returns corresponding event.
221 + //@GuardedBy("this")
222 + private DeviceEvent createPort(VersionedValue<Device> device, PortDescription portDescription,
223 + Map<PortNumber, VersionedValue<Port>> ports, Timestamp timestamp) {
224 + Port port = new DefaultPort(device.entity(), portDescription.portNumber(),
225 + portDescription.isEnabled());
226 + ports.put(port.number(), new VersionedValue<Port>(port, true, timestamp));
227 + updatePortMap(device.entity().id(), ports);
228 + return new DeviceEvent(PORT_ADDED, device.entity(), port);
229 + }
230 +
231 + // Checks if the specified port requires update and if so, it replaces the
232 + // existing entry in the map and returns corresponding event.
233 + //@GuardedBy("this")
234 + private DeviceEvent updatePort(VersionedValue<Device> device, VersionedValue<Port> port,
235 + PortDescription portDescription,
236 + Map<PortNumber, VersionedValue<Port>> ports,
237 + Timestamp timestamp) {
238 + if (port.entity().isEnabled() != portDescription.isEnabled()) {
239 + VersionedValue<Port> updatedPort = new VersionedValue<Port>(
240 + new DefaultPort(device.entity(), portDescription.portNumber(),
241 + portDescription.isEnabled()),
242 + portDescription.isEnabled(),
243 + timestamp);
244 + ports.put(port.entity().number(), updatedPort);
245 + updatePortMap(device.entity().id(), ports);
246 + return new DeviceEvent(PORT_UPDATED, device.entity(), updatedPort.entity());
247 + }
248 + return null;
249 + }
250 +
251 + // Prunes the specified list of ports based on which ports are in the
252 + // processed list and returns list of corresponding events.
253 + //@GuardedBy("this")
254 + private List<DeviceEvent> pruneOldPorts(Device device,
255 + Map<PortNumber, VersionedValue<Port>> ports,
256 + Set<PortNumber> processed) {
257 + List<DeviceEvent> events = new ArrayList<>();
258 + Iterator<PortNumber> iterator = ports.keySet().iterator();
259 + while (iterator.hasNext()) {
260 + PortNumber portNumber = iterator.next();
261 + if (!processed.contains(portNumber)) {
262 + events.add(new DeviceEvent(PORT_REMOVED, device,
263 + ports.get(portNumber).entity()));
264 + iterator.remove();
265 + }
266 + }
267 + if (!events.isEmpty()) {
268 + updatePortMap(device.id(), ports);
269 + }
270 + return events;
271 + }
272 +
273 + // Gets the map of ports for the specified device; if one does not already
274 + // exist, it creates and registers a new one.
275 + // WARN: returned value is a copy, changes made to the Map
276 + // needs to be written back using updatePortMap
277 + //@GuardedBy("this")
278 + private Map<PortNumber, VersionedValue<Port>> getPortMap(DeviceId deviceId) {
279 + Map<PortNumber, VersionedValue<Port>> ports = devicePorts.get(deviceId);
280 + if (ports == null) {
281 + ports = new HashMap<>();
282 + // this probably is waste of time in most cases.
283 + updatePortMap(deviceId, ports);
284 + }
285 + return ports;
286 + }
287 +
288 + //@GuardedBy("this")
289 + private void updatePortMap(DeviceId deviceId, Map<PortNumber, VersionedValue<Port>> ports) {
290 + devicePorts.put(deviceId, ports);
291 + }
292 +
293 + @Override
294 + public DeviceEvent updatePortStatus(DeviceId deviceId,
295 + PortDescription portDescription) {
296 + VersionedValue<Device> device = devices.get(deviceId);
297 + checkArgument(device != null, DEVICE_NOT_FOUND, deviceId);
298 + Map<PortNumber, VersionedValue<Port>> ports = getPortMap(deviceId);
299 + VersionedValue<Port> port = ports.get(portDescription.portNumber());
300 + Timestamp timestamp = clockService.getTimestamp(deviceId);
301 + return updatePort(device, port, portDescription, ports, timestamp);
302 + }
303 +
304 + @Override
305 + public List<Port> getPorts(DeviceId deviceId) {
306 + Map<PortNumber, VersionedValue<Port>> versionedPorts = devicePorts.get(deviceId);
307 + if (versionedPorts == null) return Collections.emptyList();
308 + List<Port> ports = new ArrayList<Port>();
309 + for (VersionedValue<Port> port : versionedPorts.values()) {
310 + ports.add(port.entity());
311 + }
312 + return ports;
313 + }
314 +
315 + @Override
316 + public Port getPort(DeviceId deviceId, PortNumber portNumber) {
317 + Map<PortNumber, VersionedValue<Port>> ports = devicePorts.get(deviceId);
318 + return ports == null ? null : ports.get(portNumber).entity();
319 + }
320 +
321 + @Override
322 + public boolean isAvailable(DeviceId deviceId) {
323 + return devices.get(deviceId).isUp();
324 + }
325 +
326 + @Override
327 + public DeviceEvent removeDevice(DeviceId deviceId) {
328 + VersionedValue<Device> previousDevice = devices.remove(deviceId);
329 + return previousDevice == null ? null :
330 + new DeviceEvent(DEVICE_REMOVED, previousDevice.entity(), null);
331 + }
332 +}
1 +package org.onlab.onos.store.device.impl;
2 +
3 +import org.onlab.onos.store.Timestamp;
4 +
5 +/**
6 + * Wrapper class for a entity that is versioned
7 + * and can either be up or down.
8 + *
9 + * @param <T> type of the value.
10 + */
11 +public class VersionedValue<T> {
12 + private final T entity;
13 + private final Timestamp timestamp;
14 + private final boolean isUp;
15 +
16 + public VersionedValue(T entity, boolean isUp, Timestamp timestamp) {
17 + this.entity = entity;
18 + this.isUp = isUp;
19 + this.timestamp = timestamp;
20 + }
21 +
22 + /**
23 + * Returns the value.
24 + * @return value.
25 + */
26 + public T entity() {
27 + return entity;
28 + }
29 +
30 + /**
31 + * Tells whether the entity is up or down.
32 + * @return true if up, false otherwise.
33 + */
34 + public boolean isUp() {
35 + return isUp;
36 + }
37 +
38 + /**
39 + * Returns the timestamp (version) associated with this entity.
40 + * @return timestamp.
41 + */
42 + public Timestamp timestamp() {
43 + return timestamp;
44 + }
45 +}
1 package org.onlab.onos.store.impl; 1 package org.onlab.onos.store.impl;
2 2
3 -import static com.google.common.base.Preconditions.checkNotNull;
4 import static com.google.common.base.Preconditions.checkArgument; 3 import static com.google.common.base.Preconditions.checkArgument;
5 4
6 import java.util.Objects; 5 import java.util.Objects;
7 6
8 -import org.onlab.onos.net.ElementId;
9 import org.onlab.onos.store.Timestamp; 7 import org.onlab.onos.store.Timestamp;
10 8
11 import com.google.common.base.MoreObjects; 9 import com.google.common.base.MoreObjects;
...@@ -14,22 +12,20 @@ import com.google.common.collect.ComparisonChain; ...@@ -14,22 +12,20 @@ import com.google.common.collect.ComparisonChain;
14 // If it is store specific, implement serializable interfaces? 12 // If it is store specific, implement serializable interfaces?
15 /** 13 /**
16 * Default implementation of Timestamp. 14 * Default implementation of Timestamp.
15 + * TODO: Better documentation.
17 */ 16 */
18 public final class OnosTimestamp implements Timestamp { 17 public final class OnosTimestamp implements Timestamp {
19 18
20 - private final ElementId id;
21 private final int termNumber; 19 private final int termNumber;
22 private final int sequenceNumber; 20 private final int sequenceNumber;
23 21
24 /** 22 /**
25 * Default version tuple. 23 * Default version tuple.
26 * 24 *
27 - * @param id identifier of the element
28 * @param termNumber the mastership termNumber 25 * @param termNumber the mastership termNumber
29 * @param sequenceNumber the sequenceNumber number within the termNumber 26 * @param sequenceNumber the sequenceNumber number within the termNumber
30 */ 27 */
31 - public OnosTimestamp(ElementId id, int termNumber, int sequenceNumber) { 28 + public OnosTimestamp(int termNumber, int sequenceNumber) {
32 - this.id = checkNotNull(id);
33 this.termNumber = termNumber; 29 this.termNumber = termNumber;
34 this.sequenceNumber = sequenceNumber; 30 this.sequenceNumber = sequenceNumber;
35 } 31 }
...@@ -38,9 +34,6 @@ public final class OnosTimestamp implements Timestamp { ...@@ -38,9 +34,6 @@ public final class OnosTimestamp implements Timestamp {
38 public int compareTo(Timestamp o) { 34 public int compareTo(Timestamp o) {
39 checkArgument(o instanceof OnosTimestamp, "Must be OnosTimestamp", o); 35 checkArgument(o instanceof OnosTimestamp, "Must be OnosTimestamp", o);
40 OnosTimestamp that = (OnosTimestamp) o; 36 OnosTimestamp that = (OnosTimestamp) o;
41 - checkArgument(this.id.equals(that.id),
42 - "Cannot compare version for different element this:%s, that:%s",
43 - this, that);
44 37
45 return ComparisonChain.start() 38 return ComparisonChain.start()
46 .compare(this.termNumber, that.termNumber) 39 .compare(this.termNumber, that.termNumber)
...@@ -50,7 +43,7 @@ public final class OnosTimestamp implements Timestamp { ...@@ -50,7 +43,7 @@ public final class OnosTimestamp implements Timestamp {
50 43
51 @Override 44 @Override
52 public int hashCode() { 45 public int hashCode() {
53 - return Objects.hash(id, termNumber, sequenceNumber); 46 + return Objects.hash(termNumber, sequenceNumber);
54 } 47 }
55 48
56 @Override 49 @Override
...@@ -62,30 +55,19 @@ public final class OnosTimestamp implements Timestamp { ...@@ -62,30 +55,19 @@ public final class OnosTimestamp implements Timestamp {
62 return false; 55 return false;
63 } 56 }
64 OnosTimestamp that = (OnosTimestamp) obj; 57 OnosTimestamp that = (OnosTimestamp) obj;
65 - return Objects.equals(this.id, that.id) && 58 + return Objects.equals(this.termNumber, that.termNumber) &&
66 - Objects.equals(this.termNumber, that.termNumber) &&
67 Objects.equals(this.sequenceNumber, that.sequenceNumber); 59 Objects.equals(this.sequenceNumber, that.sequenceNumber);
68 } 60 }
69 61
70 @Override 62 @Override
71 public String toString() { 63 public String toString() {
72 return MoreObjects.toStringHelper(getClass()) 64 return MoreObjects.toStringHelper(getClass())
73 - .add("id", id)
74 .add("termNumber", termNumber) 65 .add("termNumber", termNumber)
75 .add("sequenceNumber", sequenceNumber) 66 .add("sequenceNumber", sequenceNumber)
76 .toString(); 67 .toString();
77 } 68 }
78 69
79 /** 70 /**
80 - * Returns the element.
81 - *
82 - * @return element identifier
83 - */
84 - public ElementId id() {
85 - return id;
86 - }
87 -
88 - /**
89 * Returns the termNumber. 71 * Returns the termNumber.
90 * 72 *
91 * @return termNumber 73 * @return termNumber
...@@ -102,4 +84,4 @@ public final class OnosTimestamp implements Timestamp { ...@@ -102,4 +84,4 @@ public final class OnosTimestamp implements Timestamp {
102 public int sequenceNumber() { 84 public int sequenceNumber() {
103 return sequenceNumber; 85 return sequenceNumber;
104 } 86 }
105 -} 87 +}
...\ No newline at end of file ...\ No newline at end of file
......
1 package org.onlab.onos.store.serializers; 1 package org.onlab.onos.store.serializers;
2 2
3 -import org.onlab.onos.net.ElementId;
4 import org.onlab.onos.store.impl.OnosTimestamp; 3 import org.onlab.onos.store.impl.OnosTimestamp;
5 4
6 import com.esotericsoftware.kryo.Kryo; 5 import com.esotericsoftware.kryo.Kryo;
...@@ -20,18 +19,17 @@ public class OnosTimestampSerializer extends Serializer<OnosTimestamp> { ...@@ -20,18 +19,17 @@ public class OnosTimestampSerializer extends Serializer<OnosTimestamp> {
20 // non-null, immutable 19 // non-null, immutable
21 super(false, true); 20 super(false, true);
22 } 21 }
22 +
23 @Override 23 @Override
24 public void write(Kryo kryo, Output output, OnosTimestamp object) { 24 public void write(Kryo kryo, Output output, OnosTimestamp object) {
25 - kryo.writeClassAndObject(output, object.id());
26 output.writeInt(object.termNumber()); 25 output.writeInt(object.termNumber());
27 output.writeInt(object.sequenceNumber()); 26 output.writeInt(object.sequenceNumber());
28 } 27 }
29 28
30 @Override 29 @Override
31 public OnosTimestamp read(Kryo kryo, Input input, Class<OnosTimestamp> type) { 30 public OnosTimestamp read(Kryo kryo, Input input, Class<OnosTimestamp> type) {
32 - ElementId id = (ElementId) kryo.readClassAndObject(input);
33 final int term = input.readInt(); 31 final int term = input.readInt();
34 final int sequence = input.readInt(); 32 final int sequence = input.readInt();
35 - return new OnosTimestamp(id, term, sequence); 33 + return new OnosTimestamp(term, sequence);
36 } 34 }
37 } 35 }
......