2 * Copyright © 2017 Orange, Inc. and others. All rights reserved.
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
9 package org.opendaylight.transportpce.common.device;
11 import java.util.Optional;
12 import java.util.concurrent.Future;
13 import java.util.concurrent.TimeUnit;
15 import org.opendaylight.mdsal.binding.api.MountPoint;
16 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
17 import org.opendaylight.yangtools.yang.binding.DataObject;
18 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
22 * Device transaction manager manages access to netconf devices. Only one transaction can be opened per device so
23 * it IS IMPORTANT TO CLOSE TRANSACTION as soon as transactions is not needed.
27 * Most important method is {@link DeviceTransactionManager#getDeviceTransaction(String)}. This method let's you
28 * obtain {@link DeviceTransaction} on the device. {@link DeviceTransaction} provices methods to read/write data
34 * {@link DeviceTransactionManager#getDataFromDevice(String, LogicalDatastoreType, InstanceIdentifier, long, TimeUnit)}
35 * is 'shortcut' to get data from device. It creates {@link DeviceTransaction}, gets data via it and then closes
40 * Two timeouts are built in process to prevent locking device forever:
44 * First is from creation of {@link DeviceTransaction} to calling method to close it (commit or cancel). When using
45 * {@link DeviceTransactionManager#getDeviceTransaction(String)} method then default timeout will be used. If there
46 * is need to specify this timeout manually use
47 * {@link DeviceTransactionManager#getDeviceTransaction(String, long, TimeUnit)} method. So if programmer will
48 * forgot to close transaction or it will take too much time transaction will be cancelled automatically and device
53 * Second timeout is from calling {@link DeviceTransaction#commit(long, TimeUnit)} until commit is completed on
54 * device. Timeout can be specified directly using commit method. So in case commit will freeze somewhere on device
55 * or it will take too much time device will be unlocked.
60 * If there is only need to read from device
61 * {@link DeviceTransactionManager#getDataFromDevice(String, LogicalDatastoreType, InstanceIdentifier, long, TimeUnit)}
62 * method can be used. It will automatically take care of {@link DeviceTransaction} and it will return data.
63 * This method <b>SHOULD NOT BE USED TOGETHER WITH DEVICE TRANSACTION ON THE SAME DEVICE IN THE SAME TIME</b>.
64 * In case that {@link DeviceTransaction} is created on device and before committing it
65 * {@link DeviceTransactionManager#getDataFromDevice(String, LogicalDatastoreType, InstanceIdentifier, long, TimeUnit)}
66 * method is called then get method will wait (will be blocking current thread) until device will be unlocked.
67 * However device is locked by transaction previously created. So this will result in blocking current thread until
68 * timeout for commit transaction will run out and cancel transaction. This can lead to incorrect execution of code.
72 * Bellow is simple example how to get {@link DeviceTransaction}, put some data to it and then commit it.
76 * // get device transaction future from device transaction manager
77 * Future<Optional<DeviceTransaction>> deviceTxFuture = deviceTransactionManager.getDeviceTransaction(deviceId);
78 * DeviceTransaction deviceTx;
80 * // wait until device transaction is available
81 * Optional<DeviceTransaction> deviceTxOpt = deviceTxFuture.get();
83 * // check if device transaction is present
84 * if (deviceTxOpt.isPresent()) {
85 * deviceTx = deviceTxOpt.get();
87 * throw new IllegalStateException("Device transaction for device " + deviceId + " was not found!");
89 * } catch (InterruptedException | ExecutionException e) {
90 * throw new IllegalStateException("Unable to obtain device transaction for device " + deviceId + "!", e);
93 * // do some operations with transaction
94 * deviceTx.put(LogicalDatastoreType.CONFIGURATION, someInstanceIdentifier, someData);
95 * deviceTx.delete(LogicalDatastoreType.CONFIGURATION, someOtherInstanceIdentifier, someOtherData);
97 * // commit transaction with 5 seconds timeout
98 * FluentFuture<? extends @NonNull CommitInfo> commit = deviceTx.commit(5, TimeUnit.SECONDS);
100 * // wait until transaction is committed
102 * } catch (InterruptedException | ExecutionException e) {
103 * throw new IllegalStateException("Failed to post data to device " + deviceId + "!", e);
108 public interface DeviceTransactionManager {
111 * Gets Future containing {@link DeviceTransaction}. Since only one transaction can be opened per device future will
112 * return transaction when all previously committed transaction on device are closed. This method will use default
113 * timeout for commit transaction.
115 * @param deviceId device identifier on which will be transaction created.
116 * @return Future returning Optional of DeviceTransaction. Optional will be empty if device with specified ID
117 * does not exists or transaction will fail to obtain.
119 Future<Optional<DeviceTransaction>> getDeviceTransaction(String deviceId);
122 * Works same as {@link DeviceTransactionManager#getDeviceTransaction(String)} but with option to set custom timeout.
124 * @param deviceId device id on which will be transaction created.
125 * @param timeoutToSubmit timeout will start running when transaction is created. If transaction will not be
126 * closed (committed or cancelled) when times runs out it will be canceled (so device will
128 * @param timeUnit time units for timeout.
129 * @return Future returning Optional of DeviceTransaction. Optional will be empty if device with specified ID
130 * does not exists or transaction will fail to obtain.
132 Future<Optional<DeviceTransaction>> getDeviceTransaction(String deviceId, long timeoutToSubmit, TimeUnit timeUnit);
134 // TODO make private in impl
136 Optional<MountPoint> getDeviceMountPoint(String deviceId);
139 * Returns data from device from specified path. Creates new device transaction, gets data via it and closes
142 * This method is blocking - it's waiting until it receives {@link DeviceTransaction} and then the data from device.
144 * @param deviceId Device identifier from which will be data read.
145 * @param logicalDatastoreType Datastore type.
146 * @param path Path to data in device's datastore.
147 * @param timeout Timeout to automatically close transaction AND to get data from device (sets both timeouts to
149 * @param timeUnit Time unit of timeout.
150 * @param <T> Type of data to be returned.
151 * @return Optional of data obtained from device. If device does not contain data or device does not exists then
152 * empty Optional will be returned.
154 <T extends DataObject> Optional<T> getDataFromDevice(String deviceId, LogicalDatastoreType logicalDatastoreType,
155 InstanceIdentifier<T> path, long timeout, TimeUnit timeUnit);
158 * Checks if device with specified ID is mounted.
160 * @param deviceId Identifier of device to check.
161 * @return True if device is mounted.
163 boolean isDeviceMounted(String deviceId);