/* * Copyright © 2017 Orange, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.transportpce.common.device; import java.util.Optional; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import org.opendaylight.controller.md.sal.binding.api.MountPoint; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; /** *

* Device transaction manager manages access to netconf devices. Only one transaction can be opened per device so * it IS IMPORTANT TO CLOSE TRANSACTION as soon as transactions is not needed. *

* *

* Most important method is {@link DeviceTransactionManager#getDeviceTransaction(String)}. This method let's you * obtain {@link DeviceTransaction} on the device. {@link DeviceTransaction} provices methods to read/write data * from/to device. *

* *

* Method * {@link DeviceTransactionManager#getDataFromDevice(String, LogicalDatastoreType, InstanceIdentifier, long, TimeUnit)} * is 'shortcut' to get data from device. It creates {@link DeviceTransaction}, gets data via it and then closes * the transaction. *

* *

* Two timeouts are built in process to prevent locking device forever: *

* * *

* If there is only need to read from device * {@link DeviceTransactionManager#getDataFromDevice(String, LogicalDatastoreType, InstanceIdentifier, long, TimeUnit)} * method can be used. It will automatically take care of {@link DeviceTransaction} and it will return data. * This method SHOULD NOT BE USED TOGETHER WITH DEVICE TRANSACTION ON THE SAME DEVICE IN THE SAME TIME. * In case that {@link DeviceTransaction} is created on device and before committing it * {@link DeviceTransactionManager#getDataFromDevice(String, LogicalDatastoreType, InstanceIdentifier, long, TimeUnit)} * method is called then get method will wait (will be blocking current thread) until device will be unlocked. * However device is locked by transaction previously created. So this will result in blocking current thread until * timeout for commit transaction will run out and cancel transaction. This can lead to incorrect execution of code. *

* *

* Bellow is simple example how to get {@link DeviceTransaction}, put some data to it and then commit it. *

*
 * {@code
 *     // get device transaction future from device transaction manager
 *     Future> deviceTxFuture = deviceTransactionManager.getDeviceTransaction(deviceId);
 *     DeviceTransaction deviceTx;
 *     try {
 *         // wait until device transaction is available
 *         Optional deviceTxOpt = deviceTxFuture.get();
 *
 *         // check if device transaction is present
 *         if (deviceTxOpt.isPresent()) {
 *             deviceTx = deviceTxOpt.get();
 *         } else {
 *             throw new IllegalStateException("Device transaction for device " + deviceId + " was not found!");
 *         }
 *     } catch (InterruptedException | ExecutionException e) {
 *         throw new IllegalStateException("Unable to obtain device transaction for device " + deviceId + "!", e);
 *     }
 *
 *     // do some operations with transaction
 *     deviceTx.put(LogicalDatastoreType.CONFIGURATION, someInstanceIdentifier, someData);
 *     deviceTx.delete(LogicalDatastoreType.CONFIGURATION, someOtherInstanceIdentifier, someOtherData);
 *
 *     // commit transaction with 5 seconds timeout
 *     FluentFuture commit = deviceTx.commit(5, TimeUnit.SECONDS);
 *     try {
 *         // wait until transaction is committed
 *         commit.get();
 *     } catch (InterruptedException | ExecutionException e) {
 *         throw new IllegalStateException("Failed to post data to device " + deviceId + "!", e);
 *     }
 * }
 * 
*/ public interface DeviceTransactionManager { /** * Gets Future containing {@link DeviceTransaction}. Since only one transaction can be opened per device future will * return transaction when all previously committed transaction on device are closed. This method will use default * timeout for commit transaction. * * @param deviceId device identifier on which will be transaction created. * @return Future returning Optional of DeviceTransaction. Optional will be empty if device with specified ID * does not exists or transaction will fail to obtain. */ Future> getDeviceTransaction(String deviceId); /** * Works same as {@link DeviceTransactionManager#getDeviceTransaction(String)} but with option to set custom timeout. * * @param deviceId device id on which will be transaction created. * @param timeoutToSubmit timeout will start running when transaction is created. If transaction will not be * closed (committed or cancelled) when times runs out it will be canceled (so device will * be unlocked). * @param timeUnit time units for timeout. * @return Future returning Optional of DeviceTransaction. Optional will be empty if device with specified ID * does not exists or transaction will fail to obtain. */ Future> getDeviceTransaction(String deviceId, long timeoutToSubmit, TimeUnit timeUnit); // TODO make private in impl @Deprecated Optional getDeviceMountPoint(String deviceId); /** * Returns data from device from specified path. Creates new device transaction, gets data via it and closes * transaction. * * This method is blocking - it's waiting until it receives {@link DeviceTransaction} and then the data from device. * * @param deviceId Device identifier from which will be data read. * @param logicalDatastoreType Datastore type. * @param path Path to data in device's datastore. * @param timeout Timeout to automatically close transaction AND to get data from device (sets both timeouts to * same value). * @param timeUnit Time unit of timeout. * @param Type of data to be returned. * @return Optional of data obtained from device. If device does not contain data or device does not exists then * empty Optional will be returned. */ Optional getDataFromDevice(String deviceId, LogicalDatastoreType logicalDatastoreType, InstanceIdentifier path, long timeout, TimeUnit timeUnit); /** * Checks if device with specified ID is mounted. * * @param deviceId Identifier of device to check. * @return True if device is mounted. */ boolean isDeviceMounted(String deviceId); }