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
61 additions
and
37 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; |
163 | - items = Maps.newConcurrentMap(); | 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 { | ||
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