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