Update MRI projects for Aluminium
[ovsdb.git] / utils / mdsal-utils / src / main / java / org / opendaylight / ovsdb / utils / mdsal / utils / MdsalUtilsAsync.java
1 /*
2  * Copyright (c) 2016 Inocybe Technologies 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
9 package org.opendaylight.ovsdb.utils.mdsal.utils;
10
11 import com.google.common.util.concurrent.FluentFuture;
12 import com.google.common.util.concurrent.FutureCallback;
13 import com.google.common.util.concurrent.MoreExecutors;
14 import java.util.Optional;
15 import org.opendaylight.mdsal.binding.api.DataBroker;
16 import org.opendaylight.mdsal.binding.api.ReadTransaction;
17 import org.opendaylight.mdsal.binding.api.WriteTransaction;
18 import org.opendaylight.mdsal.common.api.CommitInfo;
19 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
20 import org.opendaylight.yangtools.yang.binding.DataObject;
21 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
24
25 public class MdsalUtilsAsync {
26
27     private static final Logger LOG = LoggerFactory.getLogger(MdsalUtilsAsync.class);
28     private final DataBroker databroker;
29
30     /**
31      * Class constructor setting the data broker.
32      *
33      * @param dataBroker the {@link DataBroker}
34      */
35     public MdsalUtilsAsync(final DataBroker dataBroker) {
36         this.databroker = dataBroker;
37     }
38
39     /**
40      * Executes delete as a non blocking transaction and returns the future.
41      *
42      * @param store
43      *            {@link LogicalDatastoreType} which should be modified
44      * @param path
45      *            {@link InstanceIdentifier} to read from
46      * @return The {@link FluentFuture} object to which you can assign a
47      *         callback
48      */
49     public <D extends DataObject> FluentFuture<? extends CommitInfo> delete(
50                                     final LogicalDatastoreType store,
51                                     final InstanceIdentifier<D> path)  {
52         final WriteTransaction transaction = databroker.newWriteOnlyTransaction();
53         transaction.delete(store, path);
54         return transaction.commit();
55     }
56
57     /**
58      * Executes delete as a non blocking transaction and assign a default callback.
59      *
60      * @param store
61      *            {@link LogicalDatastoreType} which should be modified
62      * @param path
63      *            {@link InstanceIdentifier} to read from
64      * @param operationDesc
65      *            A brief description of the operation to perform
66      */
67     public <D extends DataObject> void delete(
68                                     final LogicalDatastoreType store,
69                                     final InstanceIdentifier<D> path,
70                                     final String operationDesc)  {
71         assignDefaultCallback(delete(store, path), operationDesc);
72     }
73
74     /**
75      * Executes put as non blocking transaction and return the future.
76      *
77      * @param logicalDatastoreType
78      *            {@link LogicalDatastoreType} which should be modified
79      * @param path
80      *            {@link InstanceIdentifier} for path to read
81      * @param <D>
82      *            The data object type
83      * @return The {@link FluentFuture} object to which you can assign a
84      *         callback
85      */
86     public <D extends DataObject> FluentFuture<? extends CommitInfo> put(
87                                         final LogicalDatastoreType logicalDatastoreType,
88                                         final InstanceIdentifier<D> path,
89                                         final D data)  {
90         final WriteTransaction transaction = databroker.newWriteOnlyTransaction();
91         transaction.mergeParentStructurePut(logicalDatastoreType, path, data);
92         return transaction.commit();
93     }
94
95     /**
96      * Executes put as non blocking transaction and assign default callback.
97      *
98      * @param logicalDatastoreType
99      *            {@link LogicalDatastoreType} which should be modified
100      * @param path
101      *            {@link InstanceIdentifier} for path to read
102      * @param <D>
103      *            The data object type
104      * @param operationDesc
105      *            A brief description of the operation to perform
106      */
107     public <D extends DataObject> void put(
108                                         final LogicalDatastoreType logicalDatastoreType,
109                                         final InstanceIdentifier<D> path,
110                                         final D data,
111                                         final String operationDesc)  {
112         assignDefaultCallback(put(logicalDatastoreType, path, data), operationDesc);
113     }
114
115     /**
116      * Executes merge as non blocking transaction and return the future.
117      *
118      * @param logicalDatastoreType
119      *            {@link LogicalDatastoreType} which should be modified
120      * @param path
121      *            {@link InstanceIdentifier} for path to read
122      * @param <D>
123      *            The data object type
124      * @param withParent
125      *            Whether or not to create missing parent.
126      * @return The {@link FluentFuture} object to which you can assign a
127      *         callback
128      */
129     // FIXME: eliminate the boolean flag here to separate out the distinct code paths
130     public <D extends DataObject> FluentFuture<? extends CommitInfo> merge(
131                                         final LogicalDatastoreType logicalDatastoreType,
132                                         final InstanceIdentifier<D> path,
133                                         final D data,
134                                         final boolean withParent)  {
135         final WriteTransaction transaction = databroker.newWriteOnlyTransaction();
136         if (withParent) {
137             transaction.mergeParentStructureMerge(logicalDatastoreType, path, data);
138         } else {
139             transaction.merge(logicalDatastoreType, path, data);
140         }
141         return transaction.commit();
142     }
143
144     /**
145      * Executes merge as non blocking transaction and assign default callback.
146      *
147      * @param logicalDatastoreType
148      *            {@link LogicalDatastoreType} which should be modified
149      * @param path
150      *            {@link InstanceIdentifier} for path to read
151      * @param <D>
152      *            The data object type
153      * @param operationDesc
154      *            A brief description of the operation to perform
155      * @param withParent
156      *            Whether or not to create missing parent.
157      */
158     // FIXME: eliminate the boolean flag here to separate out the distinct code paths
159     public <D extends DataObject> void merge(
160                                         final LogicalDatastoreType logicalDatastoreType,
161                                         final InstanceIdentifier<D> path,
162                                         final D data,
163                                         final String operationDesc,
164                                         final boolean withParent)  {
165         assignDefaultCallback(merge(logicalDatastoreType, path, data, withParent), operationDesc);
166     }
167
168     /**
169      * Executes read as non blocking transaction and assign a default callback
170      * to close the transaction.
171      *
172      * @param store
173      *            {@link LogicalDatastoreType} to read
174      * @param path
175      *            {@link InstanceIdentifier} for path to read
176      * @param <D>
177      *            The data object type
178      * @return The {@link FluentFuture} object to which you can assign a
179      *         callback
180      */
181     public <D extends DataObject> FluentFuture<Optional<D>> read(
182                                         final LogicalDatastoreType store,
183                                         final InstanceIdentifier<D> path)  {
184         final ReadTransaction transaction = databroker.newReadOnlyTransaction();
185         final FluentFuture<Optional<D>> future = transaction.read(store, path);
186         final FutureCallback<Optional<D>> closeTransactionCallback = new FutureCallback<Optional<D>>() {
187             @Override
188             public void onSuccess(final Optional<D> result) {
189                 transaction.close();
190             }
191
192             @Override
193             public void onFailure(final Throwable ex) {
194                 transaction.close();
195             }
196         };
197         future.addCallback(closeTransactionCallback, MoreExecutors.directExecutor());
198         return future;
199     }
200
201     /**
202      * Assign a default callback to a {@link FluentFuture}. It will either log
203      * a message at DEBUG level if the transaction succeed, or will log at ERROR
204      * level and throw an {@link IllegalStateException} if the transaction
205      * failed.
206      *
207      * @param transactionFuture
208      *            The transaction to commit.
209      * @param operationDesc
210      *            A description of the transaction to commit.
211      */
212     void assignDefaultCallback(final FluentFuture<? extends CommitInfo> transactionFuture,
213             final String operationDesc) {
214         transactionFuture.addCallback(new FutureCallback<CommitInfo>() {
215             @Override
216             public void onSuccess(final CommitInfo result) {
217                 LOG.debug("Transaction({}) SUCCESSFUL", operationDesc);
218             }
219
220             @Override
221             public void onFailure(final Throwable ex) {
222                 LOG.error("Transaction({}) FAILED!", operationDesc, ex);
223                 throw new IllegalStateException("  Transaction(" + operationDesc + ") not committed correctly", ex);
224             }
225         }, MoreExecutors.directExecutor());
226     }
227 }