blob: 43cacb3fd572eb19c8c271e6c12b0543166f2d1f [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 Jampani74da78b2016-02-09 21:18:36 -080027import org.onosproject.store.primitives.MapUpdate;
Madan Jampanicadd70b2016-02-08 13:45:43 -080028import org.onosproject.store.primitives.TransactionId;
29import org.onosproject.store.primitives.resources.impl.CommitResult;
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);
Madan Jampani538be742016-02-10 14:55:38 -080085 return txMaps.computeIfAbsent(mapName, name -> {
86 ConsistentMapBuilder mapBuilder = (ConsistentMapBuilder) mapBuilderSupplier.get()
87 .withName(name)
88 .withSerializer(serializer);
89 return new DefaultTransactionalMap<>(
Madan Jampanibff6d8f2015-03-31 16:53:47 -070090 name,
Madan Jampani538be742016-02-10 14:55:38 -080091 mapBuilder.buildAsyncMap(),
Madan Jampanibff6d8f2015-03-31 16:53:47 -070092 this,
Madan Jampani538be742016-02-10 14:55:38 -080093 serializer);
94 });
Madan Jampani64689552015-02-17 10:00:27 -080095 }
96
Ray Milkey8dc82082015-02-20 16:22:38 -080097 @SuppressWarnings("unchecked")
Madan Jampani64689552015-02-17 10:00:27 -080098 @Override
Sho SHIMIZUd936b422015-11-02 16:38:18 -080099 public boolean commit() {
Madan Jampanibab51a42015-08-10 13:53:35 -0700100 // TODO: rework commit implementation to be more intuitive
Madan Jampani64689552015-02-17 10:00:27 -0800101 checkState(isOpen, TX_NOT_OPEN_ERROR);
Madan Jampanicadd70b2016-02-08 13:45:43 -0800102 CommitResult result = null;
Madan Jampani64689552015-02-17 10:00:27 -0800103 try {
Madan Jampanicadd70b2016-02-08 13:45:43 -0800104 List<MapUpdate<String, byte[]>> updates = Lists.newLinkedList();
105 txMaps.values().forEach(m -> updates.addAll(m.toMapUpdates()));
106 Transaction transaction = new Transaction(transactionId, updates);
107 result = Futures.getUnchecked(transactionCommitter.apply(transaction));
108 return result == CommitResult.OK;
Sho SHIMIZUd936b422015-11-02 16:38:18 -0800109 } catch (Exception e) {
110 abort();
111 return false;
Madan Jampani64689552015-02-17 10:00:27 -0800112 } finally {
113 isOpen = false;
114 }
115 }
116
117 @Override
Madan Jampanibff6d8f2015-03-31 16:53:47 -0700118 public void abort() {
Madan Jampanibab51a42015-08-10 13:53:35 -0700119 if (isOpen) {
120 try {
Madan Jampani74da78b2016-02-09 21:18:36 -0800121 txMaps.values().forEach(m -> m.abort());
Madan Jampanibab51a42015-08-10 13:53:35 -0700122 } finally {
123 isOpen = false;
124 }
125 }
Madan Jampani64689552015-02-17 10:00:27 -0800126 }
HIGUCHI Yutadc4394c2016-01-29 15:35:10 -0800127
128 @Override
129 public String toString() {
130 ToStringHelper s = MoreObjects.toStringHelper(this)
131 .add("transactionId", transactionId)
132 .add("isOpen", isOpen);
133
134 txMaps.entrySet().forEach(e -> {
135 s.add(e.getKey(), e.getValue());
136 });
137 return s.toString();
138 }
Madan Jampanicadd70b2016-02-08 13:45:43 -0800139
140 @Override
141 public String name() {
142 return transactionId.toString();
143 }
Madan Jampani02b7fb82015-05-01 13:01:20 -0700144}