Implement managed transactions
[mdsal.git] / binding / mdsal-binding-util / src / main / java / org / opendaylight / mdsal / binding / util / 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.mdsal.binding.util;
9
10 import com.google.common.util.concurrent.FluentFuture;
11 import com.google.common.util.concurrent.Futures;
12 import java.util.concurrent.CompletionStage;
13 import java.util.concurrent.Future;
14 import javax.annotation.CheckReturnValue;
15 import org.opendaylight.mdsal.binding.api.DataBroker;
16 import org.opendaylight.mdsal.binding.api.ReadTransaction;
17 import org.opendaylight.mdsal.binding.api.ReadWriteTransaction;
18 import org.opendaylight.mdsal.binding.api.WriteTransaction;
19
20 /**
21  * Managed transaction factories provide managed transactions, <em>i.e.</em> transactions which are automatically
22  * submitted or cancelled (write) or closed (read).
23  * <p>
24  * This is a common interface for broker- and chain-based transaction managers, and should not be used directly.
25  */
26 public interface ManagedTransactionFactory {
27     /**
28      * Invokes a function with a <b>NEW</b> {@link TypedReadTransaction}, and ensures that that transaction is closed.
29      * Thus when this method returns, that transaction is guaranteed to have been closed, and will never "leak" and
30      * waste memory.
31      *
32      * <p>The function must not itself attempt to close the transaction. (It can't directly, since
33      * {@link TypedReadTransaction} doesn't expose a {@code close()} method.)
34      *
35      * <p>The provided transaction is specific to the given logical datastore type and cannot be used for any
36      * other.
37      *
38      * @param datastoreType the {@link Datastore} type that will be accessed
39      * @param txFunction the {@link InterruptibleCheckedFunction} that needs a new read transaction
40      * @return the result of the function.
41      * @throws E if an error occurs.
42      * @throws InterruptedException if the function is interrupted (this is passed through from the provided function).
43      */
44     <D extends Datastore, E extends Exception, R> R applyInterruptiblyWithNewReadOnlyTransactionAndClose(
45         Class<D> datastoreType, InterruptibleCheckedFunction<TypedReadTransaction<D>, R, E> txFunction)
46         throws E, InterruptedException;
47
48     /**
49      * Invokes a function with a <b>NEW</b> {@link TypedReadTransaction}, and ensures that that transaction is closed.
50      * Thus when this method returns, that transaction is guaranteed to have been closed, and will never "leak" and
51      * waste memory.
52      *
53      * <p>The function must not itself attempt to close the transaction. (It can't directly, since
54      * {@link TypedReadTransaction} doesn't expose a {@code close()} method.)
55      *
56      * <p>The provided transaction is specific to the given logical datastore type and cannot be used for any
57      * other.
58      *
59      * @param datastoreType the {@link Datastore} type that will be accessed
60      * @param txFunction the {@link InterruptibleCheckedFunction} that needs a new read transaction
61      * @return the result of the function.
62      * @throws E if an error occurs.
63      */
64     <D extends Datastore, E extends Exception, R> R applyWithNewReadOnlyTransactionAndClose(Class<D> datastoreType,
65         CheckedFunction<TypedReadTransaction<D>, R, E> txFunction) throws E;
66
67     /**
68      * Invokes a function with a <b>NEW</b> {@link ReadWriteTransaction}, and then submits that transaction and
69      * returns the Future from that submission, or cancels it if an exception was thrown and returns a failed
70      * future with that exception. Thus when this method returns, that transaction is guaranteed to have
71      * been either submitted or cancelled, and will never "leak" and waste memory.
72      *
73      * <p>The function must not itself use
74      * {@link ReadWriteTransaction#cancel()}, or
75      * {@link ReadWriteTransaction#commit()} (it will throw an {@link UnsupportedOperationException}).
76      *
77      * <p>The provided transaction is specific to the given logical datastore type and cannot be used for any
78      * other.
79      *
80      * <p>This is an asynchronous API, like {@link DataBroker}'s own;
81      * when returning from this method, the operation of the Transaction may well still be ongoing in the background,
82      * or pending;
83      * calling code therefore <b>must</b> handle the returned future, e.g. by passing it onwards (return),
84      * or by itself adding callback listeners to it using {@link Futures}' methods, or by transforming it into a
85      * {@link CompletionStage}
86      * (but better NOT by using the blocking {@link Future#get()} on it).
87      *
88      * @param datastoreType the {@link Datastore} type that will be accessed
89      * @param txFunction the {@link InterruptibleCheckedFunction} that needs a new read-write transaction
90      * @return the {@link FluentFuture} returned by {@link ReadWriteTransaction#commit()}, or a failed future with an
91      * application specific exception (not from submit())
92      */
93     @CheckReturnValue
94     <D extends Datastore, E extends Exception, R>
95         FluentFuture<R> applyWithNewReadWriteTransactionAndSubmit(Class<D> datastoreType,
96             InterruptibleCheckedFunction<TypedReadWriteTransaction<D>, R, E> txFunction);
97
98     /**
99      * Invokes a function with a <b>NEW</b> {@link ReadTransaction}, and ensures that that transaction is closed.
100      * Thus when this method returns, that transaction is guaranteed to have been closed, and will never "leak" and
101      * waste memory.
102      *
103      * <p>The function must not itself attempt to close the transaction. (It can't directly, since
104      * {@link ReadTransaction} doesn't expose a {@code close()} method.)
105      *
106      * <p>The provided transaction is specific to the given logical datastore type and cannot be used for any
107      * other.
108      *
109      * @param datastoreType the {@link Datastore} type that will be accessed
110      * @param txConsumer the {@link InterruptibleCheckedFunction} that needs a new read transaction
111      * @throws E if an error occurs.
112      * @throws InterruptedException if the function is interrupted (this is passed through from the provided function).
113      */
114     <D extends Datastore, E extends Exception> void callInterruptiblyWithNewReadOnlyTransactionAndClose(
115         Class<D> datastoreType, InterruptibleCheckedConsumer<TypedReadTransaction<D>, E> txConsumer)
116         throws E, InterruptedException;
117
118     /**
119      * Invokes a function with a <b>NEW</b> {@link ReadTransaction}, and ensures that that transaction is closed.
120      * Thus when this method returns, that transaction is guaranteed to have been closed, and will never "leak" and
121      * waste memory.
122      *
123      * <p>The function must not itself attempt to close the transaction. (It can't directly, since
124      * {@link ReadTransaction} doesn't expose a {@code close()} method.)
125      *
126      * <p>The provided transaction is specific to the given logical datastore type and cannot be used for any
127      * other.
128      *
129      * @param datastoreType the {@link Datastore} type that will be accessed
130      * @param txConsumer the {@link InterruptibleCheckedFunction} that needs a new read transaction
131      * @throws E if an error occurs.
132      */
133     <D extends Datastore, E extends Exception> void callWithNewReadOnlyTransactionAndClose(Class<D> datastoreType,
134         CheckedConsumer<TypedReadTransaction<D>, E> txConsumer) throws E;
135
136     /**
137      * Invokes a consumer with a <b>NEW</b> {@link ReadWriteTransaction}, and then submits that transaction and
138      * returns the Future from that submission, or cancels it if an exception was thrown and returns a failed
139      * future with that exception. Thus when this method returns, that transaction is guaranteed to have
140      * been either submitted or cancelled, and will never "leak" and waste memory.
141      *
142      * <p>The consumer should not (cannot) itself use
143      * {@link ReadWriteTransaction#cancel()}, or
144      * {@link ReadWriteTransaction#commit()} (it will throw an {@link UnsupportedOperationException}).
145      *
146      * <p>The provided transaction is specific to the given logical datastore type and cannot be used for any
147      * other.
148      *
149      * <p>This is an asynchronous API, like {@link DataBroker}'s own;
150      * when returning from this method, the operation of the Transaction may well still be ongoing in the background,
151      * or pending;
152      * calling code therefore <b>must</b> handle the returned future, e.g. by passing it onwards (return),
153      * or by itself adding callback listeners to it using {@link Futures}' methods, or by transforming it into a
154      * {@link CompletionStage}
155      * (but better NOT by using the blocking {@link Future#get()} on it).
156      *
157      * @param datastoreType the {@link Datastore} type that will be accessed
158      * @param txConsumer the {@link InterruptibleCheckedConsumer} that needs a new read-write transaction
159      * @return the {@link FluentFuture} returned by {@link ReadWriteTransaction#commit()}, or a failed future with an
160      * application specific exception (not from submit())
161      */
162     @CheckReturnValue
163     <D extends Datastore, E extends Exception>
164         FluentFuture<? extends Object> callWithNewReadWriteTransactionAndSubmit(Class<D> datastoreType,
165             InterruptibleCheckedConsumer<TypedReadWriteTransaction<D>, E> txConsumer);
166
167     /**
168      * Invokes a consumer with a <b>NEW</b> {@link WriteTransaction}, and then submits that transaction and
169      * returns the Future from that submission, or cancels it if an exception was thrown and returns a failed
170      * future with that exception. Thus when this method returns, that transaction is guaranteed to have
171      * been either submitted or cancelled, and will never "leak" and waste memory.
172      *
173      * <p>The consumer should not (cannot) itself use
174      * {@link WriteTransaction#cancel()}, or
175      * {@link WriteTransaction#commit()} (it will throw an {@link UnsupportedOperationException}).
176      *
177      * <p>The provided transaction is specific to the given logical datastore type and cannot be used for any
178      * other.
179      *
180      * <p>This is an asynchronous API, like {@link DataBroker}'s own;
181      * when returning from this method, the operation of the Transaction may well still be ongoing in the background,
182      * or pending;
183      * calling code therefore <b>must</b> handle the returned future, e.g. by passing it onwards (return),
184      * or by itself adding callback listeners to it using {@link Futures}' methods, or by transforming it into a
185      * {@link CompletionStage}
186      * (but better NOT by using the blocking {@link Future#get()} on it).
187      *
188      * @param datastoreType the {@link Datastore} type that will be accessed
189      * @param txConsumer the {@link InterruptibleCheckedConsumer} that needs a new write only transaction
190      * @return the {@link FluentFuture} returned by {@link WriteTransaction#commit()}, or a failed future with an
191      * application specific exception (not from submit())
192      */
193     @CheckReturnValue
194     <D extends Datastore, E extends Exception>
195         FluentFuture<? extends Object> callWithNewWriteOnlyTransactionAndSubmit(Class<D> datastoreType,
196             InterruptibleCheckedConsumer<TypedWriteTransaction<D>, E> txConsumer);
197 }