use of org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.locks.Lock in project controller by opendaylight.
the class WriteTransactionsHandler method start.
public static ListenableFuture<RpcResult<WriteTransactionsOutput>> start(final DOMDataBroker domDataBroker, final WriteTransactionsInput input) {
LOG.debug("Starting write-transactions.");
final String id = input.getId();
final MapEntryNode entry = ImmutableNodes.mapEntryBuilder(ID_INT, ID, id).withChild(ImmutableNodes.mapNodeBuilder(ITEM).build()).build();
final YangInstanceIdentifier idListItem = ID_INT_YID.node(entry.getIdentifier());
final ContainerNode containerNode = ImmutableContainerNodeBuilder.create().withNodeIdentifier(new NodeIdentifier(ID_INTS)).withChild(ImmutableNodes.mapNodeBuilder(ID_INT).build()).build();
DOMDataWriteTransaction tx = domDataBroker.newWriteOnlyTransaction();
// write only the top list
tx.merge(LogicalDatastoreType.CONFIGURATION, ID_INTS_YID, containerNode);
try {
tx.submit().checkedGet(INIT_TX_TIMEOUT_SECONDS, TimeUnit.SECONDS);
} catch (final OptimisticLockFailedException e) {
// when multiple write-transactions are executed concurrently we need to ignore this.
// If we get optimistic lock here it means id-ints already exists and we can continue.
LOG.debug("Got an optimistic lock when writing initial top level list element.", e);
} catch (final TransactionCommitFailedException | TimeoutException e) {
LOG.warn("Unable to ensure IdInts list for id: {} exists.", id, e);
return Futures.immediateFuture(RpcResultBuilder.<WriteTransactionsOutput>failed().withError(RpcError.ErrorType.APPLICATION, "Unexpected-exception", e).build());
}
tx = domDataBroker.newWriteOnlyTransaction();
tx.merge(LogicalDatastoreType.CONFIGURATION, idListItem, entry);
try {
tx.submit().get(INIT_TX_TIMEOUT_SECONDS, TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
LOG.warn("Unable to ensure IdInts list for id: {} exists.", id, e);
return Futures.immediateFuture(RpcResultBuilder.<WriteTransactionsOutput>failed().withError(RpcError.ErrorType.APPLICATION, "Unexpected-exception", e).build());
}
LOG.debug("Filling the item list with initial values.");
final CollectionNodeBuilder<MapEntryNode, MapNode> mapBuilder = ImmutableNodes.mapNodeBuilder(ITEM);
final YangInstanceIdentifier itemListId = idListItem.node(ITEM);
tx = domDataBroker.newWriteOnlyTransaction();
tx.put(LogicalDatastoreType.CONFIGURATION, itemListId, mapBuilder.build());
try {
tx.submit().get(INIT_TX_TIMEOUT_SECONDS, TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
LOG.warn("Unable to fill the initial item list.", e);
return Futures.immediateFuture(RpcResultBuilder.<WriteTransactionsOutput>failed().withError(RpcError.ErrorType.APPLICATION, "Unexpected-exception", e).build());
}
final WriteTransactionsHandler handler;
if (input.isChainedTransactions()) {
handler = new Chained(domDataBroker, idListItem, input);
} else {
handler = new Simple(domDataBroker, idListItem, input);
}
handler.doStart();
return handler.completionFuture;
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.locks.Lock in project genius by opendaylight.
the class LockManagerServiceImpl method readWriteLock.
/**
* Read and write the lock immediately if available. Returns true if
* successfully locked.
*/
private boolean readWriteLock(final InstanceIdentifier<Lock> lockInstanceIdentifier, final Lock lockData) throws InterruptedException, ExecutionException {
String lockName = lockData.getLockName();
synchronized (lockName.intern()) {
ReadWriteTransaction tx = broker.newReadWriteTransaction();
Optional<Lock> result = tx.read(LogicalDatastoreType.OPERATIONAL, lockInstanceIdentifier).get();
if (!result.isPresent()) {
LOG.debug("Writing lock lockData {}", lockData);
tx.put(LogicalDatastoreType.OPERATIONAL, lockInstanceIdentifier, lockData, true);
tx.submit().get();
return true;
} else {
String lockDataOwner = result.get().getLockOwner();
String currentOwner = lockData.getLockOwner();
if (currentOwner.equals(lockDataOwner)) {
return true;
}
}
tx.cancel();
return false;
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.locks.Lock in project genius by opendaylight.
the class LockManagerServiceImpl method tryLock.
@Override
public Future<RpcResult<Void>> tryLock(TryLockInput input) {
String lockName = input.getLockName();
String owner = lockManagerUtils.getUniqueID();
LOG.debug("Locking {}, owner {}", lockName, owner);
long waitTime = input.getTime() == null ? DEFAULT_WAIT_TIME_IN_MILLIS * DEFAULT_RETRY_COUNT : input.getTime();
TimeUnit timeUnit = input.getTimeUnit() == null ? TimeUnit.MILLISECONDS : lockManagerUtils.convertToTimeUnit(input.getTimeUnit());
waitTime = timeUnit.toMillis(waitTime);
long retryCount = waitTime / DEFAULT_WAIT_TIME_IN_MILLIS;
InstanceIdentifier<Lock> lockInstanceIdentifier = lockManagerUtils.getLockInstanceIdentifier(lockName);
Lock lockData = lockManagerUtils.buildLock(lockName, owner);
RpcResultBuilder<Void> lockRpcBuilder;
try {
if (getLock(lockInstanceIdentifier, lockData, retryCount)) {
lockRpcBuilder = RpcResultBuilder.success();
LOG.debug("Acquired lock {} by owner {}", lockName, owner);
} else {
lockRpcBuilder = RpcResultBuilder.failed();
LOG.error("Failed to get lock {} owner {} after {} retries", lockName, owner, retryCount);
}
} catch (InterruptedException e) {
lockRpcBuilder = RpcResultBuilder.failed();
LOG.error("Failed to get lock {} owner {}", lockName, owner, e);
}
return Futures.immediateFuture(lockRpcBuilder.build());
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.locks.Lock in project genius by opendaylight.
the class LockManagerTest method testTryLock.
@Test
public // tryLock() RPC will retry only specific number of times, and it will only return after that
void testTryLock() throws InterruptedException, ExecutionException, TimeoutException {
String uniqueId = lockManagerUtils.getBladeId() + ":2";
logCaptureRule.expectError("Failed to get lock testTryLock owner " + uniqueId + " after 3 retries");
TryLockInput lockInput = new TryLockInputBuilder().setLockName("testTryLock").setTime(3L).setTimeUnit(TimeUnits.Seconds).build();
assertVoidRpcSuccess(lockManager.tryLock(lockInput));
// The second acquireLock request will retry for 3 seconds
// and since the first lock is not unlocked, the request will fail.
lockInput = new TryLockInputBuilder().setLockName("testTryLock").setTime(3000L).setTimeUnit(TimeUnits.Milliseconds).build();
assertRpcErrorWithoutCausesOrMessages(lockManager.tryLock(lockInput));
// Try to unlock the key in a separate thread before retry expires, and see
// if lock gets acquired.
runUnlockTimerTask("testTryLock", 2000);
lockInput = new TryLockInputBuilder().setLockName("testTryLock").setTime(4000000L).setTimeUnit(TimeUnits.Microseconds).build();
assertVoidRpcSuccess(lockManager.tryLock(lockInput));
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.locks.Lock in project genius by opendaylight.
the class LockManagerTest method testAskTimeOutException.
@Test
public void testAskTimeOutException() throws InterruptedException, ExecutionException, TimeoutException {
String lockName = "testLock";
logCaptureRule.expectError("Unable to acquire lock for " + lockName + ", try 1", 1);
dbFailureSimulator.failButSubmitsAnyways();
LockInput lockInput = new LockInputBuilder().setLockName(lockName).build();
assertRpcErrorCause(lockManager.lock(lockInput), TransactionCommitFailedException.class, "caused by simulated AskTimeoutException");
}
Aggregations