import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.SettableFuture;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
-import javax.annotation.Nullable;
+import javax.annotation.Nonnull;
import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
protected final List<ListenableFuture<DOMRpcResult>> resultsFutures;
private final List<TxListener> listeners = new CopyOnWriteArrayList<>();
// Allow commit to be called only once
- protected boolean finished = false;
+ protected volatile boolean finished = false;
public AbstractWriteTx(final NetconfBaseOps netOps, final RemoteDeviceId id, final boolean rollbackSupport) {
this.netOps = netOps;
editStructure, Optional.of(ModifyAction.NONE), "delete");
}
- @Override
- public final ListenableFuture<RpcResult<TransactionStatus>> commit() {
+ protected final ListenableFuture<RpcResult<Void>> commitConfiguration() {
listeners.forEach(listener -> listener.onTransactionSubmitted(this));
checkNotFinished();
finished = true;
- final ListenableFuture<RpcResult<TransactionStatus>> result = performCommit();
- Futures.addCallback(result, new FutureCallback<RpcResult<TransactionStatus>>() {
+ final ListenableFuture<RpcResult<Void>> result = performCommit();
+ Futures.addCallback(result, new FutureCallback<RpcResult<Void>>() {
@Override
- public void onSuccess(@Nullable final RpcResult<TransactionStatus> result) {
- if (result != null && result.isSuccessful()) {
+ public void onSuccess(@Nonnull final RpcResult<Void> rpcResult) {
+ if (rpcResult.isSuccessful()) {
listeners.forEach(txListener -> txListener.onTransactionSuccessful(AbstractWriteTx.this));
} else {
final TransactionCommitFailedException cause =
new TransactionCommitFailedException("Transaction failed",
- result.getErrors().toArray(new RpcError[result.getErrors().size()]));
+ rpcResult.getErrors().toArray(new RpcError[rpcResult.getErrors().size()]));
listeners.forEach(listener -> listener.onTransactionFailed(AbstractWriteTx.this, cause));
}
}
public void onFailure(final Throwable throwable) {
listeners.forEach(listener -> listener.onTransactionFailed(AbstractWriteTx.this, throwable));
}
- });
+ }, MoreExecutors.directExecutor());
return result;
}
- protected abstract ListenableFuture<RpcResult<TransactionStatus>> performCommit();
+ protected abstract ListenableFuture<RpcResult<Void>> performCommit();
private void checkEditable(final LogicalDatastoreType store) {
checkNotFinished();
DataContainerChild<?, ?> editStructure,
Optional<ModifyAction> defaultOperation, String operation);
- protected ListenableFuture<RpcResult<TransactionStatus>> resultsToTxStatus() {
- final SettableFuture<RpcResult<TransactionStatus>> transformed = SettableFuture.create();
+ protected ListenableFuture<RpcResult<Void>> resultsToTxStatus() {
+ final SettableFuture<RpcResult<Void>> transformed = SettableFuture.create();
Futures.addCallback(Futures.allAsList(resultsFutures), new FutureCallback<List<DOMRpcResult>>() {
@Override
- public void onSuccess(final List<DOMRpcResult> domRpcResults) {
+ public void onSuccess(@Nonnull final List<DOMRpcResult> domRpcResults) {
domRpcResults.forEach(domRpcResult -> {
if (!domRpcResult.getErrors().isEmpty() && !transformed.isDone()) {
final NetconfDocumentedException exception =
});
if (!transformed.isDone()) {
- transformed.set(RpcResultBuilder.success(TransactionStatus.COMMITED).build());
+ transformed.set(RpcResultBuilder.<Void>success().build());
}
}
DocumentedException.ErrorSeverity.ERROR);
transformed.setException(exception);
}
- });
+ }, MoreExecutors.directExecutor());
return transformed;
}