4676b5a555a55d7f81ee7979d411f5ee0a1767ff
[genius.git] / mdsalutil / mdsalutil-api / src / main / java / org / opendaylight / genius / infra / ManagedTransactionFactory.java
1 /*
2  * Copyright © 2018 Red Hat, Inc. and others.
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.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;
23
24 /**
25  * Managed transaction factories provide managed transactions, <em>i.e.</em> transactions which are automatically
26  * submitted or cancelled (write) or closed (read).
27  */
28 public interface ManagedTransactionFactory {
29     /**
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
32      * waste memory.
33      *
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.)
36      *
37      * <p>The provided transaction is specific to the given logical datastore type and cannot be used for any
38      * other.
39      *
40      * @param datastoreType the {@link Datastore} type that will be accessed
41      * @param txFunction the {@link InterruptibleCheckedFunction} that needs a new read transaction
42      *
43      * @return the result of the function.
44      *
45      * @throws E if an error occurs.
46      * @throws InterruptedException if the transaction is interrupted.
47      */
48     <D extends Datastore, E extends Exception, R> R applyWithNewReadOnlyTransactionAndClose(Class<D> datastoreType,
49         InterruptibleCheckedFunction<TypedReadTransaction<D>, R, E> txFunction) throws E, InterruptedException;
50
51     /**
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.
56      *
57      * <p>The function must not itself use
58      * {@link ReadWriteTransaction#cancel()}, or
59      * {@link ReadWriteTransaction#submit()} (it will throw an {@link UnsupportedOperationException}).
60      *
61      * <p>The provided transaction is specific to the given logical datastore type and cannot be used for any
62      * other.
63      *
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,
66      * or pending;
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).
73      *
74      * @param datastoreType the {@link Datastore} type that will be accessed
75      * @param txFunction the {@link InterruptibleCheckedFunction} that needs a new read-write transaction
76      *
77      * @return the {@link ListenableFuture} returned by {@link ReadWriteTransaction#submit()},
78      *         or a failed future with an application specific exception (not from submit())
79      */
80     @CheckReturnValue
81     <D extends Datastore, E extends Exception, R>
82         FluentFuture<R> applyWithNewReadWriteTransactionAndSubmit(Class<D> datastoreType,
83             InterruptibleCheckedFunction<TypedReadWriteTransaction<D>, R, E> txFunction);
84
85     /**
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
88      * waste memory.
89      *
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.)
92      *
93      * <p>The provided transaction is specific to the given logical datastore type and cannot be used for any
94      * other.
95      *
96      * @param datastoreType the {@link Datastore} type that will be accessed
97      * @param txConsumer the {@link InterruptibleCheckedFunction} that needs a new read transaction
98      *
99      * @throws E if an error occurs.
100      * @throws InterruptedException if the transaction is interrupted.
101      */
102     <D extends Datastore, E extends Exception> void callWithNewReadOnlyTransactionAndClose(Class<D> datastoreType,
103         InterruptibleCheckedConsumer<TypedReadTransaction<D>, E> txConsumer) throws E, InterruptedException;
104
105     /**
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.
110      *
111      * <p>The consumer should not (cannot) itself use
112      * {@link ReadWriteTransaction#cancel()}, or
113      * {@link ReadWriteTransaction#submit()} (it will throw an {@link UnsupportedOperationException}).
114      *
115      * <p>The provided transaction is specific to the given logical datastore type and cannot be used for any
116      * other.
117      *
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,
120      * or pending;
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).
127      *
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())
132      */
133     @CheckReturnValue
134     <D extends Datastore, E extends Exception>
135         FluentFuture<Void> callWithNewReadWriteTransactionAndSubmit(Class<D> datastoreType,
136             InterruptibleCheckedConsumer<TypedReadWriteTransaction<D>, E> txConsumer);
137
138     /**
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.
143      *
144      * <p>The consumer should not (cannot) itself use
145      * {@link WriteTransaction#cancel()}, or
146      * {@link WriteTransaction#submit()} (it will throw an {@link UnsupportedOperationException}).
147      *
148      * <p>The provided transaction is specific to the given logical datastore type and cannot be used for any
149      * other.
150      *
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,
153      * or pending;
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).
160      *
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())
165      */
166     @CheckReturnValue
167     <D extends Datastore, E extends Exception>
168         FluentFuture<Void> callWithNewWriteOnlyTransactionAndSubmit(Class<D> datastoreType,
169             InterruptibleCheckedConsumer<TypedWriteTransaction<D>, E> txConsumer);
170 }