Aaron Kruglikov
Committed by Gerrit Code Review

Modifying eventually consistent map and tests to make use of the persistence service.

Change-Id: I44ffcabb9d765a1c70c2790366c6d7381416dac6
...@@ -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
......