blob: d165bc1c3b02acd7ecdcbd9a5610217074b2932b [file] [log] [blame]
Madan Jampani64689552015-02-17 10:00:27 -08001/*
2 * Copyright 2015 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
Madan Jampanif4c88502016-01-21 12:35:36 -080017package org.onosproject.store.primitives.impl;
Madan Jampani64689552015-02-17 10:00:27 -080018
19import java.util.List;
20import java.util.Map;
Madan Jampanicadd70b2016-02-08 13:45:43 -080021import java.util.concurrent.CompletableFuture;
22import java.util.function.Function;
Madan Jampani50589ac2015-06-08 11:38:46 -070023import java.util.function.Supplier;
Madan Jampani64689552015-02-17 10:00:27 -080024
25import static com.google.common.base.Preconditions.*;
26
Madan Jampanicadd70b2016-02-08 13:45:43 -080027import org.onosproject.store.primitives.TransactionId;
28import org.onosproject.store.primitives.resources.impl.CommitResult;
29import org.onosproject.store.primitives.resources.impl.MapUpdate;
Madan Jampani50589ac2015-06-08 11:38:46 -070030import org.onosproject.store.service.ConsistentMapBuilder;
Madan Jampani64689552015-02-17 10:00:27 -080031import org.onosproject.store.service.Serializer;
32import org.onosproject.store.service.TransactionContext;
Madan Jampani64689552015-02-17 10:00:27 -080033import org.onosproject.store.service.TransactionalMap;
Madan Jampani64689552015-02-17 10:00:27 -080034
HIGUCHI Yutadc4394c2016-01-29 15:35:10 -080035import com.google.common.base.MoreObjects;
36import com.google.common.base.MoreObjects.ToStringHelper;
Madan Jampani64689552015-02-17 10:00:27 -080037import com.google.common.collect.Lists;
38import com.google.common.collect.Maps;
Madan Jampanibab51a42015-08-10 13:53:35 -070039import com.google.common.util.concurrent.Futures;
Madan Jampani64689552015-02-17 10:00:27 -080040
41/**
42 * Default TransactionContext implementation.
43 */
44public class DefaultTransactionContext implements TransactionContext {
Madan Jampanibff6d8f2015-03-31 16:53:47 -070045 private static final String TX_NOT_OPEN_ERROR = "Transaction Context is not open";
46
47 @SuppressWarnings("rawtypes")
48 private final Map<String, DefaultTransactionalMap> txMaps = Maps.newConcurrentMap();
Madan Jampani64689552015-02-17 10:00:27 -080049 private boolean isOpen = false;
Madan Jampanicadd70b2016-02-08 13:45:43 -080050 private final Function<Transaction, CompletableFuture<CommitResult>> transactionCommitter;
51 private final TransactionId transactionId;
Madan Jampani50589ac2015-06-08 11:38:46 -070052 private final Supplier<ConsistentMapBuilder> mapBuilderSupplier;
Madan Jampani64689552015-02-17 10:00:27 -080053
Madan Jampanicadd70b2016-02-08 13:45:43 -080054 public DefaultTransactionContext(TransactionId transactionId,
55 Function<Transaction, CompletableFuture<CommitResult>> transactionCommitter,
Madan Jampani50589ac2015-06-08 11:38:46 -070056 Supplier<ConsistentMapBuilder> mapBuilderSupplier) {
Madan Jampanibff6d8f2015-03-31 16:53:47 -070057 this.transactionId = transactionId;
Madan Jampanicadd70b2016-02-08 13:45:43 -080058 this.transactionCommitter = checkNotNull(transactionCommitter);
Madan Jampani50589ac2015-06-08 11:38:46 -070059 this.mapBuilderSupplier = checkNotNull(mapBuilderSupplier);
Madan Jampanibff6d8f2015-03-31 16:53:47 -070060 }
61
62 @Override
Madan Jampanicadd70b2016-02-08 13:45:43 -080063 public TransactionId transactionId() {
Madan Jampanibff6d8f2015-03-31 16:53:47 -070064 return transactionId;
Madan Jampani64689552015-02-17 10:00:27 -080065 }
66
67 @Override
68 public void begin() {
Madan Jampanibff6d8f2015-03-31 16:53:47 -070069 checkState(!isOpen, "Transaction Context is already open");
Madan Jampani64689552015-02-17 10:00:27 -080070 isOpen = true;
71 }
72
73 @Override
Madan Jampanibff6d8f2015-03-31 16:53:47 -070074 public boolean isOpen() {
75 return isOpen;
76 }
77
78 @Override
Ray Milkey8dc82082015-02-20 16:22:38 -080079 @SuppressWarnings("unchecked")
Madan Jampanibff6d8f2015-03-31 16:53:47 -070080 public <K, V> TransactionalMap<K, V> getTransactionalMap(String mapName,
Madan Jampani64689552015-02-17 10:00:27 -080081 Serializer serializer) {
Madan Jampani64689552015-02-17 10:00:27 -080082 checkState(isOpen, TX_NOT_OPEN_ERROR);
Madan Jampanibff6d8f2015-03-31 16:53:47 -070083 checkNotNull(mapName);
84 checkNotNull(serializer);
85 return txMaps.computeIfAbsent(mapName, name -> new DefaultTransactionalMap<>(
86 name,
Madan Jampani50589ac2015-06-08 11:38:46 -070087 mapBuilderSupplier.get().withName(name).withSerializer(serializer).build(),
Madan Jampanibff6d8f2015-03-31 16:53:47 -070088 this,
89 serializer));
Madan Jampani64689552015-02-17 10:00:27 -080090 }
91
Ray Milkey8dc82082015-02-20 16:22:38 -080092 @SuppressWarnings("unchecked")
Madan Jampani64689552015-02-17 10:00:27 -080093 @Override
Sho SHIMIZUd936b422015-11-02 16:38:18 -080094 public boolean commit() {
Madan Jampanibab51a42015-08-10 13:53:35 -070095 // TODO: rework commit implementation to be more intuitive
Madan Jampani64689552015-02-17 10:00:27 -080096 checkState(isOpen, TX_NOT_OPEN_ERROR);
Madan Jampanicadd70b2016-02-08 13:45:43 -080097 CommitResult result = null;
Madan Jampani64689552015-02-17 10:00:27 -080098 try {
Madan Jampanicadd70b2016-02-08 13:45:43 -080099 List<MapUpdate<String, byte[]>> updates = Lists.newLinkedList();
100 txMaps.values().forEach(m -> updates.addAll(m.toMapUpdates()));
101 Transaction transaction = new Transaction(transactionId, updates);
102 result = Futures.getUnchecked(transactionCommitter.apply(transaction));
103 return result == CommitResult.OK;
Sho SHIMIZUd936b422015-11-02 16:38:18 -0800104 } catch (Exception e) {
105 abort();
106 return false;
Madan Jampani64689552015-02-17 10:00:27 -0800107 } finally {
108 isOpen = false;
109 }
110 }
111
112 @Override
Madan Jampanibff6d8f2015-03-31 16:53:47 -0700113 public void abort() {
Madan Jampanibab51a42015-08-10 13:53:35 -0700114 if (isOpen) {
115 try {
116 txMaps.values().forEach(m -> m.rollback());
117 } finally {
118 isOpen = false;
119 }
120 }
Madan Jampani64689552015-02-17 10:00:27 -0800121 }
HIGUCHI Yutadc4394c2016-01-29 15:35:10 -0800122
123 @Override
124 public String toString() {
125 ToStringHelper s = MoreObjects.toStringHelper(this)
126 .add("transactionId", transactionId)
127 .add("isOpen", isOpen);
128
129 txMaps.entrySet().forEach(e -> {
130 s.add(e.getKey(), e.getValue());
131 });
132 return s.toString();
133 }
Madan Jampanicadd70b2016-02-08 13:45:43 -0800134
135 @Override
136 public String name() {
137 return transactionId.toString();
138 }
Madan Jampani02b7fb82015-05-01 13:01:20 -0700139}