Committed by
Gerrit Code Review
Modifying eventually consistent map and tests to make use of the persistence service.
Change-Id: I44ffcabb9d765a1c70c2790366c6d7381416dac6
Showing
6 changed files
with
60 additions
and
36 deletions
| ... | @@ -30,7 +30,8 @@ import org.onlab.util.KryoNamespace; | ... | @@ -30,7 +30,8 @@ import org.onlab.util.KryoNamespace; |
| 30 | import org.onosproject.cluster.NodeId; | 30 | import org.onosproject.cluster.NodeId; |
| 31 | import org.onosproject.store.Timestamp; | 31 | import org.onosproject.store.Timestamp; |
| 32 | 32 | ||
| 33 | -import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.*; | 33 | +import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.PUT; |
| 34 | +import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.REMOVE; | ||
| 34 | 35 | ||
| 35 | /** | 36 | /** |
| 36 | * Testing version of an Eventually Consistent Map. | 37 | * Testing version of an Eventually Consistent Map. | ... | ... |
| ... | @@ -69,6 +69,12 @@ | ... | @@ -69,6 +69,12 @@ |
| 69 | </dependency> | 69 | </dependency> |
| 70 | 70 | ||
| 71 | <dependency> | 71 | <dependency> |
| 72 | + <groupId>org.onosproject</groupId> | ||
| 73 | + <artifactId>onos-core-persistence</artifactId> | ||
| 74 | + <version>${project.version}</version> | ||
| 75 | + </dependency> | ||
| 76 | + | ||
| 77 | + <dependency> | ||
| 72 | <groupId>org.mapdb</groupId> | 78 | <groupId>org.mapdb</groupId> |
| 73 | <artifactId>mapdb</artifactId> | 79 | <artifactId>mapdb</artifactId> |
| 74 | <version>1.0.8</version> | 80 | <version>1.0.8</version> |
| ... | @@ -110,5 +116,4 @@ | ... | @@ -110,5 +116,4 @@ |
| 110 | <artifactId>onlab-thirdparty</artifactId> | 116 | <artifactId>onlab-thirdparty</artifactId> |
| 111 | </dependency> | 117 | </dependency> |
| 112 | </dependencies> | 118 | </dependencies> |
| 113 | - | ||
| 114 | </project> | 119 | </project> | ... | ... |
| ... | @@ -55,6 +55,7 @@ import org.onosproject.cluster.ControllerNode; | ... | @@ -55,6 +55,7 @@ import org.onosproject.cluster.ControllerNode; |
| 55 | import org.onosproject.cluster.NodeId; | 55 | import org.onosproject.cluster.NodeId; |
| 56 | import org.onosproject.core.ApplicationId; | 56 | import org.onosproject.core.ApplicationId; |
| 57 | import org.onosproject.core.IdGenerator; | 57 | import org.onosproject.core.IdGenerator; |
| 58 | +import org.onosproject.persistence.PersistenceService; | ||
| 58 | import org.onosproject.store.cluster.messaging.ClusterCommunicationService; | 59 | import org.onosproject.store.cluster.messaging.ClusterCommunicationService; |
| 59 | import org.onosproject.store.ecmap.EventuallyConsistentMapBuilderImpl; | 60 | import org.onosproject.store.ecmap.EventuallyConsistentMapBuilderImpl; |
| 60 | import org.onosproject.store.service.AtomicCounterBuilder; | 61 | import org.onosproject.store.service.AtomicCounterBuilder; |
| ... | @@ -128,6 +129,9 @@ public class DatabaseManager implements StorageService, StorageAdminService { | ... | @@ -128,6 +129,9 @@ public class DatabaseManager implements StorageService, StorageAdminService { |
| 128 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 129 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| 129 | protected ClusterCommunicationService clusterCommunicator; | 130 | protected ClusterCommunicationService clusterCommunicator; |
| 130 | 131 | ||
| 132 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 133 | + protected PersistenceService persistenceService; | ||
| 134 | + | ||
| 131 | protected String nodeIdToUri(NodeId nodeId) { | 135 | protected String nodeIdToUri(NodeId nodeId) { |
| 132 | ControllerNode node = clusterService.getNode(nodeId); | 136 | ControllerNode node = clusterService.getNode(nodeId); |
| 133 | return String.format("onos://%s:%d", node.ip(), node.tcpPort()); | 137 | return String.format("onos://%s:%d", node.ip(), node.tcpPort()); |
| ... | @@ -312,7 +316,8 @@ public class DatabaseManager implements StorageService, StorageAdminService { | ... | @@ -312,7 +316,8 @@ public class DatabaseManager implements StorageService, StorageAdminService { |
| 312 | @Override | 316 | @Override |
| 313 | public <K, V> EventuallyConsistentMapBuilder<K, V> eventuallyConsistentMapBuilder() { | 317 | public <K, V> EventuallyConsistentMapBuilder<K, V> eventuallyConsistentMapBuilder() { |
| 314 | return new EventuallyConsistentMapBuilderImpl<>(clusterService, | 318 | return new EventuallyConsistentMapBuilderImpl<>(clusterService, |
| 315 | - clusterCommunicator); | 319 | + clusterCommunicator, |
| 320 | + persistenceService); | ||
| 316 | } | 321 | } |
| 317 | 322 | ||
| 318 | @Override | 323 | @Override | ... | ... |
| ... | @@ -18,6 +18,7 @@ package org.onosproject.store.ecmap; | ... | @@ -18,6 +18,7 @@ package org.onosproject.store.ecmap; |
| 18 | import org.onlab.util.KryoNamespace; | 18 | import org.onlab.util.KryoNamespace; |
| 19 | import org.onosproject.cluster.ClusterService; | 19 | import org.onosproject.cluster.ClusterService; |
| 20 | import org.onosproject.cluster.NodeId; | 20 | import org.onosproject.cluster.NodeId; |
| 21 | +import org.onosproject.persistence.PersistenceService; | ||
| 21 | import org.onosproject.store.Timestamp; | 22 | import org.onosproject.store.Timestamp; |
| 22 | import org.onosproject.store.cluster.messaging.ClusterCommunicationService; | 23 | import org.onosproject.store.cluster.messaging.ClusterCommunicationService; |
| 23 | import org.onosproject.store.service.EventuallyConsistentMap; | 24 | import org.onosproject.store.service.EventuallyConsistentMap; |
| ... | @@ -52,6 +53,8 @@ public class EventuallyConsistentMapBuilderImpl<K, V> | ... | @@ -52,6 +53,8 @@ public class EventuallyConsistentMapBuilderImpl<K, V> |
| 52 | private TimeUnit antiEntropyTimeUnit = TimeUnit.SECONDS; | 53 | private TimeUnit antiEntropyTimeUnit = TimeUnit.SECONDS; |
| 53 | private boolean convergeFaster = false; | 54 | private boolean convergeFaster = false; |
| 54 | private boolean persistent = false; | 55 | private boolean persistent = false; |
| 56 | + private boolean persistentMap = false; | ||
| 57 | + private final PersistenceService persistenceService; | ||
| 55 | 58 | ||
| 56 | /** | 59 | /** |
| 57 | * Creates a new eventually consistent map builder. | 60 | * Creates a new eventually consistent map builder. |
| ... | @@ -60,7 +63,9 @@ public class EventuallyConsistentMapBuilderImpl<K, V> | ... | @@ -60,7 +63,9 @@ public class EventuallyConsistentMapBuilderImpl<K, V> |
| 60 | * @param clusterCommunicator cluster communication service | 63 | * @param clusterCommunicator cluster communication service |
| 61 | */ | 64 | */ |
| 62 | public EventuallyConsistentMapBuilderImpl(ClusterService clusterService, | 65 | public EventuallyConsistentMapBuilderImpl(ClusterService clusterService, |
| 63 | - ClusterCommunicationService clusterCommunicator) { | 66 | + ClusterCommunicationService clusterCommunicator, |
| 67 | + PersistenceService persistenceService) { | ||
| 68 | + this.persistenceService = persistenceService; | ||
| 64 | this.clusterService = checkNotNull(clusterService); | 69 | this.clusterService = checkNotNull(clusterService); |
| 65 | this.clusterCommunicator = checkNotNull(clusterCommunicator); | 70 | this.clusterCommunicator = checkNotNull(clusterCommunicator); |
| 66 | } | 71 | } |
| ... | @@ -133,6 +138,7 @@ public class EventuallyConsistentMapBuilderImpl<K, V> | ... | @@ -133,6 +138,7 @@ public class EventuallyConsistentMapBuilderImpl<K, V> |
| 133 | 138 | ||
| 134 | @Override | 139 | @Override |
| 135 | public EventuallyConsistentMapBuilder<K, V> withPersistence() { | 140 | public EventuallyConsistentMapBuilder<K, V> withPersistence() { |
| 141 | + checkNotNull(this.persistenceService); | ||
| 136 | persistent = true; | 142 | persistent = true; |
| 137 | return this; | 143 | return this; |
| 138 | } | 144 | } |
| ... | @@ -156,6 +162,7 @@ public class EventuallyConsistentMapBuilderImpl<K, V> | ... | @@ -156,6 +162,7 @@ public class EventuallyConsistentMapBuilderImpl<K, V> |
| 156 | antiEntropyPeriod, | 162 | antiEntropyPeriod, |
| 157 | antiEntropyTimeUnit, | 163 | antiEntropyTimeUnit, |
| 158 | convergeFaster, | 164 | convergeFaster, |
| 159 | - persistent); | 165 | + persistent, |
| 166 | + persistenceService); | ||
| 160 | } | 167 | } |
| 161 | } | 168 | } | ... | ... |
| ... | @@ -28,6 +28,7 @@ import org.onlab.util.SlidingWindowCounter; | ... | @@ -28,6 +28,7 @@ import org.onlab.util.SlidingWindowCounter; |
| 28 | import org.onosproject.cluster.ClusterService; | 28 | import org.onosproject.cluster.ClusterService; |
| 29 | import org.onosproject.cluster.ControllerNode; | 29 | import org.onosproject.cluster.ControllerNode; |
| 30 | import org.onosproject.cluster.NodeId; | 30 | import org.onosproject.cluster.NodeId; |
| 31 | +import org.onosproject.persistence.PersistenceService; | ||
| 31 | import org.onosproject.store.Timestamp; | 32 | import org.onosproject.store.Timestamp; |
| 32 | import org.onosproject.store.cluster.messaging.ClusterCommunicationService; | 33 | import org.onosproject.store.cluster.messaging.ClusterCommunicationService; |
| 33 | import org.onosproject.store.cluster.messaging.MessageSubject; | 34 | import org.onosproject.store.cluster.messaging.MessageSubject; |
| ... | @@ -37,6 +38,7 @@ import org.onosproject.store.serializers.KryoSerializer; | ... | @@ -37,6 +38,7 @@ import org.onosproject.store.serializers.KryoSerializer; |
| 37 | import org.onosproject.store.service.EventuallyConsistentMap; | 38 | import org.onosproject.store.service.EventuallyConsistentMap; |
| 38 | import org.onosproject.store.service.EventuallyConsistentMapEvent; | 39 | import org.onosproject.store.service.EventuallyConsistentMapEvent; |
| 39 | import org.onosproject.store.service.EventuallyConsistentMapListener; | 40 | import org.onosproject.store.service.EventuallyConsistentMapListener; |
| 41 | +import org.onosproject.store.service.Serializer; | ||
| 40 | import org.onosproject.store.service.WallClockTimestamp; | 42 | import org.onosproject.store.service.WallClockTimestamp; |
| 41 | import org.slf4j.Logger; | 43 | import org.slf4j.Logger; |
| 42 | import org.slf4j.LoggerFactory; | 44 | import org.slf4j.LoggerFactory; |
| ... | @@ -81,6 +83,7 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -81,6 +83,7 @@ public class EventuallyConsistentMapImpl<K, V> |
| 81 | private final ClusterCommunicationService clusterCommunicator; | 83 | private final ClusterCommunicationService clusterCommunicator; |
| 82 | private final KryoSerializer serializer; | 84 | private final KryoSerializer serializer; |
| 83 | private final NodeId localNodeId; | 85 | private final NodeId localNodeId; |
| 86 | + private final PersistenceService persistenceService; | ||
| 84 | 87 | ||
| 85 | private final BiFunction<K, V, Timestamp> timestampProvider; | 88 | private final BiFunction<K, V, Timestamp> timestampProvider; |
| 86 | 89 | ||
| ... | @@ -116,7 +119,9 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -116,7 +119,9 @@ public class EventuallyConsistentMapImpl<K, V> |
| 116 | private SlidingWindowCounter counter = new SlidingWindowCounter(WINDOW_SIZE); | 119 | private SlidingWindowCounter counter = new SlidingWindowCounter(WINDOW_SIZE); |
| 117 | 120 | ||
| 118 | private final boolean persistent; | 121 | private final boolean persistent; |
| 119 | - private final PersistentStore<K, V> persistentStore; | 122 | + |
| 123 | + private static final String PERSISTENT_LOCAL_MAP_NAME = "itemsMap"; | ||
| 124 | + | ||
| 120 | 125 | ||
| 121 | /** | 126 | /** |
| 122 | * Creates a new eventually consistent map shared amongst multiple instances. | 127 | * Creates a new eventually consistent map shared amongst multiple instances. |
| ... | @@ -158,9 +163,32 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -158,9 +163,32 @@ public class EventuallyConsistentMapImpl<K, V> |
| 158 | long antiEntropyPeriod, | 163 | long antiEntropyPeriod, |
| 159 | TimeUnit antiEntropyTimeUnit, | 164 | TimeUnit antiEntropyTimeUnit, |
| 160 | boolean convergeFaster, | 165 | boolean convergeFaster, |
| 161 | - boolean persistent) { | 166 | + boolean persistent, |
| 167 | + PersistenceService persistenceService) { | ||
| 162 | this.mapName = mapName; | 168 | this.mapName = mapName; |
| 169 | + this.serializer = createSerializer(serializerBuilder); | ||
| 170 | + this.persistenceService = persistenceService; | ||
| 171 | + this.persistent = | ||
| 172 | + persistent; | ||
| 173 | + if (persistent) { | ||
| 174 | + items = this.persistenceService.<K, MapValue<V>>persistentMapBuilder() | ||
| 175 | + .withName(PERSISTENT_LOCAL_MAP_NAME) | ||
| 176 | + .withSerializer(new Serializer() { | ||
| 177 | + | ||
| 178 | + @Override | ||
| 179 | + public <T> byte[] encode(T object) { | ||
| 180 | + return EventuallyConsistentMapImpl.this.serializer.encode(object); | ||
| 181 | + } | ||
| 182 | + | ||
| 183 | + @Override | ||
| 184 | + public <T> T decode(byte[] bytes) { | ||
| 185 | + return EventuallyConsistentMapImpl.this.serializer.decode(bytes); | ||
| 186 | + } | ||
| 187 | + }) | ||
| 188 | + .build(); | ||
| 189 | + } else { | ||
| 163 | items = Maps.newConcurrentMap(); | 190 | items = Maps.newConcurrentMap(); |
| 191 | + } | ||
| 164 | senderPending = Maps.newConcurrentMap(); | 192 | senderPending = Maps.newConcurrentMap(); |
| 165 | destroyedMessage = mapName + ERROR_DESTROYED; | 193 | destroyedMessage = mapName + ERROR_DESTROYED; |
| 166 | 194 | ||
| ... | @@ -168,8 +196,6 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -168,8 +196,6 @@ public class EventuallyConsistentMapImpl<K, V> |
| 168 | this.clusterCommunicator = clusterCommunicator; | 196 | this.clusterCommunicator = clusterCommunicator; |
| 169 | this.localNodeId = clusterService.getLocalNode().id(); | 197 | this.localNodeId = clusterService.getLocalNode().id(); |
| 170 | 198 | ||
| 171 | - this.serializer = createSerializer(serializerBuilder); | ||
| 172 | - | ||
| 173 | this.timestampProvider = timestampProvider; | 199 | this.timestampProvider = timestampProvider; |
| 174 | 200 | ||
| 175 | if (peerUpdateFunction != null) { | 201 | if (peerUpdateFunction != null) { |
| ... | @@ -198,20 +224,6 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -198,20 +224,6 @@ public class EventuallyConsistentMapImpl<K, V> |
| 198 | newFixedThreadPool(8, groupedThreads("onos/ecm", mapName + "-publish-%d")); | 224 | newFixedThreadPool(8, groupedThreads("onos/ecm", mapName + "-publish-%d")); |
| 199 | } | 225 | } |
| 200 | 226 | ||
| 201 | - this.persistent = persistent; | ||
| 202 | - | ||
| 203 | - if (this.persistent) { | ||
| 204 | - String dataDirectory = System.getProperty("karaf.data", "./data"); | ||
| 205 | - String filename = dataDirectory + "/" + "mapdb-ecm-" + mapName; | ||
| 206 | - | ||
| 207 | - ExecutorService dbExecutor = | ||
| 208 | - newFixedThreadPool(1, groupedThreads("onos/ecm", mapName + "-dbwriter")); | ||
| 209 | - | ||
| 210 | - persistentStore = new MapDbPersistentStore<>(filename, dbExecutor, serializer); | ||
| 211 | - persistentStore.readInto(items); | ||
| 212 | - } else { | ||
| 213 | - this.persistentStore = null; | ||
| 214 | - } | ||
| 215 | 227 | ||
| 216 | if (backgroundExecutor != null) { | 228 | if (backgroundExecutor != null) { |
| 217 | this.backgroundExecutor = backgroundExecutor; | 229 | this.backgroundExecutor = backgroundExecutor; |
| ... | @@ -373,15 +385,6 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -373,15 +385,6 @@ public class EventuallyConsistentMapImpl<K, V> |
| 373 | return existing; | 385 | return existing; |
| 374 | } | 386 | } |
| 375 | }); | 387 | }); |
| 376 | - if (updated.get()) { | ||
| 377 | - if (persistent) { | ||
| 378 | - if (tombstone.isPresent()) { | ||
| 379 | - persistentStore.update(key, tombstone.get()); | ||
| 380 | - } else { | ||
| 381 | - persistentStore.remove(key); | ||
| 382 | - } | ||
| 383 | - } | ||
| 384 | - } | ||
| 385 | return previousValue.get(); | 388 | return previousValue.get(); |
| 386 | } | 389 | } |
| 387 | 390 | ||
| ... | @@ -455,6 +458,7 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -455,6 +458,7 @@ public class EventuallyConsistentMapImpl<K, V> |
| 455 | 458 | ||
| 456 | /** | 459 | /** |
| 457 | * Returns true if newValue was accepted i.e. map is updated. | 460 | * Returns true if newValue was accepted i.e. map is updated. |
| 461 | + * | ||
| 458 | * @param key key | 462 | * @param key key |
| 459 | * @param newValue proposed new value | 463 | * @param newValue proposed new value |
| 460 | * @return true if update happened; false if map already contains a more recent value for the key | 464 | * @return true if update happened; false if map already contains a more recent value for the key |
| ... | @@ -473,9 +477,6 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -473,9 +477,6 @@ public class EventuallyConsistentMapImpl<K, V> |
| 473 | } | 477 | } |
| 474 | return existing; | 478 | return existing; |
| 475 | }); | 479 | }); |
| 476 | - if (updated.get() && persistent) { | ||
| 477 | - persistentStore.update(key, newValue); | ||
| 478 | - } | ||
| 479 | return updated.get(); | 480 | return updated.get(); |
| 480 | } | 481 | } |
| 481 | 482 | ... | ... |
| ... | @@ -42,6 +42,7 @@ import org.onosproject.cluster.ControllerNode; | ... | @@ -42,6 +42,7 @@ import org.onosproject.cluster.ControllerNode; |
| 42 | import org.onosproject.cluster.DefaultControllerNode; | 42 | import org.onosproject.cluster.DefaultControllerNode; |
| 43 | import org.onosproject.cluster.NodeId; | 43 | import org.onosproject.cluster.NodeId; |
| 44 | import org.onosproject.event.AbstractEvent; | 44 | import org.onosproject.event.AbstractEvent; |
| 45 | +import org.onosproject.persistence.impl.PersistenceManager; | ||
| 45 | import org.onosproject.store.Timestamp; | 46 | import org.onosproject.store.Timestamp; |
| 46 | import org.onosproject.store.cluster.messaging.ClusterCommunicationService; | 47 | import org.onosproject.store.cluster.messaging.ClusterCommunicationService; |
| 47 | import org.onosproject.store.cluster.messaging.ClusterCommunicationServiceAdapter; | 48 | import org.onosproject.store.cluster.messaging.ClusterCommunicationServiceAdapter; |
| ... | @@ -81,6 +82,7 @@ public class EventuallyConsistentMapImplTest { | ... | @@ -81,6 +82,7 @@ public class EventuallyConsistentMapImplTest { |
| 81 | 82 | ||
| 82 | private EventuallyConsistentMap<String, String> ecMap; | 83 | private EventuallyConsistentMap<String, String> ecMap; |
| 83 | 84 | ||
| 85 | + private PersistenceManager persistenceService; | ||
| 84 | private ClusterService clusterService; | 86 | private ClusterService clusterService; |
| 85 | private ClusterCommunicationService clusterCommunicator; | 87 | private ClusterCommunicationService clusterCommunicator; |
| 86 | private SequentialClockService<String, String> clockService; | 88 | private SequentialClockService<String, String> clockService; |
| ... | @@ -136,6 +138,8 @@ public class EventuallyConsistentMapImplTest { | ... | @@ -136,6 +138,8 @@ public class EventuallyConsistentMapImplTest { |
| 136 | 138 | ||
| 137 | clusterCommunicator = createMock(ClusterCommunicationService.class); | 139 | clusterCommunicator = createMock(ClusterCommunicationService.class); |
| 138 | 140 | ||
| 141 | + persistenceService = new PersistenceManager(); | ||
| 142 | + persistenceService.activate(); | ||
| 139 | // Add expectation for adding cluster message subscribers which | 143 | // Add expectation for adding cluster message subscribers which |
| 140 | // delegate to our ClusterCommunicationService implementation. This | 144 | // delegate to our ClusterCommunicationService implementation. This |
| 141 | // allows us to get a reference to the map's internal cluster message | 145 | // allows us to get a reference to the map's internal cluster message |
| ... | @@ -153,11 +157,12 @@ public class EventuallyConsistentMapImplTest { | ... | @@ -153,11 +157,12 @@ public class EventuallyConsistentMapImplTest { |
| 153 | .register(TestTimestamp.class); | 157 | .register(TestTimestamp.class); |
| 154 | 158 | ||
| 155 | ecMap = new EventuallyConsistentMapBuilderImpl<String, String>( | 159 | ecMap = new EventuallyConsistentMapBuilderImpl<String, String>( |
| 156 | - clusterService, clusterCommunicator) | 160 | + clusterService, clusterCommunicator, persistenceService) |
| 157 | .withName(MAP_NAME) | 161 | .withName(MAP_NAME) |
| 158 | .withSerializer(serializer) | 162 | .withSerializer(serializer) |
| 159 | .withTimestampProvider((k, v) -> clockService.getTimestamp(k, v)) | 163 | .withTimestampProvider((k, v) -> clockService.getTimestamp(k, v)) |
| 160 | .withCommunicationExecutor(MoreExecutors.newDirectExecutorService()) | 164 | .withCommunicationExecutor(MoreExecutors.newDirectExecutorService()) |
| 165 | + .withPersistence() | ||
| 161 | .build(); | 166 | .build(); |
| 162 | 167 | ||
| 163 | // Reset ready for tests to add their own expectations | 168 | // Reset ready for tests to add their own expectations | ... | ... |
-
Please register or login to post a comment