2 * Copyright (c) 2017 Red Hat, Inc. and others. All rights reserved.
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
8 package org.opendaylight.mdsal.binding.util;
10 import static java.util.Objects.requireNonNull;
12 import com.google.common.annotations.Beta;
13 import com.google.common.util.concurrent.FluentFuture;
14 import edu.umd.cs.findbugs.annotations.CheckReturnValue;
15 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
16 import java.util.function.Function;
17 import javax.inject.Inject;
18 import org.opendaylight.mdsal.binding.api.DataBroker;
19 import org.opendaylight.mdsal.binding.api.Transaction;
20 import org.opendaylight.mdsal.binding.api.TransactionChain;
21 import org.opendaylight.mdsal.binding.api.TransactionChainListener;
22 import org.opendaylight.mdsal.binding.api.WriteTransaction;
23 import org.opendaylight.mdsal.common.api.CommitInfo;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
28 * Implementation of {@link ManagedNewTransactionRunner}. This is based on {@link ManagedTransactionFactoryImpl} but
29 * re-implements operations based on read-write transactions to cancel transactions which don't end up making any
30 * changes to the datastore.
33 // Do *NOT* mark this as @Singleton, because users choose their implementation
34 public class ManagedNewTransactionRunnerImpl extends ManagedTransactionFactoryImpl<DataBroker>
35 implements ManagedNewTransactionRunner {
37 private static final Logger LOG = LoggerFactory.getLogger(ManagedNewTransactionRunnerImpl.class);
40 public ManagedNewTransactionRunnerImpl(final DataBroker broker) {
41 // Early check to ensure the error message is understandable for the caller
42 super(requireNonNull(broker, "broker must not be null"));
45 // This is overridden to use this class’s commit method
48 public <D extends Datastore, E extends Exception, R> FluentFuture<R> applyWithNewReadWriteTransactionAndSubmit(
49 final D datastore, final InterruptibleCheckedFunction<TypedReadWriteTransaction<D>, R, E> txFunction) {
50 return super.applyWithNewTransactionAndSubmit(datastore, getTransactionFactory()::newReadWriteTransaction,
51 WriteTrackingTypedReadWriteTransactionImpl::new, txFunction::apply, this::commit);
55 @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE")
56 public <R> R applyWithNewTransactionChainAndClose(final Function<ManagedTransactionChain, R> chainConsumer) {
57 try (TransactionChain realTxChain = getTransactionFactory().createTransactionChain(
58 new TransactionChainListener() {
60 public void onTransactionChainFailed(TransactionChain chain, Transaction transaction, Throwable cause) {
61 LOG.error("Error handling a transaction chain", cause);
65 public void onTransactionChainSuccessful(TransactionChain chain) {
69 return chainConsumer.apply(new ManagedTransactionChainImpl(realTxChain));
73 // This is overridden to use this class’s commit method
76 public <D extends Datastore, E extends Exception>
77 FluentFuture<? extends Object> callWithNewReadWriteTransactionAndSubmit(final D datastore,
78 final InterruptibleCheckedConsumer<TypedReadWriteTransaction<D>, E> txConsumer) {
79 return callWithNewTransactionAndSubmit(datastore, getTransactionFactory()::newReadWriteTransaction,
80 WriteTrackingTypedReadWriteTransactionImpl::new, txConsumer::accept, this::commit);
83 // This is overridden to use this class’s commit method
86 public <D extends Datastore, E extends Exception>
87 FluentFuture<? extends Object> callWithNewWriteOnlyTransactionAndSubmit(final D datastore,
88 final InterruptibleCheckedConsumer<TypedWriteTransaction<D>, E> txConsumer) {
89 return super.callWithNewTransactionAndSubmit(datastore, getTransactionFactory()::newWriteOnlyTransaction,
90 WriteTrackingTypedWriteTransactionImpl::new, txConsumer::accept, this::commit);
94 private FluentFuture<? extends CommitInfo> commit(final WriteTransaction realTx,
95 final WriteTrackingTransaction wrappedTx) {
96 if (wrappedTx.isWritten()) {
97 // The transaction contains changes, commit it
98 return realTx.commit();
101 // The transaction only handled reads, cancel it
103 return CommitInfo.emptyFluentFuture();