Adding some tests for GossipDeviceStore + bugfix
Change-Id: Ic0d55fa499b1d66131f059b4a47cd105c55a6e63
Showing
6 changed files
with
112 additions
and
21 deletions
... | @@ -62,6 +62,11 @@ | ... | @@ -62,6 +62,11 @@ |
62 | <groupId>org.apache.commons</groupId> | 62 | <groupId>org.apache.commons</groupId> |
63 | <artifactId>commons-lang3</artifactId> | 63 | <artifactId>commons-lang3</artifactId> |
64 | </dependency> | 64 | </dependency> |
65 | + <dependency> | ||
66 | + <groupId>org.easymock</groupId> | ||
67 | + <artifactId>easymock</artifactId> | ||
68 | + <scope>test</scope> | ||
69 | + </dependency> | ||
65 | </dependencies> | 70 | </dependencies> |
66 | 71 | ||
67 | <build> | 72 | <build> | ... | ... |
... | @@ -58,7 +58,7 @@ class DeviceDescriptions { | ... | @@ -58,7 +58,7 @@ class DeviceDescriptions { |
58 | * | 58 | * |
59 | * @param newDesc new DeviceDescription | 59 | * @param newDesc new DeviceDescription |
60 | */ | 60 | */ |
61 | - public synchronized void putDeviceDesc(Timestamped<DeviceDescription> newDesc) { | 61 | + public void putDeviceDesc(Timestamped<DeviceDescription> newDesc) { |
62 | Timestamped<DeviceDescription> oldOne = deviceDesc; | 62 | Timestamped<DeviceDescription> oldOne = deviceDesc; |
63 | Timestamped<DeviceDescription> newOne = newDesc; | 63 | Timestamped<DeviceDescription> newOne = newDesc; |
64 | if (oldOne != null) { | 64 | if (oldOne != null) { |
... | @@ -76,7 +76,7 @@ class DeviceDescriptions { | ... | @@ -76,7 +76,7 @@ class DeviceDescriptions { |
76 | * | 76 | * |
77 | * @param newDesc new PortDescription | 77 | * @param newDesc new PortDescription |
78 | */ | 78 | */ |
79 | - public synchronized void putPortDesc(Timestamped<PortDescription> newDesc) { | 79 | + public void putPortDesc(Timestamped<PortDescription> newDesc) { |
80 | Timestamped<PortDescription> oldOne = portDescs.get(newDesc.value().portNumber()); | 80 | Timestamped<PortDescription> oldOne = portDescs.get(newDesc.value().portNumber()); |
81 | Timestamped<PortDescription> newOne = newDesc; | 81 | Timestamped<PortDescription> newOne = newDesc; |
82 | if (oldOne != null) { | 82 | if (oldOne != null) { | ... | ... |
1 | package org.onlab.onos.store.device.impl; | 1 | package org.onlab.onos.store.device.impl; |
2 | 2 | ||
3 | +import com.google.common.base.Function; | ||
3 | import com.google.common.collect.FluentIterable; | 4 | import com.google.common.collect.FluentIterable; |
4 | import com.google.common.collect.ImmutableList; | 5 | import com.google.common.collect.ImmutableList; |
5 | import com.google.common.collect.Maps; | 6 | import com.google.common.collect.Maps; |
... | @@ -118,7 +119,7 @@ public class GossipDeviceStore | ... | @@ -118,7 +119,7 @@ public class GossipDeviceStore |
118 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 119 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
119 | protected ClusterService clusterService; | 120 | protected ClusterService clusterService; |
120 | 121 | ||
121 | - private static final KryoSerializer SERIALIZER = new KryoSerializer() { | 122 | + protected static final KryoSerializer SERIALIZER = new KryoSerializer() { |
122 | @Override | 123 | @Override |
123 | protected void setupKryoPool() { | 124 | protected void setupKryoPool() { |
124 | serializerPool = KryoPool.newBuilder() | 125 | serializerPool = KryoPool.newBuilder() |
... | @@ -206,14 +207,19 @@ public class GossipDeviceStore | ... | @@ -206,14 +207,19 @@ public class GossipDeviceStore |
206 | public synchronized DeviceEvent createOrUpdateDevice(ProviderId providerId, | 207 | public synchronized DeviceEvent createOrUpdateDevice(ProviderId providerId, |
207 | DeviceId deviceId, | 208 | DeviceId deviceId, |
208 | DeviceDescription deviceDescription) { | 209 | DeviceDescription deviceDescription) { |
209 | - Timestamp newTimestamp = clockService.getTimestamp(deviceId); | 210 | + final Timestamp newTimestamp = clockService.getTimestamp(deviceId); |
210 | final Timestamped<DeviceDescription> deltaDesc = new Timestamped<>(deviceDescription, newTimestamp); | 211 | final Timestamped<DeviceDescription> deltaDesc = new Timestamped<>(deviceDescription, newTimestamp); |
211 | - DeviceEvent event = createOrUpdateDeviceInternal(providerId, deviceId, deltaDesc); | 212 | + final DeviceEvent event; |
213 | + final Timestamped<DeviceDescription> mergedDesc; | ||
214 | + synchronized (getDeviceDescriptions(deviceId)) { | ||
215 | + event = createOrUpdateDeviceInternal(providerId, deviceId, deltaDesc); | ||
216 | + mergedDesc = getDeviceDescriptions(deviceId).get(providerId).getDeviceDesc(); | ||
217 | + } | ||
212 | if (event != null) { | 218 | if (event != null) { |
213 | log.info("Notifying peers of a device update topology event for providerId: {} and deviceId: {}", | 219 | log.info("Notifying peers of a device update topology event for providerId: {} and deviceId: {}", |
214 | providerId, deviceId); | 220 | providerId, deviceId); |
215 | try { | 221 | try { |
216 | - notifyPeers(new InternalDeviceEvent(providerId, deviceId, deltaDesc)); | 222 | + notifyPeers(new InternalDeviceEvent(providerId, deviceId, mergedDesc)); |
217 | } catch (IOException e) { | 223 | } catch (IOException e) { |
218 | log.error("Failed to notify peers of a device update topology event for providerId: " | 224 | log.error("Failed to notify peers of a device update topology event for providerId: " |
219 | + providerId + " and deviceId: " + deviceId, e); | 225 | + providerId + " and deviceId: " + deviceId, e); |
... | @@ -317,8 +323,8 @@ public class GossipDeviceStore | ... | @@ -317,8 +323,8 @@ public class GossipDeviceStore |
317 | 323 | ||
318 | @Override | 324 | @Override |
319 | public DeviceEvent markOffline(DeviceId deviceId) { | 325 | public DeviceEvent markOffline(DeviceId deviceId) { |
320 | - Timestamp timestamp = clockService.getTimestamp(deviceId); | 326 | + final Timestamp timestamp = clockService.getTimestamp(deviceId); |
321 | - DeviceEvent event = markOfflineInternal(deviceId, timestamp); | 327 | + final DeviceEvent event = markOfflineInternal(deviceId, timestamp); |
322 | if (event != null) { | 328 | if (event != null) { |
323 | log.info("Notifying peers of a device offline topology event for deviceId: {}", | 329 | log.info("Notifying peers of a device offline topology event for deviceId: {}", |
324 | deviceId); | 330 | deviceId); |
... | @@ -390,17 +396,33 @@ public class GossipDeviceStore | ... | @@ -390,17 +396,33 @@ public class GossipDeviceStore |
390 | public synchronized List<DeviceEvent> updatePorts(ProviderId providerId, | 396 | public synchronized List<DeviceEvent> updatePorts(ProviderId providerId, |
391 | DeviceId deviceId, | 397 | DeviceId deviceId, |
392 | List<PortDescription> portDescriptions) { | 398 | List<PortDescription> portDescriptions) { |
393 | - Timestamp newTimestamp = clockService.getTimestamp(deviceId); | ||
394 | 399 | ||
395 | - Timestamped<List<PortDescription>> timestampedPortDescriptions = | 400 | + final Timestamp newTimestamp = clockService.getTimestamp(deviceId); |
396 | - new Timestamped<>(portDescriptions, newTimestamp); | 401 | + |
397 | - | 402 | + final Timestamped<List<PortDescription>> timestampedInput |
398 | - List<DeviceEvent> events = updatePortsInternal(providerId, deviceId, timestampedPortDescriptions); | 403 | + = new Timestamped<>(portDescriptions, newTimestamp); |
404 | + final List<DeviceEvent> events; | ||
405 | + final Timestamped<List<PortDescription>> merged; | ||
406 | + | ||
407 | + synchronized (getDeviceDescriptions(deviceId)) { | ||
408 | + events = updatePortsInternal(providerId, deviceId, timestampedInput); | ||
409 | + final DeviceDescriptions descs = getDeviceDescriptions(deviceId).get(providerId); | ||
410 | + List<PortDescription> mergedList = | ||
411 | + FluentIterable.from(portDescriptions) | ||
412 | + .transform(new Function<PortDescription, PortDescription>() { | ||
413 | + @Override | ||
414 | + public PortDescription apply(PortDescription input) { | ||
415 | + // lookup merged port description | ||
416 | + return descs.getPortDesc(input.portNumber()).value(); | ||
417 | + } | ||
418 | + }).toList(); | ||
419 | + merged = new Timestamped<List<PortDescription>>(mergedList, newTimestamp); | ||
420 | + } | ||
399 | if (!events.isEmpty()) { | 421 | if (!events.isEmpty()) { |
400 | log.info("Notifying peers of a port update topology event for providerId: {} and deviceId: {}", | 422 | log.info("Notifying peers of a port update topology event for providerId: {} and deviceId: {}", |
401 | providerId, deviceId); | 423 | providerId, deviceId); |
402 | try { | 424 | try { |
403 | - notifyPeers(new InternalPortEvent(providerId, deviceId, timestampedPortDescriptions)); | 425 | + notifyPeers(new InternalPortEvent(providerId, deviceId, merged)); |
404 | } catch (IOException e) { | 426 | } catch (IOException e) { |
405 | log.error("Failed to notify peers of a port update topology event or providerId: " | 427 | log.error("Failed to notify peers of a port update topology event or providerId: " |
406 | + providerId + " and deviceId: " + deviceId, e); | 428 | + providerId + " and deviceId: " + deviceId, e); |
... | @@ -527,16 +549,25 @@ public class GossipDeviceStore | ... | @@ -527,16 +549,25 @@ public class GossipDeviceStore |
527 | } | 549 | } |
528 | 550 | ||
529 | @Override | 551 | @Override |
530 | - public synchronized DeviceEvent updatePortStatus(ProviderId providerId, DeviceId deviceId, | 552 | + public synchronized DeviceEvent updatePortStatus(ProviderId providerId, |
531 | - PortDescription portDescription) { | 553 | + DeviceId deviceId, |
532 | - Timestamp newTimestamp = clockService.getTimestamp(deviceId); | 554 | + PortDescription portDescription) { |
533 | - final Timestamped<PortDescription> deltaDesc = new Timestamped<>(portDescription, newTimestamp); | 555 | + |
534 | - DeviceEvent event = updatePortStatusInternal(providerId, deviceId, deltaDesc); | 556 | + final Timestamp newTimestamp = clockService.getTimestamp(deviceId); |
557 | + final Timestamped<PortDescription> deltaDesc | ||
558 | + = new Timestamped<>(portDescription, newTimestamp); | ||
559 | + final DeviceEvent event; | ||
560 | + final Timestamped<PortDescription> mergedDesc; | ||
561 | + synchronized (getDeviceDescriptions(deviceId)) { | ||
562 | + event = updatePortStatusInternal(providerId, deviceId, deltaDesc); | ||
563 | + mergedDesc = getDeviceDescriptions(deviceId).get(providerId) | ||
564 | + .getPortDesc(portDescription.portNumber()); | ||
565 | + } | ||
535 | if (event != null) { | 566 | if (event != null) { |
536 | log.info("Notifying peers of a port status update topology event for providerId: {} and deviceId: {}", | 567 | log.info("Notifying peers of a port status update topology event for providerId: {} and deviceId: {}", |
537 | providerId, deviceId); | 568 | providerId, deviceId); |
538 | try { | 569 | try { |
539 | - notifyPeers(new InternalPortStatusEvent(providerId, deviceId, deltaDesc)); | 570 | + notifyPeers(new InternalPortStatusEvent(providerId, deviceId, mergedDesc)); |
540 | } catch (IOException e) { | 571 | } catch (IOException e) { |
541 | log.error("Failed to notify peers of a port status update topology event or providerId: " | 572 | log.error("Failed to notify peers of a port status update topology event or providerId: " |
542 | + providerId + " and deviceId: " + deviceId, e); | 573 | + providerId + " and deviceId: " + deviceId, e); |
... | @@ -684,7 +715,7 @@ public class GossipDeviceStore | ... | @@ -684,7 +715,7 @@ public class GossipDeviceStore |
684 | * @return Device instance | 715 | * @return Device instance |
685 | */ | 716 | */ |
686 | private Device composeDevice(DeviceId deviceId, | 717 | private Device composeDevice(DeviceId deviceId, |
687 | - ConcurrentMap<ProviderId, DeviceDescriptions> providerDescs) { | 718 | + Map<ProviderId, DeviceDescriptions> providerDescs) { |
688 | 719 | ||
689 | checkArgument(!providerDescs.isEmpty(), "No Device descriptions supplied"); | 720 | checkArgument(!providerDescs.isEmpty(), "No Device descriptions supplied"); |
690 | 721 | ... | ... |
This diff is collapsed. Click to expand it.
core/store/serializers/src/main/java/org/onlab/onos/store/serializers/ImmutableListSerializer.java
0 → 100644
1 | +package org.onlab.onos.store.serializers; | ||
2 | + | ||
3 | +import org.onlab.util.KryoPool.FamilySerializer; | ||
4 | + | ||
5 | +import com.esotericsoftware.kryo.Kryo; | ||
6 | +import com.esotericsoftware.kryo.io.Input; | ||
7 | +import com.esotericsoftware.kryo.io.Output; | ||
8 | +import com.google.common.collect.ImmutableList; | ||
9 | +import com.google.common.collect.ImmutableList.Builder; | ||
10 | + | ||
11 | +/** | ||
12 | + * Creates {@link ImmutableList} serializer instance. | ||
13 | + */ | ||
14 | +public class ImmutableListSerializer extends FamilySerializer<ImmutableList<?>> { | ||
15 | + | ||
16 | + /** | ||
17 | + * Creates {@link ImmutableList} serializer instance. | ||
18 | + */ | ||
19 | + public ImmutableListSerializer() { | ||
20 | + // non-null, immutable | ||
21 | + super(false, true); | ||
22 | + } | ||
23 | + @Override | ||
24 | + public void write(Kryo kryo, Output output, ImmutableList<?> object) { | ||
25 | + output.writeInt(object.size()); | ||
26 | + for (Object e : object) { | ||
27 | + kryo.writeClassAndObject(output, e); | ||
28 | + } | ||
29 | + } | ||
30 | + | ||
31 | + @Override | ||
32 | + public ImmutableList<?> read(Kryo kryo, Input input, | ||
33 | + Class<ImmutableList<?>> type) { | ||
34 | + final int size = input.readInt(); | ||
35 | + Builder<Object> builder = ImmutableList.builder(); | ||
36 | + for (int i = 0; i < size; ++i) { | ||
37 | + builder.add(kryo.readClassAndObject(input)); | ||
38 | + } | ||
39 | + return builder.build(); | ||
40 | + } | ||
41 | + | ||
42 | + @Override | ||
43 | + public void registerFamilies(Kryo kryo) { | ||
44 | + kryo.register(ImmutableList.of(1).getClass(), this); | ||
45 | + kryo.register(ImmutableList.of(1, 2).getClass(), this); | ||
46 | + // TODO register required ImmutableList variants | ||
47 | + } | ||
48 | + | ||
49 | +} |
... | @@ -31,6 +31,9 @@ import org.onlab.packet.IpAddress; | ... | @@ -31,6 +31,9 @@ import org.onlab.packet.IpAddress; |
31 | import org.onlab.packet.IpPrefix; | 31 | import org.onlab.packet.IpPrefix; |
32 | import org.onlab.util.KryoPool; | 32 | import org.onlab.util.KryoPool; |
33 | 33 | ||
34 | +import com.google.common.collect.ImmutableList; | ||
35 | +import com.google.common.collect.ImmutableMap; | ||
36 | + | ||
34 | public final class KryoPoolUtil { | 37 | public final class KryoPoolUtil { |
35 | 38 | ||
36 | /** | 39 | /** |
... | @@ -47,12 +50,15 @@ public final class KryoPoolUtil { | ... | @@ -47,12 +50,15 @@ public final class KryoPoolUtil { |
47 | */ | 50 | */ |
48 | public static final KryoPool API = KryoPool.newBuilder() | 51 | public static final KryoPool API = KryoPool.newBuilder() |
49 | .register(MISC) | 52 | .register(MISC) |
53 | + .register(ImmutableMap.class, new ImmutableMapSerializer()) | ||
54 | + .register(ImmutableList.class, new ImmutableListSerializer()) | ||
50 | .register( | 55 | .register( |
51 | // | 56 | // |
52 | ArrayList.class, | 57 | ArrayList.class, |
53 | Arrays.asList().getClass(), | 58 | Arrays.asList().getClass(), |
54 | HashMap.class, | 59 | HashMap.class, |
55 | // | 60 | // |
61 | + // | ||
56 | ControllerNode.State.class, | 62 | ControllerNode.State.class, |
57 | Device.Type.class, | 63 | Device.Type.class, |
58 | DefaultAnnotations.class, | 64 | DefaultAnnotations.class, | ... | ... |
-
Please register or login to post a comment