use of org.opendaylight.mdsal.common.api.CommitInfo in project netvirt by opendaylight.
the class ElanL2GatewayUtils method removeRemoteUcastMacsFromExternalDevice.
/**
* Removes the given MAC Addresses from the specified External Device.
*
* @param deviceNodeId
* the device node id
* @param macAddresses
* the mac addresses
* @return the listenable future
*/
private FluentFuture<? extends @NonNull CommitInfo> removeRemoteUcastMacsFromExternalDevice(String deviceNodeId, String logicalSwitchName, List<PhysAddress> macAddresses) {
NodeId nodeId = new NodeId(deviceNodeId);
// TODO (eperefr)
List<MacAddress> lstMac = macAddresses.stream().filter(Objects::nonNull).map(physAddress -> new MacAddress(physAddress.getValue().toLowerCase(Locale.getDefault()))).collect(Collectors.toList());
return HwvtepUtils.deleteRemoteUcastMacs(broker, nodeId, logicalSwitchName, lstMac);
}
use of org.opendaylight.mdsal.common.api.CommitInfo in project controller by opendaylight.
the class ConcurrentDOMDataBrokerTest method testSuccessfulSubmit.
private void testSuccessfulSubmit(final boolean doAsync) throws InterruptedException {
final CountDownLatch asyncCanCommitContinue = new CountDownLatch(1);
Answer<ListenableFuture<Boolean>> asyncCanCommit = invocation -> {
final SettableFuture<Boolean> future = SettableFuture.create();
if (doAsync) {
new Thread(() -> {
Uninterruptibles.awaitUninterruptibly(asyncCanCommitContinue, 10, TimeUnit.SECONDS);
future.set(Boolean.TRUE);
}).start();
} else {
future.set(Boolean.TRUE);
}
return future;
};
doAnswer(asyncCanCommit).when(mockCohort1).canCommit();
doReturn(immediateNullFluentFuture()).when(mockCohort1).preCommit();
doReturn(immediateNullFluentFuture()).when(mockCohort1).commit();
doReturn(immediateTrueFluentFuture()).when(mockCohort2).canCommit();
doReturn(immediateNullFluentFuture()).when(mockCohort2).preCommit();
doReturn(immediateNullFluentFuture()).when(mockCohort2).commit();
ListenableFuture<? extends CommitInfo> future = coordinator.commit(transaction, Arrays.asList(mockCohort1, mockCohort2));
final CountDownLatch doneLatch = new CountDownLatch(1);
final AtomicReference<Throwable> caughtEx = new AtomicReference<>();
Futures.addCallback(future, new FutureCallback<CommitInfo>() {
@Override
public void onSuccess(final CommitInfo result) {
doneLatch.countDown();
}
@Override
public void onFailure(final Throwable failure) {
caughtEx.set(failure);
doneLatch.countDown();
}
}, MoreExecutors.directExecutor());
asyncCanCommitContinue.countDown();
assertTrue("Submit complete", doneLatch.await(5, TimeUnit.SECONDS));
if (caughtEx.get() != null) {
Throwables.throwIfUnchecked(caughtEx.get());
throw new RuntimeException(caughtEx.get());
}
assertEquals("Task count", doAsync ? 1 : 0, futureExecutor.getTaskCount());
InOrder inOrder = inOrder(mockCohort1, mockCohort2);
inOrder.verify(mockCohort1).canCommit();
inOrder.verify(mockCohort2).canCommit();
inOrder.verify(mockCohort1).preCommit();
inOrder.verify(mockCohort2).preCommit();
inOrder.verify(mockCohort1).commit();
inOrder.verify(mockCohort2).commit();
}
use of org.opendaylight.mdsal.common.api.CommitInfo in project controller by opendaylight.
the class OpendaylightToaster method setToasterStatusUp.
private void setToasterStatusUp(final Function<Boolean, MakeToastOutput> resultCallback) {
WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
tx.put(OPERATIONAL, TOASTER_IID, buildToaster(ToasterStatus.Up));
Futures.addCallback(tx.commit(), new FutureCallback<CommitInfo>() {
@Override
public void onSuccess(final CommitInfo result) {
LOG.info("Successfully set ToasterStatus to Up");
notifyCallback(true);
}
@Override
public void onFailure(final Throwable failure) {
// We shouldn't get an OptimisticLockFailedException (or any ex) as no
// other component should be updating the operational state.
LOG.error("Failed to update toaster status", failure);
notifyCallback(false);
}
void notifyCallback(final boolean result) {
if (resultCallback != null) {
resultCallback.apply(result);
}
}
}, MoreExecutors.directExecutor());
}
use of org.opendaylight.mdsal.common.api.CommitInfo in project controller by opendaylight.
the class OpendaylightToaster method checkStatusAndMakeToast.
private void checkStatusAndMakeToast(final MakeToastInput input, final SettableFuture<RpcResult<MakeToastOutput>> futureResult, final int tries) {
// Read the ToasterStatus and, if currently Up, try to write the status to Down.
// If that succeeds, then we essentially have an exclusive lock and can proceed
// to make toast.
final ReadWriteTransaction tx = dataBroker.newReadWriteTransaction();
FluentFuture<Optional<Toaster>> readFuture = tx.read(OPERATIONAL, TOASTER_IID);
final ListenableFuture<? extends CommitInfo> commitFuture = Futures.transformAsync(readFuture, toasterData -> {
ToasterStatus toasterStatus = ToasterStatus.Up;
if (toasterData.isPresent()) {
toasterStatus = toasterData.get().getToasterStatus();
}
LOG.debug("Read toaster status: {}", toasterStatus);
if (toasterStatus == ToasterStatus.Up) {
if (outOfBread()) {
LOG.debug("Toaster is out of bread");
tx.cancel();
return Futures.immediateFailedFuture(new TransactionCommitFailedException("", makeToasterOutOfBreadError()));
}
LOG.debug("Setting Toaster status to Down");
// We're not currently making toast - try to update the status to Down
// to indicate we're going to make toast. This acts as a lock to prevent
// concurrent toasting.
tx.put(OPERATIONAL, TOASTER_IID, buildToaster(ToasterStatus.Down));
return tx.commit();
}
LOG.debug("Oops - already making toast!");
// Return an error since we are already making toast. This will get
// propagated to the commitFuture below which will interpret the null
// TransactionStatus in the RpcResult as an error condition.
tx.cancel();
return Futures.immediateFailedFuture(new TransactionCommitFailedException("", makeToasterInUseError()));
}, MoreExecutors.directExecutor());
Futures.addCallback(commitFuture, new FutureCallback<CommitInfo>() {
@Override
public void onSuccess(final CommitInfo result) {
// OK to make toast
currentMakeToastTask.set(executor.submit(new MakeToastTask(input, futureResult)));
}
@Override
public void onFailure(final Throwable ex) {
if (ex instanceof OptimisticLockFailedException) {
if (tries - 1 > 0) {
LOG.debug("Got OptimisticLockFailedException - trying again");
checkStatusAndMakeToast(input, futureResult, tries - 1);
} else {
futureResult.set(RpcResultBuilder.<MakeToastOutput>failed().withError(ErrorType.APPLICATION, ex.getMessage()).build());
}
} else if (ex instanceof TransactionCommitFailedException) {
LOG.debug("Failed to commit Toaster status", ex);
// Probably already making toast.
futureResult.set(RpcResultBuilder.<MakeToastOutput>failed().withRpcErrors(((TransactionCommitFailedException) ex).getErrorList()).build());
} else {
LOG.debug("Unexpected error committing Toaster status", ex);
futureResult.set(RpcResultBuilder.<MakeToastOutput>failed().withError(ErrorType.APPLICATION, "Unexpected error committing Toaster status", ex).build());
}
}
}, MoreExecutors.directExecutor());
}
use of org.opendaylight.mdsal.common.api.CommitInfo in project controller by opendaylight.
the class TxchainDomWrite method executeList.
@Override
public void executeList() {
final LogicalDatastoreType dsType = getDataStoreType();
final YangInstanceIdentifier pid = YangInstanceIdentifier.builder().node(TestExec.QNAME).node(OuterList.QNAME).build();
final DOMTransactionChain chain = domDataBroker.createMergingTransactionChain(this);
DOMDataTreeWriteTransaction tx = chain.newWriteOnlyTransaction();
int txSubmitted = 0;
int writeCnt = 0;
for (MapEntryNode element : this.list) {
YangInstanceIdentifier yid = pid.node(NodeIdentifierWithPredicates.of(OuterList.QNAME, element.getIdentifier().asMap()));
if (oper == StartTestInput.Operation.PUT) {
tx.put(dsType, yid, element);
} else {
tx.merge(dsType, yid, element);
}
writeCnt++;
// Start performing the operation; submit the transaction at every n-th operation
if (writeCnt == writesPerTx) {
txSubmitted++;
tx.commit().addCallback(new FutureCallback<CommitInfo>() {
@Override
public void onSuccess(final CommitInfo result) {
txOk++;
}
@Override
public void onFailure(final Throwable cause) {
LOG.error("Transaction failed", cause);
txError++;
}
}, MoreExecutors.directExecutor());
tx = chain.newWriteOnlyTransaction();
writeCnt = 0;
}
}
try {
txSubmitted++;
tx.commit().get();
txOk++;
} catch (final InterruptedException | ExecutionException e) {
LOG.error("Transaction failed", e);
txError++;
}
try {
chain.close();
} catch (final IllegalStateException e) {
LOG.error("Transaction close failed,", e);
}
LOG.debug("Transactions: submitted {}, completed {}", txSubmitted, txOk + txError);
}
Aggregations