blob: 73888221fc5c74f3cfe12f32119bc0dd3ae5e34d [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
17package org.onosproject.store.consistent.impl;
18
19import java.util.List;
20import java.util.Map;
Madan Jampani50589ac2015-06-08 11:38:46 -070021import java.util.function.Supplier;
Madan Jampani64689552015-02-17 10:00:27 -080022
23import static com.google.common.base.Preconditions.*;
24
Madan Jampani50589ac2015-06-08 11:38:46 -070025import org.onosproject.store.service.ConsistentMapBuilder;
Madan Jampanibff6d8f2015-03-31 16:53:47 -070026import org.onosproject.store.service.DatabaseUpdate;
Madan Jampani64689552015-02-17 10:00:27 -080027import org.onosproject.store.service.Serializer;
Madan Jampanibab51a42015-08-10 13:53:35 -070028import org.onosproject.store.service.Transaction;
Madan Jampani64689552015-02-17 10:00:27 -080029import org.onosproject.store.service.TransactionContext;
Madan Jampani64689552015-02-17 10:00:27 -080030import org.onosproject.store.service.TransactionalMap;
Madan Jampani64689552015-02-17 10:00:27 -080031
32import com.google.common.collect.Lists;
33import com.google.common.collect.Maps;
Madan Jampanibab51a42015-08-10 13:53:35 -070034import com.google.common.util.concurrent.Futures;
Madan Jampani64689552015-02-17 10:00:27 -080035
36/**
37 * Default TransactionContext implementation.
38 */
39public class DefaultTransactionContext implements TransactionContext {
Madan Jampanibff6d8f2015-03-31 16:53:47 -070040 private static final String TX_NOT_OPEN_ERROR = "Transaction Context is not open";
41
42 @SuppressWarnings("rawtypes")
43 private final Map<String, DefaultTransactionalMap> txMaps = Maps.newConcurrentMap();
Madan Jampani64689552015-02-17 10:00:27 -080044 private boolean isOpen = false;
Madan Jampanif1b8e172015-03-23 11:42:02 -070045 private final Database database;
Madan Jampanibff6d8f2015-03-31 16:53:47 -070046 private final long transactionId;
Madan Jampani50589ac2015-06-08 11:38:46 -070047 private final Supplier<ConsistentMapBuilder> mapBuilderSupplier;
Madan Jampani64689552015-02-17 10:00:27 -080048
Madan Jampani50589ac2015-06-08 11:38:46 -070049 public DefaultTransactionContext(long transactionId,
50 Database database,
51 Supplier<ConsistentMapBuilder> mapBuilderSupplier) {
Madan Jampanibff6d8f2015-03-31 16:53:47 -070052 this.transactionId = transactionId;
Madan Jampani50589ac2015-06-08 11:38:46 -070053 this.database = checkNotNull(database);
54 this.mapBuilderSupplier = checkNotNull(mapBuilderSupplier);
Madan Jampanibff6d8f2015-03-31 16:53:47 -070055 }
56
57 @Override
58 public long transactionId() {
59 return transactionId;
Madan Jampani64689552015-02-17 10:00:27 -080060 }
61
62 @Override
63 public void begin() {
Madan Jampanibff6d8f2015-03-31 16:53:47 -070064 checkState(!isOpen, "Transaction Context is already open");
Madan Jampani64689552015-02-17 10:00:27 -080065 isOpen = true;
66 }
67
68 @Override
Madan Jampanibff6d8f2015-03-31 16:53:47 -070069 public boolean isOpen() {
70 return isOpen;
71 }
72
73 @Override
Ray Milkey8dc82082015-02-20 16:22:38 -080074 @SuppressWarnings("unchecked")
Madan Jampanibff6d8f2015-03-31 16:53:47 -070075 public <K, V> TransactionalMap<K, V> getTransactionalMap(String mapName,
Madan Jampani64689552015-02-17 10:00:27 -080076 Serializer serializer) {
Madan Jampani64689552015-02-17 10:00:27 -080077 checkState(isOpen, TX_NOT_OPEN_ERROR);
Madan Jampanibff6d8f2015-03-31 16:53:47 -070078 checkNotNull(mapName);
79 checkNotNull(serializer);
80 return txMaps.computeIfAbsent(mapName, name -> new DefaultTransactionalMap<>(
81 name,
Madan Jampani50589ac2015-06-08 11:38:46 -070082 mapBuilderSupplier.get().withName(name).withSerializer(serializer).build(),
Madan Jampanibff6d8f2015-03-31 16:53:47 -070083 this,
84 serializer));
Madan Jampani64689552015-02-17 10:00:27 -080085 }
86
Ray Milkey8dc82082015-02-20 16:22:38 -080087 @SuppressWarnings("unchecked")
Madan Jampani64689552015-02-17 10:00:27 -080088 @Override
Sho SHIMIZUd936b422015-11-02 16:38:18 -080089 public boolean commit() {
Madan Jampanibab51a42015-08-10 13:53:35 -070090 // TODO: rework commit implementation to be more intuitive
Madan Jampani64689552015-02-17 10:00:27 -080091 checkState(isOpen, TX_NOT_OPEN_ERROR);
Madan Jampanibab51a42015-08-10 13:53:35 -070092 CommitResponse response = null;
Madan Jampani64689552015-02-17 10:00:27 -080093 try {
Madan Jampanibff6d8f2015-03-31 16:53:47 -070094 List<DatabaseUpdate> updates = Lists.newLinkedList();
Madan Jampanibab51a42015-08-10 13:53:35 -070095 txMaps.values().forEach(m -> updates.addAll(m.prepareDatabaseUpdates()));
96 Transaction transaction = new DefaultTransaction(transactionId, updates);
97 response = Futures.getUnchecked(database.prepareAndCommit(transaction));
Sho SHIMIZUd936b422015-11-02 16:38:18 -080098 return response.success();
99 } catch (Exception e) {
100 abort();
101 return false;
Madan Jampani64689552015-02-17 10:00:27 -0800102 } finally {
103 isOpen = false;
104 }
105 }
106
107 @Override
Madan Jampanibff6d8f2015-03-31 16:53:47 -0700108 public void abort() {
Madan Jampanibab51a42015-08-10 13:53:35 -0700109 if (isOpen) {
110 try {
111 txMaps.values().forEach(m -> m.rollback());
112 } finally {
113 isOpen = false;
114 }
115 }
Madan Jampani64689552015-02-17 10:00:27 -0800116 }
Madan Jampani02b7fb82015-05-01 13:01:20 -0700117}