Deprecate ManagedNewTransactionRunner et al.
[genius.git] / mdsalutil / mdsalutil-api / src / main / java / org / opendaylight / genius / infra / ManagedNewTransactionRunnerImpl.java
1 /*
2  * Copyright (c) 2017 Red Hat, Inc. and others. All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.genius.infra;
9
10 import com.google.common.annotations.Beta;
11 import com.google.common.util.concurrent.FluentFuture;
12 import com.google.common.util.concurrent.Futures;
13 import com.google.common.util.concurrent.ListenableFuture;
14 import edu.umd.cs.findbugs.annotations.CheckReturnValue;
15 import java.util.function.Function;
16 import javax.inject.Inject;
17 import org.opendaylight.infrautils.utils.function.InterruptibleCheckedConsumer;
18 import org.opendaylight.infrautils.utils.function.InterruptibleCheckedFunction;
19 import org.opendaylight.mdsal.binding.api.DataBroker;
20 import org.opendaylight.mdsal.binding.api.ReadWriteTransaction;
21 import org.opendaylight.mdsal.binding.api.Transaction;
22 import org.opendaylight.mdsal.binding.api.TransactionChain;
23 import org.opendaylight.mdsal.binding.api.TransactionChainListener;
24 import org.opendaylight.mdsal.binding.api.WriteTransaction;
25 import org.opendaylight.mdsal.common.api.CommitInfo;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29
30 /**
31  * Implementation of {@link ManagedNewTransactionRunner}. This is based on {@link ManagedTransactionFactoryImpl} but
32  * re-implements operations based on (read-)write transactions to cancel transactions which don't end up making any
33  * changes to the datastore.
34  *
35  * @deprecated Use {@link org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunnerImpl} instead.
36  */
37 @Beta
38 @Deprecated(forRemoval = true)
39 // Do *NOT* mark this as @Singleton, because users choose Impl; and as long as this in API, because of https://wiki.opendaylight.org/view/BestPractices/DI_Guidelines#Nota_Bene
40 public class ManagedNewTransactionRunnerImpl extends ManagedTransactionFactoryImpl
41         implements ManagedNewTransactionRunner {
42
43     private static final Logger LOG = LoggerFactory.getLogger(ManagedNewTransactionRunnerImpl.class);
44
45     private final DataBroker broker;
46
47     @Inject
48     public ManagedNewTransactionRunnerImpl(DataBroker broker) {
49         super(broker);
50         this.broker = broker;
51     }
52
53     @Override
54     @CheckReturnValue
55     public <E extends Exception> ListenableFuture<Void>
56             callWithNewWriteOnlyTransactionAndSubmit(InterruptibleCheckedConsumer<WriteTransaction, E> txConsumer) {
57         return callWithNewTransactionAndSubmit(Datastore.class, broker::newWriteOnlyTransaction,
58             (datastoreType, realTx) -> new NonSubmitCancelableWriteTransaction(realTx),
59             txConsumer::accept, (realTx, wrappedTx) -> realTx.commit());
60     }
61
62     @Override
63     @CheckReturnValue
64     public <D extends Datastore, E extends Exception> FluentFuture<Void> callWithNewWriteOnlyTransactionAndSubmit(
65         Class<D> datastoreType, InterruptibleCheckedConsumer<TypedWriteTransaction<D>, E> txConsumer) {
66         return callWithNewTransactionAndSubmit(datastoreType, broker::newWriteOnlyTransaction,
67             WriteTrackingTypedWriteTransactionImpl::new, txConsumer::accept, this::commit);
68     }
69
70     @Override
71     @CheckReturnValue
72     public <E extends Exception> ListenableFuture<Void>
73             callWithNewReadWriteTransactionAndSubmit(InterruptibleCheckedConsumer<ReadWriteTransaction, E> txConsumer) {
74         return callWithNewTransactionAndSubmit(Datastore.class, broker::newReadWriteTransaction,
75             (datastoreType, realTx) -> new NonSubmitCancelableReadWriteTransaction(realTx), txConsumer::accept,
76             this::commit);
77     }
78
79     @Override
80     @CheckReturnValue
81     public <D extends Datastore, E extends Exception> FluentFuture<Void>
82         callWithNewReadWriteTransactionAndSubmit(Class<D> datastoreType,
83             InterruptibleCheckedConsumer<TypedReadWriteTransaction<D>, E> txConsumer) {
84         return callWithNewTransactionAndSubmit(datastoreType, broker::newReadWriteTransaction,
85             WriteTrackingTypedReadWriteTransactionImpl::new, txConsumer::accept, this::commit);
86     }
87
88     @Override
89     @CheckReturnValue
90     public <D extends Datastore, E extends Exception, R> FluentFuture<R> applyWithNewReadWriteTransactionAndSubmit(
91             Class<D> datastoreType, InterruptibleCheckedFunction<TypedReadWriteTransaction<D>, R, E> txFunction) {
92         return super.applyWithNewTransactionAndSubmit(datastoreType, broker::newReadWriteTransaction,
93             WriteTrackingTypedReadWriteTransactionImpl::new, txFunction::apply, this::commit);
94     }
95
96     @Override
97     public <R> R applyWithNewTransactionChainAndClose(Function<ManagedTransactionChain, R> chainConsumer) {
98         try (TransactionChain realTxChain = broker.createTransactionChain(new TransactionChainListener() {
99             @Override
100             public void onTransactionChainFailed(TransactionChain chain, Transaction transaction,
101                 Throwable cause) {
102                 LOG.error("Error handling a transaction chain", cause);
103             }
104
105             @Override
106             public void onTransactionChainSuccessful(TransactionChain chain) {
107                 // Nothing to do
108             }
109         })) {
110             return chainConsumer.apply(new ManagedTransactionChainImpl(realTxChain));
111         }
112     }
113
114     @CheckReturnValue
115     private FluentFuture<? extends CommitInfo> commit(WriteTransaction realTx, WriteTrackingTransaction wrappedTx) {
116         if (wrappedTx.isWritten()) {
117             // The transaction contains changes, commit it
118             return realTx.commit();
119         } else {
120             // The transaction only handled reads, cancel it
121             realTx.cancel();
122             return FluentFuture.from(Futures.immediateFuture(CommitInfo.empty()));
123         }
124     }
125 }