Madan Jampani

1. Refactored ConsistentMap and StorageServive (renamed from DatabaseService) to api bundle.

2. Misc bug fixes uncovered during testing

Change-Id: I1219c5264831bcfa93565f764511f89de35a949d
Showing 15 changed files with 189 additions and 36 deletions
1 -package org.onosproject.store.consistent.impl; 1 +package org.onosproject.store.service;
2 2
3 import java.util.Collection; 3 import java.util.Collection;
4 import java.util.List; 4 import java.util.List;
......
1 -package org.onosproject.store.consistent.impl; 1 +package org.onosproject.store.service;
2 2
3 /** 3 /**
4 * Top level exception for ConsistentMap failures. 4 * Top level exception for ConsistentMap failures.
......
1 +package org.onosproject.store.service;
2 +
3 +/**
4 + * Interface for serialization for store artifacts.
5 + */
6 +public interface Serializer {
7 + /**
8 + * Serialize the specified object.
9 + * @param object object to serialize.
10 + * @return serialized bytes.
11 + * @param <T> encoded type
12 + */
13 + <T> byte[] encode(T object);
14 +
15 + /**
16 + * Deserialize the specified bytes.
17 + * @param bytes byte array to deserialize.
18 + * @return deserialized object.
19 + * @param <T> decoded type
20 + */
21 + <T> T decode(byte[] bytes);
22 +}
...\ No newline at end of file ...\ No newline at end of file
1 -package org.onosproject.store.consistent.impl; 1 +package org.onosproject.store.service;
2 -
3 -import org.onosproject.store.serializers.StoreSerializer;
4 2
5 /** 3 /**
6 - * Database service. 4 + * Storage service.
5 + * <p>
6 + * This service provides operations for creating key-value stores.
7 + * One can chose to create key-value stores with varying properties such
8 + * as strongly consistent vs eventually consistent, durable vs volatile.
9 + * <p>
10 + * Various store implementations should leverage the data structures provided
11 + * by this service
7 */ 12 */
8 -public interface DatabaseService { 13 +public interface StorageService {
9 14
10 /** 15 /**
11 * Creates a ConsistentMap. 16 * Creates a ConsistentMap.
12 * 17 *
13 - * @param <K> Key type
14 - * @param <V> value type
15 * @param name map name 18 * @param name map name
16 * @param serializer serializer to use for serializing keys and values. 19 * @param serializer serializer to use for serializing keys and values.
17 * @return consistent map. 20 * @return consistent map.
21 + * @param <K> key type
22 + * @param <V> value type
18 */ 23 */
19 - <K, V> ConsistentMap<K , V> createConsistentMap(String name, StoreSerializer serializer); 24 + <K, V> ConsistentMap<K , V> createConsistentMap(String name, Serializer serializer);
25 +
26 + // TODO: add API for creating Eventually Consistent Map.
20 } 27 }
...\ No newline at end of file ...\ No newline at end of file
......
1 -package org.onosproject.store.consistent.impl; 1 +package org.onosproject.store.service;
2 2
3 import static com.google.common.base.Preconditions.*; 3 import static com.google.common.base.Preconditions.*;
4 4
......
1 -package org.onosproject.store.consistent.impl; 1 +package org.onosproject.store.service;
2 2
3 import com.google.common.base.MoreObjects; 3 import com.google.common.base.MoreObjects;
4 4
......
...@@ -2,7 +2,6 @@ package org.onosproject.store.consistent.impl; ...@@ -2,7 +2,6 @@ package org.onosproject.store.consistent.impl;
2 2
3 import static com.google.common.base.Preconditions.*; 3 import static com.google.common.base.Preconditions.*;
4 4
5 -import java.util.AbstractMap;
6 import java.util.Collection; 5 import java.util.Collection;
7 import java.util.Collections; 6 import java.util.Collections;
8 import java.util.List; 7 import java.util.List;
...@@ -15,8 +14,13 @@ import java.util.concurrent.TimeoutException; ...@@ -15,8 +14,13 @@ import java.util.concurrent.TimeoutException;
15 import java.util.stream.Collectors; 14 import java.util.stream.Collectors;
16 import java.util.Set; 15 import java.util.Set;
17 16
17 +import org.apache.commons.lang3.tuple.Pair;
18 import org.onlab.util.HexString; 18 import org.onlab.util.HexString;
19 -import org.onosproject.store.serializers.StoreSerializer; 19 +import org.onosproject.store.service.ConsistentMap;
20 +import org.onosproject.store.service.ConsistentMapException;
21 +import org.onosproject.store.service.Serializer;
22 +import org.onosproject.store.service.UpdateOperation;
23 +import org.onosproject.store.service.Versioned;
20 24
21 import com.google.common.cache.CacheBuilder; 25 import com.google.common.cache.CacheBuilder;
22 import com.google.common.cache.CacheLoader; 26 import com.google.common.cache.CacheLoader;
...@@ -33,7 +37,7 @@ public class ConsistentMapImpl<K, V> implements ConsistentMap<K, V> { ...@@ -33,7 +37,7 @@ public class ConsistentMapImpl<K, V> implements ConsistentMap<K, V> {
33 37
34 private final String name; 38 private final String name;
35 private final DatabaseProxy<String, byte[]> proxy; 39 private final DatabaseProxy<String, byte[]> proxy;
36 - private final StoreSerializer serializer; 40 + private final Serializer serializer;
37 41
38 private static final int OPERATION_TIMEOUT_MILLIS = 1000; 42 private static final int OPERATION_TIMEOUT_MILLIS = 1000;
39 private static final String ERROR_NULL_KEY = "Key cannot be null"; 43 private static final String ERROR_NULL_KEY = "Key cannot be null";
...@@ -55,7 +59,7 @@ public class ConsistentMapImpl<K, V> implements ConsistentMap<K, V> { ...@@ -55,7 +59,7 @@ public class ConsistentMapImpl<K, V> implements ConsistentMap<K, V> {
55 59
56 ConsistentMapImpl(String name, 60 ConsistentMapImpl(String name,
57 DatabaseProxy<String, byte[]> proxy, 61 DatabaseProxy<String, byte[]> proxy,
58 - StoreSerializer serializer) { 62 + Serializer serializer) {
59 this.name = checkNotNull(name, "map name cannot be null"); 63 this.name = checkNotNull(name, "map name cannot be null");
60 this.proxy = checkNotNull(proxy, "database proxy cannot be null"); 64 this.proxy = checkNotNull(proxy, "database proxy cannot be null");
61 this.serializer = checkNotNull(serializer, "serializer cannot be null"); 65 this.serializer = checkNotNull(serializer, "serializer cannot be null");
...@@ -87,14 +91,15 @@ public class ConsistentMapImpl<K, V> implements ConsistentMap<K, V> { ...@@ -87,14 +91,15 @@ public class ConsistentMapImpl<K, V> implements ConsistentMap<K, V> {
87 public Versioned<V> get(K key) { 91 public Versioned<V> get(K key) {
88 checkNotNull(key, ERROR_NULL_KEY); 92 checkNotNull(key, ERROR_NULL_KEY);
89 Versioned<byte[]> value = complete(proxy.get(name, keyCache.getUnchecked(key))); 93 Versioned<byte[]> value = complete(proxy.get(name, keyCache.getUnchecked(key)));
90 - return new Versioned<>(serializer.decode(value.value()), value.version()); 94 + return (value != null) ? new Versioned<>(serializer.decode(value.value()), value.version()) : null;
91 } 95 }
92 96
93 @Override 97 @Override
94 public Versioned<V> put(K key, V value) { 98 public Versioned<V> put(K key, V value) {
95 checkNotNull(key, ERROR_NULL_KEY); 99 checkNotNull(key, ERROR_NULL_KEY);
96 checkNotNull(value, ERROR_NULL_VALUE); 100 checkNotNull(value, ERROR_NULL_VALUE);
97 - Versioned<byte[]> previousValue = complete(proxy.get(name, keyCache.getUnchecked(key))); 101 + Versioned<byte[]> previousValue =
102 + complete(proxy.put(name, keyCache.getUnchecked(key), serializer.encode(value)));
98 return (previousValue != null) ? 103 return (previousValue != null) ?
99 new Versioned<>(serializer.decode(previousValue.value()), previousValue.version()) : null; 104 new Versioned<>(serializer.decode(previousValue.value()), previousValue.version()) : null;
100 105
...@@ -103,7 +108,7 @@ public class ConsistentMapImpl<K, V> implements ConsistentMap<K, V> { ...@@ -103,7 +108,7 @@ public class ConsistentMapImpl<K, V> implements ConsistentMap<K, V> {
103 @Override 108 @Override
104 public Versioned<V> remove(K key) { 109 public Versioned<V> remove(K key) {
105 checkNotNull(key, ERROR_NULL_KEY); 110 checkNotNull(key, ERROR_NULL_KEY);
106 - Versioned<byte[]> value = complete(proxy.get(name, keyCache.getUnchecked(key))); 111 + Versioned<byte[]> value = complete(proxy.remove(name, keyCache.getUnchecked(key)));
107 return (value != null) ? new Versioned<>(serializer.decode(value.value()), value.version()) : null; 112 return (value != null) ? new Versioned<>(serializer.decode(value.value()), value.version()) : null;
108 } 113 }
109 114
...@@ -198,7 +203,7 @@ public class ConsistentMapImpl<K, V> implements ConsistentMap<K, V> { ...@@ -198,7 +203,7 @@ public class ConsistentMapImpl<K, V> implements ConsistentMap<K, V> {
198 } 203 }
199 204
200 private Map.Entry<K, Versioned<V>> fromRawEntry(Map.Entry<String, Versioned<byte[]>> e) { 205 private Map.Entry<K, Versioned<V>> fromRawEntry(Map.Entry<String, Versioned<byte[]>> e) {
201 - return new AbstractMap.SimpleEntry<>( 206 + return Pair.of(
202 dK(e.getKey()), 207 dK(e.getKey()),
203 new Versioned<>( 208 new Versioned<>(
204 serializer.decode(e.getValue().value()), 209 serializer.decode(e.getValue().value()),
......
...@@ -22,7 +22,9 @@ import org.apache.felix.scr.annotations.Service; ...@@ -22,7 +22,9 @@ import org.apache.felix.scr.annotations.Service;
22 import org.onosproject.cluster.ClusterService; 22 import org.onosproject.cluster.ClusterService;
23 import org.onosproject.cluster.ControllerNode; 23 import org.onosproject.cluster.ControllerNode;
24 import org.onosproject.cluster.DefaultControllerNode; 24 import org.onosproject.cluster.DefaultControllerNode;
25 -import org.onosproject.store.serializers.StoreSerializer; 25 +import org.onosproject.store.service.ConsistentMap;
26 +import org.onosproject.store.service.Serializer;
27 +import org.onosproject.store.service.StorageService;
26 import org.slf4j.Logger; 28 import org.slf4j.Logger;
27 29
28 import com.google.common.collect.Sets; 30 import com.google.common.collect.Sets;
...@@ -32,7 +34,7 @@ import com.google.common.collect.Sets; ...@@ -32,7 +34,7 @@ import com.google.common.collect.Sets;
32 */ 34 */
33 @Component(immediate = true, enabled = true) 35 @Component(immediate = true, enabled = true)
34 @Service 36 @Service
35 -public class DatabaseManager implements DatabaseService { 37 +public class DatabaseManager implements StorageService {
36 38
37 private final Logger log = getLogger(getClass()); 39 private final Logger log = getLogger(getClass());
38 private PartitionedDatabase partitionedDatabase; 40 private PartitionedDatabase partitionedDatabase;
...@@ -44,7 +46,7 @@ public class DatabaseManager implements DatabaseService { ...@@ -44,7 +46,7 @@ public class DatabaseManager implements DatabaseService {
44 protected ClusterService clusterService; 46 protected ClusterService clusterService;
45 47
46 protected String nodeToUri(ControllerNode node) { 48 protected String nodeToUri(ControllerNode node) {
47 - return "tcp://" + node.ip() + ":" + COPYCAT_TCP_PORT; 49 + return String.format("tcp://%s:%d", node.ip(), COPYCAT_TCP_PORT);
48 } 50 }
49 51
50 @Activate 52 @Activate
...@@ -76,7 +78,17 @@ public class DatabaseManager implements DatabaseService { ...@@ -76,7 +78,17 @@ public class DatabaseManager implements DatabaseService {
76 String localNodeUri = nodeToUri(clusterService.getLocalNode()); 78 String localNodeUri = nodeToUri(clusterService.getLocalNode());
77 79
78 ClusterConfig clusterConfig = new ClusterConfig() 80 ClusterConfig clusterConfig = new ClusterConfig()
79 - .withProtocol(new NettyTcpProtocol()) 81 + .withProtocol(new NettyTcpProtocol()
82 + .withSsl(false)
83 + .withConnectTimeout(60000)
84 + .withAcceptBacklog(1024)
85 + .withTrafficClass(-1)
86 + .withSoLinger(-1)
87 + .withReceiveBufferSize(32768)
88 + .withSendBufferSize(8192)
89 + .withThreads(1))
90 + .withElectionTimeout(300)
91 + .withHeartbeatInterval(150)
80 .withMembers(activeNodeUris) 92 .withMembers(activeNodeUris)
81 .withLocalMember(localNodeUri); 93 .withLocalMember(localNodeUri);
82 94
...@@ -85,8 +97,15 @@ public class DatabaseManager implements DatabaseService { ...@@ -85,8 +97,15 @@ public class DatabaseManager implements DatabaseService {
85 partitionMap.forEach((name, nodes) -> { 97 partitionMap.forEach((name, nodes) -> {
86 Set<String> replicas = nodes.stream().map(this::nodeToUri).collect(Collectors.toSet()); 98 Set<String> replicas = nodes.stream().map(this::nodeToUri).collect(Collectors.toSet());
87 DatabaseConfig partitionConfig = new DatabaseConfig() 99 DatabaseConfig partitionConfig = new DatabaseConfig()
100 + .withElectionTimeout(300)
101 + .withHeartbeatInterval(150)
88 .withConsistency(Consistency.STRONG) 102 .withConsistency(Consistency.STRONG)
89 - .withLog(new FileLog(logDir)) 103 + .withLog(new FileLog()
104 + .withDirectory(logDir)
105 + .withSegmentSize(1073741824) // 1GB
106 + .withFlushOnWrite(true)
107 + .withSegmentInterval(Long.MAX_VALUE))
108 + .withDefaultSerializer(new DatabaseSerializer())
90 .withReplicas(replicas); 109 .withReplicas(replicas);
91 databaseConfig.addPartition(name, partitionConfig); 110 databaseConfig.addPartition(name, partitionConfig);
92 }); 111 });
...@@ -116,7 +135,7 @@ public class DatabaseManager implements DatabaseService { ...@@ -116,7 +135,7 @@ public class DatabaseManager implements DatabaseService {
116 } 135 }
117 136
118 @Override 137 @Override
119 - public <K, V> ConsistentMap<K , V> createConsistentMap(String name, StoreSerializer serializer) { 138 + public <K, V> ConsistentMap<K , V> createConsistentMap(String name, Serializer serializer) {
120 return new ConsistentMapImpl<K, V>(name, partitionedDatabase, serializer); 139 return new ConsistentMapImpl<K, V>(name, partitionedDatabase, serializer);
121 } 140 }
122 } 141 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -6,6 +6,9 @@ import java.util.Map; ...@@ -6,6 +6,9 @@ import java.util.Map;
6 import java.util.Set; 6 import java.util.Set;
7 import java.util.concurrent.CompletableFuture; 7 import java.util.concurrent.CompletableFuture;
8 8
9 +import org.onosproject.store.service.UpdateOperation;
10 +import org.onosproject.store.service.Versioned;
11 +
9 /** 12 /**
10 * Database proxy. 13 * Database proxy.
11 */ 14 */
......
1 +package org.onosproject.store.consistent.impl;
2 +
3 +import java.nio.ByteBuffer;
4 +
5 +import org.apache.commons.lang3.tuple.ImmutablePair;
6 +import org.apache.commons.lang3.tuple.Pair;
7 +import org.onlab.util.KryoNamespace;
8 +import org.onosproject.store.serializers.KryoNamespaces;
9 +import org.onosproject.store.serializers.KryoSerializer;
10 +import org.onosproject.store.service.Versioned;
11 +
12 +import net.kuujo.copycat.cluster.internal.MemberInfo;
13 +import net.kuujo.copycat.protocol.rpc.AppendRequest;
14 +import net.kuujo.copycat.protocol.rpc.AppendResponse;
15 +import net.kuujo.copycat.protocol.rpc.CommitRequest;
16 +import net.kuujo.copycat.protocol.rpc.CommitResponse;
17 +import net.kuujo.copycat.protocol.rpc.PollRequest;
18 +import net.kuujo.copycat.protocol.rpc.PollResponse;
19 +import net.kuujo.copycat.protocol.rpc.QueryRequest;
20 +import net.kuujo.copycat.protocol.rpc.QueryResponse;
21 +import net.kuujo.copycat.protocol.rpc.ReplicaInfo;
22 +import net.kuujo.copycat.protocol.rpc.SyncRequest;
23 +import net.kuujo.copycat.protocol.rpc.SyncResponse;
24 +import net.kuujo.copycat.util.serializer.SerializerConfig;
25 +
26 +/**
27 + * Serializer for DatabaseManager's interaction with Copycat.
28 + */
29 +public class DatabaseSerializer extends SerializerConfig {
30 +
31 + private static final KryoNamespace COPYCAT = KryoNamespace.newBuilder()
32 + .nextId(KryoNamespace.FLOATING_ID)
33 + .register(AppendRequest.class)
34 + .register(AppendResponse.class)
35 + .register(SyncRequest.class)
36 + .register(SyncResponse.class)
37 + .register(PollRequest.class)
38 + .register(PollResponse.class)
39 + .register(QueryRequest.class)
40 + .register(QueryResponse.class)
41 + .register(CommitRequest.class)
42 + .register(CommitResponse.class)
43 + .register(ReplicaInfo.class)
44 + .register(MemberInfo.class)
45 + .build();
46 +
47 + private static final KryoNamespace ONOS_STORE = KryoNamespace.newBuilder()
48 + .nextId(KryoNamespace.FLOATING_ID)
49 + .register(Versioned.class)
50 + .register(Pair.class)
51 + .register(ImmutablePair.class)
52 + .build();
53 +
54 + private static final KryoSerializer SERIALIZER = new KryoSerializer() {
55 + @Override
56 + protected void setupKryoPool() {
57 + serializerPool = KryoNamespace.newBuilder()
58 + .register(KryoNamespaces.BASIC)
59 + .register(COPYCAT)
60 + .register(ONOS_STORE)
61 + .build();
62 + }
63 + };
64 +
65 + @Override
66 + public ByteBuffer writeObject(Object object) {
67 + return ByteBuffer.wrap(SERIALIZER.encode(object));
68 + }
69 +
70 + @Override
71 + public <T> T readObject(ByteBuffer buffer) {
72 + return SERIALIZER.decode(buffer);
73 + }
74 +}
...\ No newline at end of file ...\ No newline at end of file
...@@ -5,6 +5,9 @@ import java.util.List; ...@@ -5,6 +5,9 @@ import java.util.List;
5 import java.util.Map.Entry; 5 import java.util.Map.Entry;
6 import java.util.Set; 6 import java.util.Set;
7 7
8 +import org.onosproject.store.service.UpdateOperation;
9 +import org.onosproject.store.service.Versioned;
10 +
8 import net.kuujo.copycat.state.Command; 11 import net.kuujo.copycat.state.Command;
9 import net.kuujo.copycat.state.Initializer; 12 import net.kuujo.copycat.state.Initializer;
10 import net.kuujo.copycat.state.Query; 13 import net.kuujo.copycat.state.Query;
......
...@@ -13,6 +13,9 @@ import java.util.Set; ...@@ -13,6 +13,9 @@ import java.util.Set;
13 import java.util.concurrent.CompletableFuture; 13 import java.util.concurrent.CompletableFuture;
14 import java.util.function.Supplier; 14 import java.util.function.Supplier;
15 15
16 +import org.onosproject.store.service.UpdateOperation;
17 +import org.onosproject.store.service.Versioned;
18 +
16 /** 19 /**
17 * Default database. 20 * Default database.
18 */ 21 */
...@@ -132,7 +135,7 @@ public class DefaultDatabase extends AbstractResource<Database> implements Datab ...@@ -132,7 +135,7 @@ public class DefaultDatabase extends AbstractResource<Database> implements Datab
132 return runStartupTasks() 135 return runStartupTasks()
133 .thenCompose(v -> stateMachine.open()) 136 .thenCompose(v -> stateMachine.open())
134 .thenRun(() -> { 137 .thenRun(() -> {
135 - this.proxy = stateMachine.createProxy(DatabaseProxy.class); 138 + this.proxy = stateMachine.createProxy(DatabaseProxy.class, this.getClass().getClassLoader());
136 }) 139 })
137 .thenApply(v -> null); 140 .thenApply(v -> null);
138 } 141 }
......
...@@ -6,8 +6,16 @@ import java.util.HashMap; ...@@ -6,8 +6,16 @@ import java.util.HashMap;
6 import java.util.List; 6 import java.util.List;
7 import java.util.Map; 7 import java.util.Map;
8 import java.util.Map.Entry; 8 import java.util.Map.Entry;
9 +import java.util.stream.Collectors;
9 import java.util.Set; 10 import java.util.Set;
10 11
12 +import org.apache.commons.lang3.tuple.Pair;
13 +import org.onosproject.store.service.UpdateOperation;
14 +import org.onosproject.store.service.Versioned;
15 +
16 +import com.google.common.collect.ImmutableList;
17 +import com.google.common.collect.ImmutableSet;
18 +
11 import net.kuujo.copycat.state.Initializer; 19 import net.kuujo.copycat.state.Initializer;
12 import net.kuujo.copycat.state.StateContext; 20 import net.kuujo.copycat.state.StateContext;
13 21
...@@ -88,17 +96,21 @@ public class DefaultDatabaseState<K, V> implements DatabaseState<K, V> { ...@@ -88,17 +96,21 @@ public class DefaultDatabaseState<K, V> implements DatabaseState<K, V> {
88 96
89 @Override 97 @Override
90 public Set<K> keySet(String tableName) { 98 public Set<K> keySet(String tableName) {
91 - return getTableMap(tableName).keySet(); 99 + return ImmutableSet.copyOf(getTableMap(tableName).keySet());
92 } 100 }
93 101
94 @Override 102 @Override
95 public Collection<Versioned<V>> values(String tableName) { 103 public Collection<Versioned<V>> values(String tableName) {
96 - return getTableMap(tableName).values(); 104 + return ImmutableList.copyOf(getTableMap(tableName).values());
97 } 105 }
98 106
99 @Override 107 @Override
100 public Set<Entry<K, Versioned<V>>> entrySet(String tableName) { 108 public Set<Entry<K, Versioned<V>>> entrySet(String tableName) {
101 - return getTableMap(tableName).entrySet(); 109 + return ImmutableSet.copyOf(getTableMap(tableName)
110 + .entrySet()
111 + .stream()
112 + .map(entry -> Pair.of(entry.getKey(), entry.getValue()))
113 + .collect(Collectors.toSet()));
102 } 114 }
103 115
104 @Override 116 @Override
...@@ -110,7 +122,7 @@ public class DefaultDatabaseState<K, V> implements DatabaseState<K, V> { ...@@ -110,7 +122,7 @@ public class DefaultDatabaseState<K, V> implements DatabaseState<K, V> {
110 @Override 122 @Override
111 public boolean remove(String tableName, K key, V value) { 123 public boolean remove(String tableName, K key, V value) {
112 Versioned<V> existing = getTableMap(tableName).get(key); 124 Versioned<V> existing = getTableMap(tableName).get(key);
113 - if (existing != null && existing.value().equals(value)) { 125 + if (existing != null && checkEquality(existing.value(), value)) {
114 getTableMap(tableName).remove(key); 126 getTableMap(tableName).remove(key);
115 return true; 127 return true;
116 } 128 }
...@@ -130,7 +142,7 @@ public class DefaultDatabaseState<K, V> implements DatabaseState<K, V> { ...@@ -130,7 +142,7 @@ public class DefaultDatabaseState<K, V> implements DatabaseState<K, V> {
130 @Override 142 @Override
131 public boolean replace(String tableName, K key, V oldValue, V newValue) { 143 public boolean replace(String tableName, K key, V oldValue, V newValue) {
132 Versioned<V> existing = getTableMap(tableName).get(key); 144 Versioned<V> existing = getTableMap(tableName).get(key);
133 - if (existing != null && existing.value().equals(oldValue)) { 145 + if (existing != null && checkEquality(existing.value(), oldValue)) {
134 put(tableName, key, newValue); 146 put(tableName, key, newValue);
135 return true; 147 return true;
136 } 148 }
...@@ -198,11 +210,11 @@ public class DefaultDatabaseState<K, V> implements DatabaseState<K, V> { ...@@ -198,11 +210,11 @@ public class DefaultDatabaseState<K, V> implements DatabaseState<K, V> {
198 case PUT_IF_VERSION_MATCH: 210 case PUT_IF_VERSION_MATCH:
199 return existingEntry != null && existingEntry.version() == update.currentVersion(); 211 return existingEntry != null && existingEntry.version() == update.currentVersion();
200 case PUT_IF_VALUE_MATCH: 212 case PUT_IF_VALUE_MATCH:
201 - return existingEntry != null && existingEntry.value().equals(update.currentValue()); 213 + return existingEntry != null && checkEquality(existingEntry.value(), update.currentValue());
202 case REMOVE_IF_VERSION_MATCH: 214 case REMOVE_IF_VERSION_MATCH:
203 return existingEntry == null || existingEntry.version() == update.currentVersion(); 215 return existingEntry == null || existingEntry.version() == update.currentVersion();
204 case REMOVE_IF_VALUE_MATCH: 216 case REMOVE_IF_VALUE_MATCH:
205 - return existingEntry == null || existingEntry.value().equals(update.currentValue()); 217 + return existingEntry == null || checkEquality(existingEntry.value(), update.currentValue());
206 default: 218 default:
207 throw new IllegalStateException("Unsupported type: " + update.type()); 219 throw new IllegalStateException("Unsupported type: " + update.type());
208 } 220 }
......
...@@ -9,6 +9,10 @@ import java.util.concurrent.CompletableFuture; ...@@ -9,6 +9,10 @@ import java.util.concurrent.CompletableFuture;
9 import java.util.concurrent.CopyOnWriteArrayList; 9 import java.util.concurrent.CopyOnWriteArrayList;
10 import java.util.concurrent.atomic.AtomicBoolean; 10 import java.util.concurrent.atomic.AtomicBoolean;
11 import java.util.concurrent.atomic.AtomicInteger; 11 import java.util.concurrent.atomic.AtomicInteger;
12 +
13 +import org.onosproject.store.service.UpdateOperation;
14 +import org.onosproject.store.service.Versioned;
15 +
12 import com.google.common.collect.ImmutableMap; 16 import com.google.common.collect.ImmutableMap;
13 import com.google.common.collect.Lists; 17 import com.google.common.collect.Lists;
14 import com.google.common.collect.Maps; 18 import com.google.common.collect.Maps;
...@@ -112,7 +116,7 @@ public class PartitionedDatabase implements DatabaseProxy<String, byte[]>, Parti ...@@ -112,7 +116,7 @@ public class PartitionedDatabase implements DatabaseProxy<String, byte[]>, Parti
112 return CompletableFuture.allOf(partitions 116 return CompletableFuture.allOf(partitions
113 .values() 117 .values()
114 .stream() 118 .stream()
115 - .map(p -> p.values(tableName)) 119 + .map(p -> p.values(tableName).thenApply(values::addAll))
116 .toArray(CompletableFuture[]::new)) 120 .toArray(CompletableFuture[]::new))
117 .thenApply(v -> values); 121 .thenApply(v -> values);
118 } 122 }
......
...@@ -67,13 +67,14 @@ public interface PartitionedDatabaseManager { ...@@ -67,13 +67,14 @@ public interface PartitionedDatabaseManager {
67 CopycatConfig copycatConfig = new CopycatConfig() 67 CopycatConfig copycatConfig = new CopycatConfig()
68 .withName(name) 68 .withName(name)
69 .withClusterConfig(clusterConfig) 69 .withClusterConfig(clusterConfig)
70 + .withDefaultSerializer(new DatabaseSerializer())
70 .withDefaultExecutor(Executors.newSingleThreadExecutor(new NamedThreadFactory("copycat-coordinator-%d"))); 71 .withDefaultExecutor(Executors.newSingleThreadExecutor(new NamedThreadFactory("copycat-coordinator-%d")));
71 ClusterCoordinator coordinator = new DefaultClusterCoordinator(copycatConfig.resolve()); 72 ClusterCoordinator coordinator = new DefaultClusterCoordinator(copycatConfig.resolve());
72 PartitionedDatabase partitionedDatabase = new PartitionedDatabase(coordinator); 73 PartitionedDatabase partitionedDatabase = new PartitionedDatabase(coordinator);
73 partitionedDatabaseConfig.partitions().forEach((partitionName, partitionConfig) -> 74 partitionedDatabaseConfig.partitions().forEach((partitionName, partitionConfig) ->
74 partitionedDatabase.registerPartition(partitionName , 75 partitionedDatabase.registerPartition(partitionName ,
75 coordinator.getResource(partitionName, partitionConfig.resolve(clusterConfig) 76 coordinator.getResource(partitionName, partitionConfig.resolve(clusterConfig)
76 - .withDefaultSerializer(copycatConfig.getDefaultSerializer().copy()) 77 + .withSerializer(copycatConfig.getDefaultSerializer())
77 .withDefaultExecutor(copycatConfig.getDefaultExecutor())))); 78 .withDefaultExecutor(copycatConfig.getDefaultExecutor()))));
78 partitionedDatabase.setPartitioner( 79 partitionedDatabase.setPartitioner(
79 new SimpleKeyHashPartitioner(partitionedDatabase.getRegisteredPartitions())); 80 new SimpleKeyHashPartitioner(partitionedDatabase.getRegisteredPartitions()));
......