Remove javadoc warnings
[transportpce.git] / common / src / main / java / org / opendaylight / transportpce / common / device / DeviceTransaction.java
1 /*
2  * Copyright © 2017 Orange, Inc. 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.transportpce.common.device;
10
11 import com.google.common.base.Optional;
12 import com.google.common.util.concurrent.CheckedFuture;
13 import com.google.common.util.concurrent.FutureCallback;
14 import com.google.common.util.concurrent.Futures;
15 import com.google.common.util.concurrent.ListenableFuture;
16
17 import java.util.concurrent.CountDownLatch;
18 import java.util.concurrent.Executors;
19 import java.util.concurrent.ScheduledExecutorService;
20 import java.util.concurrent.TimeUnit;
21 import java.util.concurrent.atomic.AtomicBoolean;
22 import javax.annotation.Nullable;
23
24 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
25 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
26 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
27 import org.opendaylight.yangtools.yang.binding.DataObject;
28 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 /**
33  * Represents read-write transaction on netconf device.
34  * This transaction can be obtained by {@link DeviceTransactionManager}.
35  *
36  * <p>
37  * WARNING: Only one transaction can be opened at the same time on device!
38  * It's important to close (cancel/submit) transaction when work is done with it
39  * (so others can access the device).
40  * </p>
41  */
42 public class DeviceTransaction {
43
44     private static final Logger LOG = LoggerFactory.getLogger(DeviceTransaction.class);
45
46     private final ReadWriteTransaction rwTx;
47     private final CountDownLatch deviceLock;
48     private final ScheduledExecutorService scheduledExecutorService;
49     private final AtomicBoolean wasSubmittedOrCancelled = new AtomicBoolean(false);
50
51     DeviceTransaction(ReadWriteTransaction rwTx, CountDownLatch deviceLock) {
52         this.rwTx = rwTx;
53         this.deviceLock = deviceLock;
54         this.scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
55         LOG.debug("Device transaction created. Lock: {}", deviceLock);
56     }
57
58     public <T extends DataObject> CheckedFuture<Optional<T>, ReadFailedException> read(LogicalDatastoreType store,
59             InstanceIdentifier<T> path) {
60         return rwTx.read(store, path);
61     }
62
63     public <T extends DataObject> void put(LogicalDatastoreType store, InstanceIdentifier<T> path, T data) {
64         rwTx.put(store, path, data);
65     }
66
67     public <T extends DataObject> void put(LogicalDatastoreType store, InstanceIdentifier<T> path, T data,
68             boolean createMissingParents) {
69         rwTx.put(store, path, data, createMissingParents);
70     }
71
72     public <T extends DataObject> void merge(LogicalDatastoreType store, InstanceIdentifier<T> path, T data) {
73         rwTx.merge(store, path, data);
74     }
75
76     public <T extends DataObject> void merge(LogicalDatastoreType store, InstanceIdentifier<T> path, T data,
77             boolean createMissingParents) {
78         rwTx.merge(store, path, data, createMissingParents);
79     }
80
81     public void delete(LogicalDatastoreType store, InstanceIdentifier<?> path) {
82         rwTx.delete(store, path);
83     }
84
85     /**
86      * Cancels transaction and unlocks it.
87      * @return true if cancel was successful.
88      */
89     public boolean cancel() {
90         if (wasSubmittedOrCancelled.get()) {
91             LOG.warn("Transaction was already submitted or canceled!");
92             return false;
93         }
94
95         LOG.debug("Transaction cancelled. Lock: {}", deviceLock);
96         wasSubmittedOrCancelled.set(true);
97         afterClose();
98         return rwTx.cancel();
99     }
100
101     /**
102      * Submits data changed in transaction to device with defined timeout to submit. If time from timeout runs out then
103      * submit will be interrupted and device will be unlocked.
104      *
105      * @param timeout a timeout
106      * @param timeUnit a time unit
107      * @return ListenableFuture which indicates when is submit completed.
108      */
109     public ListenableFuture<Void> submit(long timeout, TimeUnit timeUnit) {
110         if (wasSubmittedOrCancelled.get()) {
111             String msg = "Transaction was already submitted or canceled!";
112             LOG.error(msg);
113             return Futures.immediateFailedFuture(new IllegalStateException(msg));
114         }
115
116         LOG.debug("Transaction submitted. Lock: {}", deviceLock);
117         wasSubmittedOrCancelled.set(true);
118         ListenableFuture<Void> future =
119                 Futures.withTimeout(rwTx.submit(), timeout, timeUnit, scheduledExecutorService);
120
121         Futures.addCallback(future, new FutureCallback<Void>() {
122             @Override
123             public void onSuccess(@Nullable Void result) {
124                 LOG.debug("Transaction with lock {} successfully submitted.", deviceLock);
125                 afterClose();
126             }
127
128             @Override
129             public void onFailure(Throwable throwable) {
130                 LOG.error("Device transaction submit failed or submit took longer than {} {}!"
131                         + " Unlocking device.", timeout, timeUnit, throwable);
132                 afterClose();
133             }
134         }, scheduledExecutorService);
135         return future;
136     }
137
138     /**
139      * Returns state of transaction.
140      * @return true if transaction was closed; otherwise false
141      */
142     public AtomicBoolean wasSubmittedOrCancelled() {
143         return wasSubmittedOrCancelled;
144     }
145
146     private void afterClose() {
147         scheduledExecutorService.shutdown();
148         deviceLock.countDown();
149     }
150 }