2 * Copyright © 2018 Red Hat, Inc. and others.
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.genius.infra;
10 import com.google.common.util.concurrent.FluentFuture;
11 import com.google.common.util.concurrent.Futures;
12 import com.google.common.util.concurrent.ListenableFuture;
13 import edu.umd.cs.findbugs.annotations.CheckReturnValue;
14 import java.util.concurrent.CompletionStage;
15 import java.util.concurrent.Future;
16 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
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.ReadTransaction;
21 import org.opendaylight.mdsal.binding.api.ReadWriteTransaction;
22 import org.opendaylight.mdsal.binding.api.WriteTransaction;
25 * Managed transaction factories provide managed transactions, <em>i.e.</em> transactions which are automatically
26 * submitted or cancelled (write) or closed (read).
28 public interface ManagedTransactionFactory {
30 * Invokes a function with a <b>NEW</b> {@link TypedReadTransaction}, and ensures that that transaction is closed.
31 * Thus when this method returns, that transaction is guaranteed to have been closed, and will never "leak" and
34 * <p>The function must not itself attempt to close the transaction. (It can't directly, since
35 * {@link TypedReadTransaction} doesn't expose a {@code close()} method.)
37 * <p>The provided transaction is specific to the given logical datastore type and cannot be used for any
40 * @param datastoreType the {@link Datastore} type that will be accessed
41 * @param txFunction the {@link InterruptibleCheckedFunction} that needs a new read transaction
43 * @return the result of the function.
45 * @throws E if an error occurs.
46 * @throws InterruptedException if the transaction is interrupted.
48 <D extends Datastore, E extends Exception, R> R applyWithNewReadOnlyTransactionAndClose(Class<D> datastoreType,
49 InterruptibleCheckedFunction<TypedReadTransaction<D>, R, E> txFunction) throws E, InterruptedException;
52 * Invokes a function with a <b>NEW</b> {@link ReadWriteTransaction}, and then submits that transaction and
53 * returns the Future from that submission, or cancels it if an exception was thrown and returns a failed
54 * future with that exception. Thus when this method returns, that transaction is guaranteed to have
55 * been either submitted or cancelled, and will never "leak" and waste memory.
57 * <p>The function must not itself use
58 * {@link ReadWriteTransaction#cancel()}, or
59 * {@link ReadWriteTransaction#submit()} (it will throw an {@link UnsupportedOperationException}).
61 * <p>The provided transaction is specific to the given logical datastore type and cannot be used for any
64 * <p>This is an asynchronous API, like {@link DataBroker}'s own;
65 * when returning from this method, the operation of the Transaction may well still be ongoing in the background,
67 * calling code therefore <b>must</b> handle the returned future, e.g. by passing it onwards (return),
68 * or by itself adding callback listeners to it using {@link Futures}' methods, or by transforming it into a
69 * {@link CompletionStage} using {@link ListenableFutures#toCompletionStage(ListenableFuture)} and chaining on
70 * that, or at the very least simply by using
71 * {@link ListenableFutures#addErrorLogging(ListenableFuture, org.slf4j.Logger, String)}
72 * (but better NOT by using the blocking {@link Future#get()} on it).
74 * @param datastoreType the {@link Datastore} type that will be accessed
75 * @param txFunction the {@link InterruptibleCheckedFunction} that needs a new read-write transaction
77 * @return the {@link ListenableFuture} returned by {@link ReadWriteTransaction#submit()},
78 * or a failed future with an application specific exception (not from submit())
81 <D extends Datastore, E extends Exception, R>
82 FluentFuture<R> applyWithNewReadWriteTransactionAndSubmit(Class<D> datastoreType,
83 InterruptibleCheckedFunction<TypedReadWriteTransaction<D>, R, E> txFunction);
86 * Invokes a function with a <b>NEW</b> {@link ReadTransaction}, and ensures that that transaction is closed.
87 * Thus when this method returns, that transaction is guaranteed to have been closed, and will never "leak" and
90 * <p>The function must not itself attempt to close the transaction. (It can't directly, since
91 * {@link ReadTransaction} doesn't expose a {@code close()} method.)
93 * <p>The provided transaction is specific to the given logical datastore type and cannot be used for any
96 * @param datastoreType the {@link Datastore} type that will be accessed
97 * @param txConsumer the {@link InterruptibleCheckedFunction} that needs a new read transaction
99 * @throws E if an error occurs.
100 * @throws InterruptedException if the transaction is interrupted.
102 <D extends Datastore, E extends Exception> void callWithNewReadOnlyTransactionAndClose(Class<D> datastoreType,
103 InterruptibleCheckedConsumer<TypedReadTransaction<D>, E> txConsumer) throws E, InterruptedException;
106 * Invokes a consumer with a <b>NEW</b> {@link ReadWriteTransaction}, and then submits that transaction and
107 * returns the Future from that submission, or cancels it if an exception was thrown and returns a failed
108 * future with that exception. Thus when this method returns, that transaction is guaranteed to have
109 * been either submitted or cancelled, and will never "leak" and waste memory.
111 * <p>The consumer should not (cannot) itself use
112 * {@link ReadWriteTransaction#cancel()}, or
113 * {@link ReadWriteTransaction#submit()} (it will throw an {@link UnsupportedOperationException}).
115 * <p>The provided transaction is specific to the given logical datastore type and cannot be used for any
118 * <p>This is an asynchronous API, like {@link DataBroker}'s own;
119 * when returning from this method, the operation of the Transaction may well still be ongoing in the background,
121 * calling code therefore <b>must</b> handle the returned future, e.g. by passing it onwards (return),
122 * or by itself adding callback listeners to it using {@link Futures}' methods, or by transforming it into a
123 * {@link CompletionStage} using {@link ListenableFutures#toCompletionStage(ListenableFuture)} and chaining on
124 * that, or at the very least simply by using
125 * {@link ListenableFutures#addErrorLogging(ListenableFuture, org.slf4j.Logger, String)}
126 * (but better NOT by using the blocking {@link Future#get()} on it).
128 * @param datastoreType the {@link Datastore} type that will be accessed
129 * @param txConsumer the {@link InterruptibleCheckedConsumer} that needs a new read-write transaction
130 * @return the {@link ListenableFuture} returned by {@link ReadWriteTransaction#submit()},
131 * or a failed future with an application specific exception (not from submit())
134 <D extends Datastore, E extends Exception>
135 FluentFuture<Void> callWithNewReadWriteTransactionAndSubmit(Class<D> datastoreType,
136 InterruptibleCheckedConsumer<TypedReadWriteTransaction<D>, E> txConsumer);
139 * Invokes a consumer with a <b>NEW</b> {@link WriteTransaction}, and then submits that transaction and
140 * returns the Future from that submission, or cancels it if an exception was thrown and returns a failed
141 * future with that exception. Thus when this method returns, that transaction is guaranteed to have
142 * been either submitted or cancelled, and will never "leak" and waste memory.
144 * <p>The consumer should not (cannot) itself use
145 * {@link WriteTransaction#cancel()}, or
146 * {@link WriteTransaction#submit()} (it will throw an {@link UnsupportedOperationException}).
148 * <p>The provided transaction is specific to the given logical datastore type and cannot be used for any
151 * <p>This is an asynchronous API, like {@link DataBroker}'s own;
152 * when returning from this method, the operation of the Transaction may well still be ongoing in the background,
154 * calling code therefore <b>must</b> handle the returned future, e.g. by passing it onwards (return),
155 * or by itself adding callback listeners to it using {@link Futures}' methods, or by transforming it into a
156 * {@link CompletionStage} using {@link ListenableFutures#toCompletionStage(ListenableFuture)} and chaining on
157 * that, or at the very least simply by using
158 * {@link ListenableFutures#addErrorLogging(ListenableFuture, org.slf4j.Logger, String)}
159 * (but better NOT by using the blocking {@link Future#get()} on it).
161 * @param datastoreType the {@link Datastore} type that will be accessed
162 * @param txConsumer the {@link InterruptibleCheckedConsumer} that needs a new write only transaction
163 * @return the {@link ListenableFuture} returned by {@link WriteTransaction#submit()},
164 * or a failed future with an application specific exception (not from submit())
167 <D extends Datastore, E extends Exception>
168 FluentFuture<Void> callWithNewWriteOnlyTransactionAndSubmit(Class<D> datastoreType,
169 InterruptibleCheckedConsumer<TypedWriteTransaction<D>, E> txConsumer);