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;
14 import org.opendaylight.mdsal.binding.api.MountPoint;
15 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
16 import org.opendaylight.yangtools.yang.binding.DataObject;
17 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
21 * Device transaction manager manages access to netconf devices. Only one transaction can be opened per device so
22 * it IS IMPORTANT TO CLOSE TRANSACTION as soon as transactions is not needed.
26 * Most important method is {@link DeviceTransactionManager#getDeviceTransaction(String)}. This method let's you
27 * obtain {@link DeviceTransaction} on the device. {@link DeviceTransaction} provices methods to read/write data
33 * {@link DeviceTransactionManager#getDataFromDevice(String, LogicalDatastoreType, InstanceIdentifier, long, TimeUnit)}
34 * is 'shortcut' to get data from device. It creates {@link DeviceTransaction}, gets data via it and then closes
39 * Two timeouts are built in process to prevent locking device forever:
43 * First is from creation of {@link DeviceTransaction} to calling method to close it (commit or cancel). When using
44 * {@link DeviceTransactionManager#getDeviceTransaction(String)} method then default timeout will be used. If there
45 * is need to specify this timeout manually use
46 * {@link DeviceTransactionManager#getDeviceTransaction(String, long, TimeUnit)} method. So if programmer will
47 * forgot to close transaction or it will take too much time transaction will be cancelled automatically and device
52 * Second timeout is from calling {@link DeviceTransaction#commit(long, TimeUnit)} until commit is completed on
53 * device. Timeout can be specified directly using commit method. So in case commit will freeze somewhere on device
54 * or it will take too much time device will be unlocked.
59 * If there is only need to read from device
60 * {@link DeviceTransactionManager#getDataFromDevice(String, LogicalDatastoreType, InstanceIdentifier, long, TimeUnit)}
61 * method can be used. It will automatically take care of {@link DeviceTransaction} and it will return data.
62 * This method <b>SHOULD NOT BE USED TOGETHER WITH DEVICE TRANSACTION ON THE SAME DEVICE IN THE SAME TIME</b>.
63 * In case that {@link DeviceTransaction} is created on device and before committing it
64 * {@link DeviceTransactionManager#getDataFromDevice(String, LogicalDatastoreType, InstanceIdentifier, long, TimeUnit)}
65 * method is called then get method will wait (will be blocking current thread) until device will be unlocked.
66 * However device is locked by transaction previously created. So this will result in blocking current thread until
67 * timeout for commit transaction will run out and cancel transaction. This can lead to incorrect execution of code.
71 * Bellow is simple example how to get {@link DeviceTransaction}, put some data to it and then commit it.
75 * // get device transaction future from device transaction manager
76 * Future<Optional<DeviceTransaction>> deviceTxFuture = deviceTransactionManager.getDeviceTransaction(deviceId);
77 * DeviceTransaction deviceTx;
79 * // wait until device transaction is available
80 * Optional<DeviceTransaction> deviceTxOpt = deviceTxFuture.get();
82 * // check if device transaction is present
83 * if (deviceTxOpt.isPresent()) {
84 * deviceTx = deviceTxOpt.get();
86 * throw new IllegalStateException("Device transaction for device " + deviceId + " was not found!");
88 * } catch (InterruptedException | ExecutionException e) {
89 * throw new IllegalStateException("Unable to obtain device transaction for device " + deviceId + "!", e);
92 * // do some operations with transaction
93 * deviceTx.put(LogicalDatastoreType.CONFIGURATION, someInstanceIdentifier, someData);
94 * deviceTx.delete(LogicalDatastoreType.CONFIGURATION, someOtherInstanceIdentifier, someOtherData);
96 * // commit transaction with 5 seconds timeout
97 * FluentFuture<? extends @NonNull CommitInfo> commit = deviceTx.commit(5, TimeUnit.SECONDS);
99 * // wait until transaction is committed
101 * } catch (InterruptedException | ExecutionException e) {
102 * throw new IllegalStateException("Failed to post data to device " + deviceId + "!", e);
107 public interface DeviceTransactionManager {
110 * Gets Future containing {@link DeviceTransaction}. Since only one transaction can be opened per device future will
111 * return transaction when all previously committed transaction on device are closed. This method will use default
112 * timeout for commit transaction.
114 * @param deviceId device identifier on which will be transaction created.
115 * @return Future returning Optional of DeviceTransaction. Optional will be empty if device with specified ID
116 * does not exists or transaction will fail to obtain.
118 Future<Optional<DeviceTransaction>> getDeviceTransaction(String deviceId);
121 * Works same as {@link DeviceTransactionManager#getDeviceTransaction(String)} but with option to set custom timeout.
123 * @param deviceId device id on which will be transaction created.
124 * @param timeoutToSubmit timeout will start running when transaction is created. If transaction will not be
125 * closed (committed or cancelled) when times runs out it will be canceled (so device will
127 * @param timeUnit time units for timeout.
128 * @return Future returning Optional of DeviceTransaction. Optional will be empty if device with specified ID
129 * does not exists or transaction will fail to obtain.
131 Future<Optional<DeviceTransaction>> getDeviceTransaction(String deviceId, long timeoutToSubmit, TimeUnit timeUnit);
133 // TODO make private in impl
134 Optional<MountPoint> getDeviceMountPoint(String deviceId);
137 * Returns data from device from specified path. Creates new device transaction, gets data via it and closes
141 * 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);