Madan Jampani
Committed by Gerrit Code Review

AsyncConsistentMap methods for supporting transactional updates

Change-Id: Iaeb0aa0abf9f52d514a2c040598599a5b8a55ee8
Showing 21 changed files with 353 additions and 71 deletions
...@@ -14,12 +14,13 @@ ...@@ -14,12 +14,13 @@
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 16
17 -package org.onosproject.store.primitives.resources.impl; 17 +package org.onosproject.store.primitives;
18 18
19 -import static com.google.common.base.Preconditions.checkArgument;
20 import static com.google.common.base.Preconditions.checkNotNull; 19 import static com.google.common.base.Preconditions.checkNotNull;
21 import static com.google.common.base.Preconditions.checkState; 20 import static com.google.common.base.Preconditions.checkState;
22 21
22 +import java.util.function.Function;
23 +
23 import com.google.common.base.MoreObjects; 24 import com.google.common.base.MoreObjects;
24 25
25 /** 26 /**
...@@ -126,6 +127,26 @@ public final class MapUpdate<K, V> { ...@@ -126,6 +127,26 @@ public final class MapUpdate<K, V> {
126 return currentVersion; 127 return currentVersion;
127 } 128 }
128 129
130 + /**
131 + * Transforms this instance into an instance of different paramterized types.
132 + *
133 + * @param keyMapper transcoder for key type
134 + * @param valueMapper transcoder to value type
135 + * @return new instance
136 + * @param <S> key type of returned instance
137 + * @param <T> value type of returned instance
138 + */
139 + public <S, T> MapUpdate<S, T> map(Function<K, S> keyMapper, Function<V, T> valueMapper) {
140 + return MapUpdate.<S, T>newBuilder()
141 + .withMapName(mapName)
142 + .withType(type)
143 + .withKey(keyMapper.apply(key))
144 + .withValue(value == null ? null : valueMapper.apply(value))
145 + .withCurrentValue(currentValue == null ? null : valueMapper.apply(currentValue))
146 + .withCurrentVersion(currentVersion)
147 + .build();
148 + }
149 +
129 @Override 150 @Override
130 public String toString() { 151 public String toString() {
131 return MoreObjects.toStringHelper(this) 152 return MoreObjects.toStringHelper(this)
...@@ -180,17 +201,16 @@ public final class MapUpdate<K, V> { ...@@ -180,17 +201,16 @@ public final class MapUpdate<K, V> {
180 } 201 }
181 202
182 public Builder<K, V> withCurrentValue(V value) { 203 public Builder<K, V> withCurrentValue(V value) {
183 - update.currentValue = checkNotNull(value, "currentValue cannot be null"); 204 + update.currentValue = value;
184 return this; 205 return this;
185 } 206 }
186 207
187 public Builder<K, V> withValue(V value) { 208 public Builder<K, V> withValue(V value) {
188 - update.value = checkNotNull(value, "value cannot be null"); 209 + update.value = value;
189 return this; 210 return this;
190 } 211 }
191 212
192 public Builder<K, V> withCurrentVersion(long version) { 213 public Builder<K, V> withCurrentVersion(long version) {
193 - checkArgument(version >= 0, "version cannot be negative");
194 update.currentVersion = version; 214 update.currentVersion = version;
195 return this; 215 return this;
196 } 216 }
......
...@@ -26,6 +26,7 @@ import java.util.function.Function; ...@@ -26,6 +26,7 @@ import java.util.function.Function;
26 import java.util.function.Predicate; 26 import java.util.function.Predicate;
27 27
28 import org.onosproject.store.primitives.DefaultConsistentMap; 28 import org.onosproject.store.primitives.DefaultConsistentMap;
29 +import org.onosproject.store.primitives.TransactionId;
29 30
30 /** 31 /**
31 * A distributed, strongly consistent map whose methods are all executed asynchronously. 32 * A distributed, strongly consistent map whose methods are all executed asynchronously.
...@@ -319,6 +320,37 @@ public interface AsyncConsistentMap<K, V> extends DistributedPrimitive { ...@@ -319,6 +320,37 @@ public interface AsyncConsistentMap<K, V> extends DistributedPrimitive {
319 CompletableFuture<Void> removeListener(MapEventListener<K, V> listener); 320 CompletableFuture<Void> removeListener(MapEventListener<K, V> listener);
320 321
321 /** 322 /**
323 + * Prepares a transaction for commitment.
324 + * @param transaction transaction
325 + * @return {@code true} if prepare is successful and transaction is ready to be committed;
326 + * {@code false} otherwise
327 + */
328 + CompletableFuture<Boolean> prepare(MapTransaction<K, V> transaction);
329 +
330 + /**
331 + * Commits a previously prepared transaction.
332 + * @param transactionId transaction identifier
333 + * @return future that will be completed when the operation finishes
334 + */
335 + CompletableFuture<Void> commit(TransactionId transactionId);
336 +
337 + /**
338 + * Aborts a previously prepared transaction.
339 + * @param transactionId transaction identifier
340 + * @return future that will be completed when the operation finishes
341 + */
342 + CompletableFuture<Void> rollback(TransactionId transactionId);
343 +
344 + /**
345 + * Returns a new {@link ConsistentMap} that is backed by this instance.
346 + *
347 + * @return new {@code ConsistentMap} instance
348 + */
349 + default ConsistentMap<K, V> asConsistentMap() {
350 + return asConsistentMap(DistributedPrimitive.DEFAULT_OPERTATION_TIMEOUT_MILLIS);
351 + }
352 +
353 + /**
322 * Returns a new {@link ConsistentMap} that is backed by this instance. 354 * Returns a new {@link ConsistentMap} that is backed by this instance.
323 * 355 *
324 * @param timeoutMillis timeout duration for the returned ConsistentMap operations 356 * @param timeoutMillis timeout duration for the returned ConsistentMap operations
......
1 +/*
2 + * Copyright 2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.store.service;
17 +
18 +import java.util.List;
19 +import java.util.function.Function;
20 +
21 +import org.onosproject.store.primitives.MapUpdate;
22 +import org.onosproject.store.primitives.TransactionId;
23 +
24 +import com.google.common.collect.ImmutableList;
25 +import com.google.common.collect.Lists;
26 +
27 +/**
28 + * Collection of map updates to be committed atomically.
29 + *
30 + * @param <K> key type
31 + * @param <V> value type
32 + */
33 +public class MapTransaction<K, V> {
34 +
35 + private final TransactionId transactionId;
36 + private final List<MapUpdate<K, V>> updates;
37 +
38 + public MapTransaction(TransactionId transactionId, List<MapUpdate<K, V>> updates) {
39 + this.transactionId = transactionId;
40 + this.updates = ImmutableList.copyOf(updates);
41 + }
42 +
43 + /**
44 + * Returns the transaction identifier.
45 + *
46 + * @return transaction id
47 + */
48 + public TransactionId transactionId() {
49 + return transactionId;
50 + }
51 +
52 + /**
53 + * Returns the list of map updates.
54 + *
55 + * @return map updates
56 + */
57 + public List<MapUpdate<K, V>> updates() {
58 + return updates;
59 + }
60 +
61 + /**
62 + * Maps this instance to another {@code MapTransaction} with different key and value types.
63 + *
64 + * @param keyMapper function for mapping key types
65 + * @param valueMapper function for mapping value types
66 + * @return newly typed instance
67 + *
68 + * @param <S> key type of returned instance
69 + * @param <T> value type of returned instance
70 + */
71 + public <S, T> MapTransaction<S, T> map(Function<K, S> keyMapper, Function<V, T> valueMapper) {
72 + return new MapTransaction<>(transactionId, Lists.transform(updates, u -> u.map(keyMapper, valueMapper)));
73 + }
74 +}
...@@ -13,9 +13,10 @@ ...@@ -13,9 +13,10 @@
13 * See the License for the specific language governing permissions and 13 * See the License for the specific language governing permissions and
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 -package org.onosproject.store.primitives.resources.impl; 16 +package org.onosproject.store.primitives;
17 17
18 import com.google.common.testing.EqualsTester; 18 import com.google.common.testing.EqualsTester;
19 +
19 import org.junit.Test; 20 import org.junit.Test;
20 21
21 import static org.hamcrest.MatcherAssert.assertThat; 22 import static org.hamcrest.MatcherAssert.assertThat;
......
...@@ -32,17 +32,18 @@ import java.util.Scanner; ...@@ -32,17 +32,18 @@ import java.util.Scanner;
32 import org.onlab.util.Match; 32 import org.onlab.util.Match;
33 import org.onosproject.cluster.NodeId; 33 import org.onosproject.cluster.NodeId;
34 import org.onosproject.event.Change; 34 import org.onosproject.event.Change;
35 +import org.onosproject.store.primitives.MapUpdate;
35 import org.onosproject.store.primitives.TransactionId; 36 import org.onosproject.store.primitives.TransactionId;
36 import org.onosproject.store.primitives.resources.impl.AtomixConsistentMapCommands; 37 import org.onosproject.store.primitives.resources.impl.AtomixConsistentMapCommands;
37 import org.onosproject.store.primitives.resources.impl.AtomixConsistentMapState; 38 import org.onosproject.store.primitives.resources.impl.AtomixConsistentMapState;
38 import org.onosproject.store.primitives.resources.impl.AtomixLeaderElectorCommands; 39 import org.onosproject.store.primitives.resources.impl.AtomixLeaderElectorCommands;
39 import org.onosproject.store.primitives.resources.impl.CommitResult; 40 import org.onosproject.store.primitives.resources.impl.CommitResult;
40 import org.onosproject.store.primitives.resources.impl.MapEntryUpdateResult; 41 import org.onosproject.store.primitives.resources.impl.MapEntryUpdateResult;
41 -import org.onosproject.store.primitives.resources.impl.MapUpdate;
42 import org.onosproject.store.primitives.resources.impl.PrepareResult; 42 import org.onosproject.store.primitives.resources.impl.PrepareResult;
43 import org.onosproject.store.primitives.resources.impl.RollbackResult; 43 import org.onosproject.store.primitives.resources.impl.RollbackResult;
44 import org.onosproject.store.serializers.KryoNamespaces; 44 import org.onosproject.store.serializers.KryoNamespaces;
45 import org.onosproject.store.service.MapEvent; 45 import org.onosproject.store.service.MapEvent;
46 +import org.onosproject.store.service.MapTransaction;
46 import org.onosproject.store.service.Versioned; 47 import org.onosproject.store.service.Versioned;
47 48
48 import com.google.common.base.Throwables; 49 import com.google.common.base.Throwables;
...@@ -65,7 +66,7 @@ public final class CatalystSerializers { ...@@ -65,7 +66,7 @@ public final class CatalystSerializers {
65 MapEntryUpdateResult.Status.class, 66 MapEntryUpdateResult.Status.class,
66 MapUpdate.class, 67 MapUpdate.class,
67 MapUpdate.Type.class, 68 MapUpdate.Type.class,
68 - Transaction.class, 69 + MapTransaction.class,
69 Transaction.State.class, 70 Transaction.State.class,
70 TransactionId.class, 71 TransactionId.class,
71 PrepareResult.class, 72 PrepareResult.class,
...@@ -99,7 +100,7 @@ public final class CatalystSerializers { ...@@ -99,7 +100,7 @@ public final class CatalystSerializers {
99 serializer.register(Match.class, factory); 100 serializer.register(Match.class, factory);
100 serializer.register(MapEntryUpdateResult.class, factory); 101 serializer.register(MapEntryUpdateResult.class, factory);
101 serializer.register(MapEntryUpdateResult.Status.class, factory); 102 serializer.register(MapEntryUpdateResult.Status.class, factory);
102 - serializer.register(Transaction.class, factory); 103 + serializer.register(MapTransaction.class, factory);
103 serializer.register(Transaction.State.class, factory); 104 serializer.register(Transaction.State.class, factory);
104 serializer.register(PrepareResult.class, factory); 105 serializer.register(PrepareResult.class, factory);
105 serializer.register(CommitResult.class, factory); 106 serializer.register(CommitResult.class, factory);
......
...@@ -65,8 +65,8 @@ import org.onosproject.cluster.PartitionId; ...@@ -65,8 +65,8 @@ import org.onosproject.cluster.PartitionId;
65 import org.onosproject.core.ApplicationId; 65 import org.onosproject.core.ApplicationId;
66 import org.onosproject.persistence.PersistenceService; 66 import org.onosproject.persistence.PersistenceService;
67 import org.onosproject.store.cluster.messaging.ClusterCommunicationService; 67 import org.onosproject.store.cluster.messaging.ClusterCommunicationService;
68 +import org.onosproject.store.primitives.MapUpdate;
68 import org.onosproject.store.primitives.TransactionId; 69 import org.onosproject.store.primitives.TransactionId;
69 -import org.onosproject.store.primitives.resources.impl.MapUpdate;
70 import org.onosproject.store.serializers.KryoNamespaces; 70 import org.onosproject.store.serializers.KryoNamespaces;
71 import org.onosproject.store.service.AsyncConsistentMap; 71 import org.onosproject.store.service.AsyncConsistentMap;
72 import org.onosproject.store.service.AtomicCounterBuilder; 72 import org.onosproject.store.service.AtomicCounterBuilder;
......
...@@ -21,8 +21,8 @@ import java.nio.ByteBuffer; ...@@ -21,8 +21,8 @@ import java.nio.ByteBuffer;
21 import org.onlab.util.KryoNamespace; 21 import org.onlab.util.KryoNamespace;
22 import org.onlab.util.Match; 22 import org.onlab.util.Match;
23 import org.onosproject.cluster.NodeId; 23 import org.onosproject.cluster.NodeId;
24 +import org.onosproject.store.primitives.MapUpdate;
24 import org.onosproject.store.primitives.TransactionId; 25 import org.onosproject.store.primitives.TransactionId;
25 -import org.onosproject.store.primitives.resources.impl.MapUpdate;
26 import org.onosproject.store.serializers.KryoNamespaces; 26 import org.onosproject.store.serializers.KryoNamespaces;
27 import org.onosproject.store.serializers.KryoSerializer; 27 import org.onosproject.store.serializers.KryoSerializer;
28 import org.onosproject.store.service.Versioned; 28 import org.onosproject.store.service.Versioned;
......
...@@ -40,11 +40,13 @@ import org.onlab.util.Match; ...@@ -40,11 +40,13 @@ import org.onlab.util.Match;
40 import org.onlab.util.SharedExecutors; 40 import org.onlab.util.SharedExecutors;
41 import org.onlab.util.Tools; 41 import org.onlab.util.Tools;
42 import org.onosproject.core.ApplicationId; 42 import org.onosproject.core.ApplicationId;
43 +import org.onosproject.store.primitives.TransactionId;
43 import org.onosproject.store.service.AsyncConsistentMap; 44 import org.onosproject.store.service.AsyncConsistentMap;
44 import org.onosproject.store.service.ConsistentMapException; 45 import org.onosproject.store.service.ConsistentMapException;
45 import org.onosproject.store.service.ConsistentMapException.ConcurrentModification; 46 import org.onosproject.store.service.ConsistentMapException.ConcurrentModification;
46 import org.onosproject.store.service.MapEvent; 47 import org.onosproject.store.service.MapEvent;
47 import org.onosproject.store.service.MapEventListener; 48 import org.onosproject.store.service.MapEventListener;
49 +import org.onosproject.store.service.MapTransaction;
48 import org.onosproject.store.service.Serializer; 50 import org.onosproject.store.service.Serializer;
49 import org.onosproject.store.service.Versioned; 51 import org.onosproject.store.service.Versioned;
50 import org.onosproject.utils.MeteringAgent; 52 import org.onosproject.utils.MeteringAgent;
...@@ -491,6 +493,21 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V ...@@ -491,6 +493,21 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V
491 return CompletableFuture.completedFuture(null); 493 return CompletableFuture.completedFuture(null);
492 } 494 }
493 495
496 + @Override
497 + public CompletableFuture<Boolean> prepare(MapTransaction<K, V> transaction) {
498 + return Tools.exceptionalFuture(new UnsupportedOperationException());
499 + }
500 +
501 + @Override
502 + public CompletableFuture<Void> commit(TransactionId transactionId) {
503 + return Tools.exceptionalFuture(new UnsupportedOperationException());
504 + }
505 +
506 + @Override
507 + public CompletableFuture<Void> rollback(TransactionId transactionId) {
508 + return Tools.exceptionalFuture(new UnsupportedOperationException());
509 + }
510 +
494 protected void notifyListeners(MapEvent<K, V> event) { 511 protected void notifyListeners(MapEvent<K, V> event) {
495 if (event == null) { 512 if (event == null) {
496 return; 513 return;
......
...@@ -26,8 +26,8 @@ import net.kuujo.copycat.state.Initializer; ...@@ -26,8 +26,8 @@ import net.kuujo.copycat.state.Initializer;
26 import net.kuujo.copycat.state.StateContext; 26 import net.kuujo.copycat.state.StateContext;
27 27
28 import org.onlab.util.Match; 28 import org.onlab.util.Match;
29 +import org.onosproject.store.primitives.MapUpdate;
29 import org.onosproject.store.primitives.TransactionId; 30 import org.onosproject.store.primitives.TransactionId;
30 -import org.onosproject.store.primitives.resources.impl.MapUpdate;
31 import org.onosproject.store.service.Versioned; 31 import org.onosproject.store.service.Versioned;
32 32
33 import java.util.Arrays; 33 import java.util.Arrays;
......
...@@ -24,9 +24,9 @@ import java.util.function.Supplier; ...@@ -24,9 +24,9 @@ import java.util.function.Supplier;
24 24
25 import static com.google.common.base.Preconditions.*; 25 import static com.google.common.base.Preconditions.*;
26 26
27 +import org.onosproject.store.primitives.MapUpdate;
27 import org.onosproject.store.primitives.TransactionId; 28 import org.onosproject.store.primitives.TransactionId;
28 import org.onosproject.store.primitives.resources.impl.CommitResult; 29 import org.onosproject.store.primitives.resources.impl.CommitResult;
29 -import org.onosproject.store.primitives.resources.impl.MapUpdate;
30 import org.onosproject.store.service.ConsistentMapBuilder; 30 import org.onosproject.store.service.ConsistentMapBuilder;
31 import org.onosproject.store.service.Serializer; 31 import org.onosproject.store.service.Serializer;
32 import org.onosproject.store.service.TransactionContext; 32 import org.onosproject.store.service.TransactionContext;
...@@ -84,7 +84,10 @@ public class DefaultTransactionContext implements TransactionContext { ...@@ -84,7 +84,10 @@ public class DefaultTransactionContext implements TransactionContext {
84 checkNotNull(serializer); 84 checkNotNull(serializer);
85 return txMaps.computeIfAbsent(mapName, name -> new DefaultTransactionalMap<>( 85 return txMaps.computeIfAbsent(mapName, name -> new DefaultTransactionalMap<>(
86 name, 86 name,
87 - mapBuilderSupplier.get().withName(name).withSerializer(serializer).build(), 87 + mapBuilderSupplier.get()
88 + .withName(name)
89 + .withSerializer(serializer)
90 + .buildAsyncMap(),
88 this, 91 this,
89 serializer)); 92 serializer));
90 } 93 }
...@@ -113,7 +116,7 @@ public class DefaultTransactionContext implements TransactionContext { ...@@ -113,7 +116,7 @@ public class DefaultTransactionContext implements TransactionContext {
113 public void abort() { 116 public void abort() {
114 if (isOpen) { 117 if (isOpen) {
115 try { 118 try {
116 - txMaps.values().forEach(m -> m.rollback()); 119 + txMaps.values().forEach(m -> m.abort());
117 } finally { 120 } finally {
118 isOpen = false; 121 isOpen = false;
119 } 122 }
......
...@@ -19,10 +19,13 @@ package org.onosproject.store.primitives.impl; ...@@ -19,10 +19,13 @@ package org.onosproject.store.primitives.impl;
19 import java.util.List; 19 import java.util.List;
20 import java.util.Map; 20 import java.util.Map;
21 import java.util.Set; 21 import java.util.Set;
22 +import java.util.concurrent.CompletableFuture;
22 23
23 import org.onlab.util.HexString; 24 import org.onlab.util.HexString;
24 -import org.onosproject.store.primitives.resources.impl.MapUpdate; 25 +import org.onosproject.store.primitives.MapUpdate;
26 +import org.onosproject.store.service.AsyncConsistentMap;
25 import org.onosproject.store.service.ConsistentMap; 27 import org.onosproject.store.service.ConsistentMap;
28 +import org.onosproject.store.service.MapTransaction;
26 import org.onosproject.store.service.Serializer; 29 import org.onosproject.store.service.Serializer;
27 import org.onosproject.store.service.TransactionContext; 30 import org.onosproject.store.service.TransactionContext;
28 import org.onosproject.store.service.TransactionalMap; 31 import org.onosproject.store.service.TransactionalMap;
...@@ -46,11 +49,12 @@ import com.google.common.collect.Sets; ...@@ -46,11 +49,12 @@ import com.google.common.collect.Sets;
46 * @param <K> key type 49 * @param <K> key type
47 * @param <V> value type. 50 * @param <V> value type.
48 */ 51 */
49 -public class DefaultTransactionalMap<K, V> implements TransactionalMap<K, V> { 52 +public class DefaultTransactionalMap<K, V> implements TransactionalMap<K, V>, TransactionParticipant {
50 53
51 private final TransactionContext txContext; 54 private final TransactionContext txContext;
52 private static final String TX_CLOSED_ERROR = "Transaction is closed"; 55 private static final String TX_CLOSED_ERROR = "Transaction is closed";
53 - private final ConsistentMap<K, V> backingMap; 56 + private final AsyncConsistentMap<K, V> backingMap;
57 + private final ConsistentMap<K, V> backingConsitentMap;
54 private final String name; 58 private final String name;
55 private final Serializer serializer; 59 private final Serializer serializer;
56 private final Map<K, Versioned<V>> readCache = Maps.newConcurrentMap(); 60 private final Map<K, Versioned<V>> readCache = Maps.newConcurrentMap();
...@@ -76,11 +80,12 @@ public class DefaultTransactionalMap<K, V> implements TransactionalMap<K, V> { ...@@ -76,11 +80,12 @@ public class DefaultTransactionalMap<K, V> implements TransactionalMap<K, V> {
76 80
77 public DefaultTransactionalMap( 81 public DefaultTransactionalMap(
78 String name, 82 String name,
79 - ConsistentMap<K, V> backingMap, 83 + AsyncConsistentMap<K, V> backingMap,
80 TransactionContext txContext, 84 TransactionContext txContext,
81 Serializer serializer) { 85 Serializer serializer) {
82 this.name = name; 86 this.name = name;
83 this.backingMap = backingMap; 87 this.backingMap = backingMap;
88 + this.backingConsitentMap = backingMap.asConsistentMap();
84 this.txContext = txContext; 89 this.txContext = txContext;
85 this.serializer = serializer; 90 this.serializer = serializer;
86 } 91 }
...@@ -96,7 +101,7 @@ public class DefaultTransactionalMap<K, V> implements TransactionalMap<K, V> { ...@@ -96,7 +101,7 @@ public class DefaultTransactionalMap<K, V> implements TransactionalMap<K, V> {
96 if (latest != null) { 101 if (latest != null) {
97 return latest; 102 return latest;
98 } else { 103 } else {
99 - Versioned<V> v = readCache.computeIfAbsent(key, k -> backingMap.get(k)); 104 + Versioned<V> v = readCache.computeIfAbsent(key, k -> backingConsitentMap.get(k));
100 return v != null ? v.value() : null; 105 return v != null ? v.value() : null;
101 } 106 }
102 } 107 }
...@@ -159,6 +164,62 @@ public class DefaultTransactionalMap<K, V> implements TransactionalMap<K, V> { ...@@ -159,6 +164,62 @@ public class DefaultTransactionalMap<K, V> implements TransactionalMap<K, V> {
159 return latest; 164 return latest;
160 } 165 }
161 166
167 + @Override
168 + public CompletableFuture<Boolean> prepare() {
169 + return backingMap.prepare(new MapTransaction<>(txContext.transactionId(), updates()));
170 + }
171 +
172 + @Override
173 + public CompletableFuture<Void> commit() {
174 + return backingMap.commit(txContext.transactionId());
175 + }
176 +
177 + @Override
178 + public CompletableFuture<Void> rollback() {
179 + return backingMap.rollback(txContext.transactionId());
180 + }
181 +
182 + @Override
183 + public boolean hasPendingUpdates() {
184 + return updates().size() > 0;
185 + }
186 +
187 + protected List<MapUpdate<K, V>> updates() {
188 + List<MapUpdate<K, V>> updates = Lists.newLinkedList();
189 + deleteSet.forEach(key -> {
190 + Versioned<V> original = readCache.get(key);
191 + if (original != null) {
192 + updates.add(MapUpdate.<K, V>newBuilder()
193 + .withMapName(name)
194 + .withType(MapUpdate.Type.REMOVE_IF_VERSION_MATCH)
195 + .withKey(key)
196 + .withCurrentVersion(original.version())
197 + .build());
198 + }
199 + });
200 + writeCache.forEach((key, value) -> {
201 + Versioned<V> original = readCache.get(key);
202 + if (original == null) {
203 + updates.add(MapUpdate.<K, V>newBuilder()
204 + .withMapName(name)
205 + .withType(MapUpdate.Type.PUT_IF_ABSENT)
206 + .withKey(key)
207 + .withValue(value)
208 + .build());
209 + } else {
210 + updates.add(MapUpdate.<K, V>newBuilder()
211 + .withMapName(name)
212 + .withType(MapUpdate.Type.PUT_IF_VERSION_MATCH)
213 + .withKey(key)
214 + .withCurrentVersion(original.version())
215 + .withValue(value)
216 + .build());
217 + }
218 + });
219 + return updates;
220 + }
221 +
222 +
162 protected List<MapUpdate<String, byte[]>> toMapUpdates() { 223 protected List<MapUpdate<String, byte[]>> toMapUpdates() {
163 List<MapUpdate<String, byte[]>> updates = Lists.newLinkedList(); 224 List<MapUpdate<String, byte[]>> updates = Lists.newLinkedList();
164 deleteSet.forEach(key -> { 225 deleteSet.forEach(key -> {
...@@ -194,19 +255,18 @@ public class DefaultTransactionalMap<K, V> implements TransactionalMap<K, V> { ...@@ -194,19 +255,18 @@ public class DefaultTransactionalMap<K, V> implements TransactionalMap<K, V> {
194 return updates; 255 return updates;
195 } 256 }
196 257
197 - // TODO: build expected result Map processing DB updates?
198 @Override 258 @Override
199 public String toString() { 259 public String toString() {
200 return MoreObjects.toStringHelper(this) 260 return MoreObjects.toStringHelper(this)
201 .add("backingMap", backingMap) 261 .add("backingMap", backingMap)
202 - .add("updates", toMapUpdates()) 262 + .add("updates", updates())
203 .toString(); 263 .toString();
204 } 264 }
205 265
206 /** 266 /**
207 * Discards all changes made to this transactional map. 267 * Discards all changes made to this transactional map.
208 */ 268 */
209 - protected void rollback() { 269 + protected void abort() {
210 readCache.clear(); 270 readCache.clear();
211 writeCache.clear(); 271 writeCache.clear();
212 deleteSet.clear(); 272 deleteSet.clear();
......
...@@ -27,8 +27,10 @@ import java.util.function.BiFunction; ...@@ -27,8 +27,10 @@ import java.util.function.BiFunction;
27 import java.util.function.Predicate; 27 import java.util.function.Predicate;
28 28
29 import org.onosproject.core.ApplicationId; 29 import org.onosproject.core.ApplicationId;
30 +import org.onosproject.store.primitives.TransactionId;
30 import org.onosproject.store.service.AsyncConsistentMap; 31 import org.onosproject.store.service.AsyncConsistentMap;
31 import org.onosproject.store.service.MapEventListener; 32 import org.onosproject.store.service.MapEventListener;
33 +import org.onosproject.store.service.MapTransaction;
32 import org.onosproject.store.service.Versioned; 34 import org.onosproject.store.service.Versioned;
33 35
34 import com.google.common.base.MoreObjects; 36 import com.google.common.base.MoreObjects;
...@@ -161,6 +163,21 @@ public class DelegatingAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, ...@@ -161,6 +163,21 @@ public class DelegatingAsyncConsistentMap<K, V> implements AsyncConsistentMap<K,
161 } 163 }
162 164
163 @Override 165 @Override
166 + public CompletableFuture<Boolean> prepare(MapTransaction<K, V> transaction) {
167 + return delegateMap.prepare(transaction);
168 + }
169 +
170 + @Override
171 + public CompletableFuture<Void> commit(TransactionId transactionId) {
172 + return delegateMap.commit(transactionId);
173 + }
174 +
175 + @Override
176 + public CompletableFuture<Void> rollback(TransactionId transactionId) {
177 + return delegateMap.rollback(transactionId);
178 + }
179 +
180 + @Override
164 public String toString() { 181 public String toString() {
165 return MoreObjects.toStringHelper(getClass()) 182 return MoreObjects.toStringHelper(getClass())
166 .add("delegateMap", delegateMap) 183 .add("delegateMap", delegateMap)
......
...@@ -28,10 +28,15 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -28,10 +28,15 @@ import java.util.concurrent.atomic.AtomicBoolean;
28 import java.util.concurrent.atomic.AtomicInteger; 28 import java.util.concurrent.atomic.AtomicInteger;
29 import java.util.function.BiFunction; 29 import java.util.function.BiFunction;
30 import java.util.function.Predicate; 30 import java.util.function.Predicate;
31 +import java.util.stream.Collectors;
31 32
33 +import org.onlab.util.Tools;
32 import org.onosproject.cluster.PartitionId; 34 import org.onosproject.cluster.PartitionId;
35 +import org.onosproject.store.primitives.MapUpdate;
36 +import org.onosproject.store.primitives.TransactionId;
33 import org.onosproject.store.service.AsyncConsistentMap; 37 import org.onosproject.store.service.AsyncConsistentMap;
34 import org.onosproject.store.service.MapEventListener; 38 import org.onosproject.store.service.MapEventListener;
39 +import org.onosproject.store.service.MapTransaction;
35 import org.onosproject.store.service.Versioned; 40 import org.onosproject.store.service.Versioned;
36 41
37 import com.google.common.collect.Lists; 42 import com.google.common.collect.Lists;
...@@ -198,6 +203,39 @@ public class PartitionedAsyncConsistentMap<K, V> implements AsyncConsistentMap<K ...@@ -198,6 +203,39 @@ public class PartitionedAsyncConsistentMap<K, V> implements AsyncConsistentMap<K
198 .toArray(CompletableFuture[]::new)); 203 .toArray(CompletableFuture[]::new));
199 } 204 }
200 205
206 + @Override
207 + public CompletableFuture<Boolean> prepare(MapTransaction<K, V> transaction) {
208 +
209 + Map<AsyncConsistentMap<K, V>, List<MapUpdate<K, V>>> updatesGroupedByMap = Maps.newIdentityHashMap();
210 + transaction.updates().forEach(update -> {
211 + AsyncConsistentMap<K, V> map = getMap(update.key());
212 + updatesGroupedByMap.computeIfAbsent(map, k -> Lists.newLinkedList()).add(update);
213 + });
214 + Map<AsyncConsistentMap<K, V>, MapTransaction<K, V>> transactionsByMap =
215 + Maps.transformValues(updatesGroupedByMap,
216 + list -> new MapTransaction<>(transaction.transactionId(), list));
217 +
218 + return Tools.allOf(transactionsByMap.entrySet()
219 + .stream()
220 + .map(e -> e.getKey().prepare(e.getValue()))
221 + .collect(Collectors.toList()))
222 + .thenApply(list -> list.stream().reduce(Boolean::logicalAnd).orElse(true));
223 + }
224 +
225 + @Override
226 + public CompletableFuture<Void> commit(TransactionId transactionId) {
227 + return CompletableFuture.allOf(getMaps().stream()
228 + .map(e -> e.commit(transactionId))
229 + .toArray(CompletableFuture[]::new));
230 + }
231 +
232 + @Override
233 + public CompletableFuture<Void> rollback(TransactionId transactionId) {
234 + return CompletableFuture.allOf(getMaps().stream()
235 + .map(e -> e.rollback(transactionId))
236 + .toArray(CompletableFuture[]::new));
237 + }
238 +
201 /** 239 /**
202 * Returns the map (partition) to which the specified key maps. 240 * Returns the map (partition) to which the specified key maps.
203 * @param key key 241 * @param key key
......
...@@ -26,8 +26,8 @@ import net.kuujo.copycat.cluster.Cluster; ...@@ -26,8 +26,8 @@ import net.kuujo.copycat.cluster.Cluster;
26 import net.kuujo.copycat.resource.ResourceState; 26 import net.kuujo.copycat.resource.ResourceState;
27 27
28 import org.onlab.util.Match; 28 import org.onlab.util.Match;
29 +import org.onosproject.store.primitives.MapUpdate;
29 import org.onosproject.store.primitives.resources.impl.CommitResult; 30 import org.onosproject.store.primitives.resources.impl.CommitResult;
30 -import org.onosproject.store.primitives.resources.impl.MapUpdate;
31 import org.onosproject.store.service.Versioned; 31 import org.onosproject.store.service.Versioned;
32 32
33 import java.util.Collection; 33 import java.util.Collection;
......
...@@ -17,8 +17,8 @@ package org.onosproject.store.primitives.impl; ...@@ -17,8 +17,8 @@ package org.onosproject.store.primitives.impl;
17 17
18 import java.util.List; 18 import java.util.List;
19 19
20 +import org.onosproject.store.primitives.MapUpdate;
20 import org.onosproject.store.primitives.TransactionId; 21 import org.onosproject.store.primitives.TransactionId;
21 -import org.onosproject.store.primitives.resources.impl.MapUpdate;
22 22
23 import com.google.common.base.MoreObjects; 23 import com.google.common.base.MoreObjects;
24 import com.google.common.collect.ImmutableList; 24 import com.google.common.collect.ImmutableList;
......
...@@ -17,34 +17,32 @@ package org.onosproject.store.primitives.impl; ...@@ -17,34 +17,32 @@ package org.onosproject.store.primitives.impl;
17 17
18 import java.util.concurrent.CompletableFuture; 18 import java.util.concurrent.CompletableFuture;
19 19
20 -import org.onosproject.store.primitives.TransactionId;
21 -import org.onosproject.store.primitives.resources.impl.CommitResult;
22 -import org.onosproject.store.primitives.resources.impl.PrepareResult;
23 -import org.onosproject.store.primitives.resources.impl.RollbackResult;
24 -
25 /** 20 /**
26 * Participant in a two-phase commit protocol. 21 * Participant in a two-phase commit protocol.
27 */ 22 */
28 public interface TransactionParticipant { 23 public interface TransactionParticipant {
29 24
30 /** 25 /**
31 - * Attempts to execute the prepare phase for the specified {@link Transaction transaction}. 26 + * Returns if this participant has updates that need to be committed.
32 - * @param transaction transaction 27 + * @return {@code true} if yes; {@code false} otherwise
33 - * @return future for prepare result 28 + */
29 + boolean hasPendingUpdates();
30 +
31 + /**
32 + * Executes the prepare phase.
33 + * @return {@code true} is successful; {@code false} otherwise
34 */ 34 */
35 - CompletableFuture<PrepareResult> prepare(Transaction transaction); 35 + CompletableFuture<Boolean> prepare();
36 36
37 /** 37 /**
38 * Attempts to execute the commit phase for previously prepared transaction. 38 * Attempts to execute the commit phase for previously prepared transaction.
39 - * @param transactionId transaction identifier 39 + * @return future that is completed when the operation completes
40 - * @return future for commit result
41 */ 40 */
42 - CompletableFuture<CommitResult> commit(TransactionId transactionId); 41 + CompletableFuture<Void> commit();
43 42
44 /** 43 /**
45 * Attempts to execute the rollback phase for previously prepared transaction. 44 * Attempts to execute the rollback phase for previously prepared transaction.
46 - * @param transactionId transaction identifier 45 + * @return future that is completed when the operation completes
47 - * @return future for rollback result
48 */ 46 */
49 - CompletableFuture<RollbackResult> rollback(TransactionId transactionId); 47 + CompletableFuture<Void> rollback();
50 } 48 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -26,9 +26,11 @@ import java.util.function.Function; ...@@ -26,9 +26,11 @@ import java.util.function.Function;
26 import java.util.function.Predicate; 26 import java.util.function.Predicate;
27 import java.util.stream.Collectors; 27 import java.util.stream.Collectors;
28 28
29 +import org.onosproject.store.primitives.TransactionId;
29 import org.onosproject.store.service.AsyncConsistentMap; 30 import org.onosproject.store.service.AsyncConsistentMap;
30 import org.onosproject.store.service.MapEvent; 31 import org.onosproject.store.service.MapEvent;
31 import org.onosproject.store.service.MapEventListener; 32 import org.onosproject.store.service.MapEventListener;
33 +import org.onosproject.store.service.MapTransaction;
32 import org.onosproject.store.service.Versioned; 34 import org.onosproject.store.service.Versioned;
33 35
34 import com.google.common.collect.Maps; 36 import com.google.common.collect.Maps;
...@@ -196,6 +198,21 @@ public class TranscodingAsyncConsistentMap<K1, V1, K2, V2> implements AsyncConsi ...@@ -196,6 +198,21 @@ public class TranscodingAsyncConsistentMap<K1, V1, K2, V2> implements AsyncConsi
196 } 198 }
197 } 199 }
198 200
201 + @Override
202 + public CompletableFuture<Boolean> prepare(MapTransaction<K1, V1> transaction) {
203 + return backingMap.prepare(transaction.map(keyEncoder, valueEncoder));
204 + }
205 +
206 + @Override
207 + public CompletableFuture<Void> commit(TransactionId transactionId) {
208 + return backingMap.commit(transactionId);
209 + }
210 +
211 + @Override
212 + public CompletableFuture<Void> rollback(TransactionId transactionId) {
213 + return backingMap.rollback(transactionId);
214 + }
215 +
199 private class InternalBackingMapEventListener implements MapEventListener<K2, V2> { 216 private class InternalBackingMapEventListener implements MapEventListener<K2, V2> {
200 217
201 private final MapEventListener<K1, V1> listener; 218 private final MapEventListener<K1, V1> listener;
......
...@@ -32,11 +32,10 @@ import java.util.function.Predicate; ...@@ -32,11 +32,10 @@ import java.util.function.Predicate;
32 32
33 import org.onlab.util.Match; 33 import org.onlab.util.Match;
34 import org.onosproject.store.primitives.TransactionId; 34 import org.onosproject.store.primitives.TransactionId;
35 -import org.onosproject.store.primitives.impl.Transaction;
36 -import org.onosproject.store.primitives.impl.TransactionParticipant;
37 import org.onosproject.store.service.AsyncConsistentMap; 35 import org.onosproject.store.service.AsyncConsistentMap;
38 import org.onosproject.store.service.MapEvent; 36 import org.onosproject.store.service.MapEvent;
39 import org.onosproject.store.service.MapEventListener; 37 import org.onosproject.store.service.MapEventListener;
38 +import org.onosproject.store.service.MapTransaction;
40 import org.onosproject.store.service.Versioned; 39 import org.onosproject.store.service.Versioned;
41 40
42 import com.google.common.collect.Sets; 41 import com.google.common.collect.Sets;
...@@ -46,7 +45,7 @@ import com.google.common.collect.Sets; ...@@ -46,7 +45,7 @@ import com.google.common.collect.Sets;
46 */ 45 */
47 @ResourceTypeInfo(id = -151, stateMachine = AtomixConsistentMapState.class) 46 @ResourceTypeInfo(id = -151, stateMachine = AtomixConsistentMapState.class)
48 public class AtomixConsistentMap extends Resource<AtomixConsistentMap, Resource.Options> 47 public class AtomixConsistentMap extends Resource<AtomixConsistentMap, Resource.Options>
49 - implements AsyncConsistentMap<String, byte[]>, TransactionParticipant { 48 + implements AsyncConsistentMap<String, byte[]> {
50 49
51 private final Set<MapEventListener<String, byte[]>> mapEventListeners = Sets.newCopyOnWriteArraySet(); 50 private final Set<MapEventListener<String, byte[]>> mapEventListeners = Sets.newCopyOnWriteArraySet();
52 51
...@@ -266,18 +265,21 @@ public class AtomixConsistentMap extends Resource<AtomixConsistentMap, Resource. ...@@ -266,18 +265,21 @@ public class AtomixConsistentMap extends Resource<AtomixConsistentMap, Resource.
266 } 265 }
267 266
268 @Override 267 @Override
269 - public CompletableFuture<PrepareResult> prepare(Transaction transaction) { 268 + public CompletableFuture<Boolean> prepare(MapTransaction<String, byte[]> transaction) {
270 - return submit(new AtomixConsistentMapCommands.TransactionPrepare(transaction)); 269 + return submit(new AtomixConsistentMapCommands.TransactionPrepare(transaction))
270 + .thenApply(v -> v == PrepareResult.OK);
271 } 271 }
272 272
273 @Override 273 @Override
274 - public CompletableFuture<CommitResult> commit(TransactionId transactionId) { 274 + public CompletableFuture<Void> commit(TransactionId transactionId) {
275 - return submit(new AtomixConsistentMapCommands.TransactionCommit(transactionId)); 275 + return submit(new AtomixConsistentMapCommands.TransactionCommit(transactionId))
276 + .thenApply(v -> null);
276 } 277 }
277 278
278 @Override 279 @Override
279 - public CompletableFuture<RollbackResult> rollback(TransactionId transactionId) { 280 + public CompletableFuture<Void> rollback(TransactionId transactionId) {
280 - return submit(new AtomixConsistentMapCommands.TransactionRollback(transactionId)); 281 + return submit(new AtomixConsistentMapCommands.TransactionRollback(transactionId))
282 + .thenApply(v -> null);
281 } 283 }
282 284
283 /** 285 /**
......
...@@ -29,7 +29,7 @@ import java.util.Set; ...@@ -29,7 +29,7 @@ import java.util.Set;
29 29
30 import org.onlab.util.Match; 30 import org.onlab.util.Match;
31 import org.onosproject.store.primitives.TransactionId; 31 import org.onosproject.store.primitives.TransactionId;
32 -import org.onosproject.store.primitives.impl.Transaction; 32 +import org.onosproject.store.service.MapTransaction;
33 import org.onosproject.store.service.Versioned; 33 import org.onosproject.store.service.Versioned;
34 34
35 import com.google.common.base.MoreObjects; 35 import com.google.common.base.MoreObjects;
...@@ -209,35 +209,35 @@ public final class AtomixConsistentMapCommands { ...@@ -209,35 +209,35 @@ public final class AtomixConsistentMapCommands {
209 */ 209 */
210 @SuppressWarnings("serial") 210 @SuppressWarnings("serial")
211 public static class TransactionPrepare extends MapCommand<PrepareResult> { 211 public static class TransactionPrepare extends MapCommand<PrepareResult> {
212 - private Transaction transaction; 212 + private MapTransaction<String, byte[]> mapTransaction;
213 213
214 public TransactionPrepare() { 214 public TransactionPrepare() {
215 } 215 }
216 216
217 - public TransactionPrepare(Transaction transaction) { 217 + public TransactionPrepare(MapTransaction<String, byte[]> mapTransaction) {
218 - this.transaction = transaction; 218 + this.mapTransaction = mapTransaction;
219 } 219 }
220 220
221 - public Transaction transaction() { 221 + public MapTransaction<String, byte[]> transaction() {
222 - return transaction; 222 + return mapTransaction;
223 } 223 }
224 224
225 @Override 225 @Override
226 public void writeObject(BufferOutput<?> buffer, Serializer serializer) { 226 public void writeObject(BufferOutput<?> buffer, Serializer serializer) {
227 super.writeObject(buffer, serializer); 227 super.writeObject(buffer, serializer);
228 - serializer.writeObject(transaction, buffer); 228 + serializer.writeObject(mapTransaction, buffer);
229 } 229 }
230 230
231 @Override 231 @Override
232 public void readObject(BufferInput<?> buffer, Serializer serializer) { 232 public void readObject(BufferInput<?> buffer, Serializer serializer) {
233 super.readObject(buffer, serializer); 233 super.readObject(buffer, serializer);
234 - transaction = serializer.readObject(buffer); 234 + mapTransaction = serializer.readObject(buffer);
235 } 235 }
236 236
237 @Override 237 @Override
238 public String toString() { 238 public String toString() {
239 return MoreObjects.toStringHelper(getClass()) 239 return MoreObjects.toStringHelper(getClass())
240 - .add("transaction", transaction) 240 + .add("mapTransaction", mapTransaction)
241 .toString(); 241 .toString();
242 } 242 }
243 } 243 }
......
...@@ -37,10 +37,11 @@ import java.util.stream.Collectors; ...@@ -37,10 +37,11 @@ import java.util.stream.Collectors;
37 37
38 import org.onlab.util.CountDownCompleter; 38 import org.onlab.util.CountDownCompleter;
39 import org.onlab.util.Match; 39 import org.onlab.util.Match;
40 +import org.onosproject.store.primitives.MapUpdate;
40 import org.onosproject.store.primitives.TransactionId; 41 import org.onosproject.store.primitives.TransactionId;
41 -import org.onosproject.store.primitives.impl.Transaction;
42 import org.onosproject.store.primitives.resources.impl.AtomixConsistentMapCommands.TransactionPrepare; 42 import org.onosproject.store.primitives.resources.impl.AtomixConsistentMapCommands.TransactionPrepare;
43 import org.onosproject.store.service.MapEvent; 43 import org.onosproject.store.service.MapEvent;
44 +import org.onosproject.store.service.MapTransaction;
44 import org.onosproject.store.service.Versioned; 45 import org.onosproject.store.service.Versioned;
45 46
46 import com.google.common.collect.Maps; 47 import com.google.common.collect.Maps;
...@@ -384,7 +385,7 @@ public class AtomixConsistentMapState extends ResourceStateMachine implements ...@@ -384,7 +385,7 @@ public class AtomixConsistentMapState extends ResourceStateMachine implements
384 Commit<? extends AtomixConsistentMapCommands.TransactionPrepare> commit) { 385 Commit<? extends AtomixConsistentMapCommands.TransactionPrepare> commit) {
385 boolean ok = false; 386 boolean ok = false;
386 try { 387 try {
387 - Transaction transaction = commit.operation().transaction(); 388 + MapTransaction<String, byte[]> transaction = commit.operation().transaction();
388 for (MapUpdate<String, byte[]> update : transaction.updates()) { 389 for (MapUpdate<String, byte[]> update : transaction.updates()) {
389 String key = update.key(); 390 String key = update.key();
390 if (preparedKeys.contains(key)) { 391 if (preparedKeys.contains(key)) {
...@@ -404,7 +405,7 @@ public class AtomixConsistentMapState extends ResourceStateMachine implements ...@@ -404,7 +405,7 @@ public class AtomixConsistentMapState extends ResourceStateMachine implements
404 // No violations detected. Add to pendingTranctions and mark 405 // No violations detected. Add to pendingTranctions and mark
405 // modified keys as 406 // modified keys as
406 // currently locked to updates. 407 // currently locked to updates.
407 - pendingTransactions.put(transaction.id(), commit); 408 + pendingTransactions.put(transaction.transactionId(), commit);
408 transaction.updates().forEach(u -> preparedKeys.add(u.key())); 409 transaction.updates().forEach(u -> preparedKeys.add(u.key()));
409 ok = true; 410 ok = true;
410 return PrepareResult.OK; 411 return PrepareResult.OK;
...@@ -430,7 +431,7 @@ public class AtomixConsistentMapState extends ResourceStateMachine implements ...@@ -430,7 +431,7 @@ public class AtomixConsistentMapState extends ResourceStateMachine implements
430 if (prepareCommit == null) { 431 if (prepareCommit == null) {
431 return CommitResult.UNKNOWN_TRANSACTION_ID; 432 return CommitResult.UNKNOWN_TRANSACTION_ID;
432 } 433 }
433 - Transaction transaction = prepareCommit.operation().transaction(); 434 + MapTransaction<String, byte[]> transaction = prepareCommit.operation().transaction();
434 long totalReferencesToCommit = transaction 435 long totalReferencesToCommit = transaction
435 .updates() 436 .updates()
436 .stream() 437 .stream()
...@@ -610,7 +611,7 @@ public class AtomixConsistentMapState extends ResourceStateMachine implements ...@@ -610,7 +611,7 @@ public class AtomixConsistentMapState extends ResourceStateMachine implements
610 611
611 @Override 612 @Override
612 public byte[] value() { 613 public byte[] value() {
613 - Transaction transaction = completer.object().operation().transaction(); 614 + MapTransaction<String, byte[]> transaction = completer.object().operation().transaction();
614 return valueForKey(key, transaction); 615 return valueForKey(key, transaction);
615 } 616 }
616 617
...@@ -624,7 +625,7 @@ public class AtomixConsistentMapState extends ResourceStateMachine implements ...@@ -624,7 +625,7 @@ public class AtomixConsistentMapState extends ResourceStateMachine implements
624 completer.countDown(); 625 completer.countDown();
625 } 626 }
626 627
627 - private byte[] valueForKey(String key, Transaction transaction) { 628 + private byte[] valueForKey(String key, MapTransaction<String, byte[]> transaction) {
628 MapUpdate<String, byte[]> update = transaction.updates() 629 MapUpdate<String, byte[]> update = transaction.updates()
629 .stream() 630 .stream()
630 .filter(u -> u.key().equals(key)) 631 .filter(u -> u.key().equals(key))
......
...@@ -27,10 +27,11 @@ import java.util.stream.Collectors; ...@@ -27,10 +27,11 @@ import java.util.stream.Collectors;
27 import org.junit.Ignore; 27 import org.junit.Ignore;
28 import org.junit.Test; 28 import org.junit.Test;
29 import org.onlab.util.Tools; 29 import org.onlab.util.Tools;
30 +import org.onosproject.store.primitives.MapUpdate;
30 import org.onosproject.store.primitives.TransactionId; 31 import org.onosproject.store.primitives.TransactionId;
31 -import org.onosproject.store.primitives.impl.Transaction;
32 import org.onosproject.store.service.MapEvent; 32 import org.onosproject.store.service.MapEvent;
33 import org.onosproject.store.service.MapEventListener; 33 import org.onosproject.store.service.MapEventListener;
34 +import org.onosproject.store.service.MapTransaction;
34 import org.onosproject.store.service.Versioned; 35 import org.onosproject.store.service.Versioned;
35 36
36 import com.google.common.collect.Sets; 37 import com.google.common.collect.Sets;
...@@ -353,10 +354,10 @@ public class AtomixConsistentMapTest extends AtomixTestBase { ...@@ -353,10 +354,10 @@ public class AtomixConsistentMapTest extends AtomixTestBase {
353 .withValue(value1) 354 .withValue(value1)
354 .build(); 355 .build();
355 356
356 - Transaction tx = new Transaction(TransactionId.from("tx1"), Arrays.asList(update1)); 357 + MapTransaction<String, byte[]> tx = new MapTransaction<>(TransactionId.from("tx1"), Arrays.asList(update1));
357 358
358 map.prepare(tx).thenAccept(result -> { 359 map.prepare(tx).thenAccept(result -> {
359 - assertEquals(PrepareResult.OK, result); 360 + assertEquals(true, result);
360 }).join(); 361 }).join();
361 assertNull(listener.event()); 362 assertNull(listener.event());
362 363
...@@ -377,7 +378,7 @@ public class AtomixConsistentMapTest extends AtomixTestBase { ...@@ -377,7 +378,7 @@ public class AtomixConsistentMapTest extends AtomixTestBase {
377 378
378 assertNull(listener.event()); 379 assertNull(listener.event());
379 380
380 - map.commit(tx.id()).join(); 381 + map.commit(tx.transactionId()).join();
381 assertNotNull(listener.event()); 382 assertNotNull(listener.event());
382 assertEquals(MapEvent.Type.INSERT, listener.event().type()); 383 assertEquals(MapEvent.Type.INSERT, listener.event().type());
383 assertTrue(Arrays.equals(value1, listener.event().newValue().value())); 384 assertTrue(Arrays.equals(value1, listener.event().newValue().value()));
...@@ -407,13 +408,13 @@ public class AtomixConsistentMapTest extends AtomixTestBase { ...@@ -407,13 +408,13 @@ public class AtomixConsistentMapTest extends AtomixTestBase {
407 .withKey("foo") 408 .withKey("foo")
408 .withValue(value1) 409 .withValue(value1)
409 .build(); 410 .build();
410 - Transaction tx = new Transaction(TransactionId.from("tx1"), Arrays.asList(update1)); 411 + MapTransaction<String, byte[]> tx = new MapTransaction<>(TransactionId.from("tx1"), Arrays.asList(update1));
411 map.prepare(tx).thenAccept(result -> { 412 map.prepare(tx).thenAccept(result -> {
412 - assertEquals(PrepareResult.OK, result); 413 + assertEquals(true, result);
413 }).join(); 414 }).join();
414 assertNull(listener.event()); 415 assertNull(listener.event());
415 416
416 - map.rollback(tx.id()).join(); 417 + map.rollback(tx.transactionId()).join();
417 assertNull(listener.event()); 418 assertNull(listener.event());
418 419
419 map.get("foo").thenAccept(result -> { 420 map.get("foo").thenAccept(result -> {
......