import com.google.common.collect.ImmutableSet;
import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FluentFuture;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
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;
+import org.opendaylight.mdsal.common.api.CommitInfo;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
return delegate.submit();
}
+ @Override
+ public FluentFuture<? extends CommitInfo> commit() {
+ logOps();
+ return delegate.commit();
+ }
+
@Override
public Object getIdentifier() {
return delegate.getIdentifier();
import com.google.common.base.Optional;
import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FluentFuture;
import java.util.Objects;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.controller.md.sal.trace.closetracker.impl.CloseTracked;
import org.opendaylight.controller.md.sal.trace.closetracker.impl.CloseTrackedRegistry;
import org.opendaylight.controller.md.sal.trace.closetracker.impl.CloseTrackedTrait;
+import org.opendaylight.mdsal.common.api.CommitInfo;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
return super.submit();
}
+ @Override
+ public FluentFuture<? extends CommitInfo> commit() {
+ closeTracker.removeFromTrackedRegistry();
+ return super.commit();
+ }
+
@Override
public boolean cancel() {
closeTracker.removeFromTrackedRegistry();
package org.opendaylight.controller.md.sal.trace.dom.impl;
import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FluentFuture;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
import org.opendaylight.controller.md.sal.trace.closetracker.impl.CloseTracked;
import org.opendaylight.controller.md.sal.trace.closetracker.impl.CloseTrackedRegistry;
import org.opendaylight.controller.md.sal.trace.closetracker.impl.CloseTrackedTrait;
+import org.opendaylight.mdsal.common.api.CommitInfo;
class TracingWriteTransaction extends AbstractTracingWriteTransaction
implements CloseTracked<TracingWriteTransaction> {
return super.submit();
}
+ @Override
+ public FluentFuture<? extends CommitInfo> commit() {
+ closeTracker.removeFromTrackedRegistry();
+ return super.commit();
+ }
+
@Override
public boolean cancel() {
closeTracker.removeFromTrackedRegistry();
import com.google.common.base.Optional;
import com.google.common.collect.ForwardingObject;
import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FluentFuture;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.mdsal.common.api.CommitInfo;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
return delegate.submit();
}
+ @Override
+ public FluentFuture<? extends CommitInfo> commit() {
+ return delegate.commit();
+ }
+
@Override
public void delete(LogicalDatastoreType store, InstanceIdentifier<?> path) {
delegate.delete(store, path);
import com.google.common.collect.ForwardingObject;
import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FluentFuture;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.mdsal.common.api.CommitInfo;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
return delegate.submit();
}
+ @Override
+ public FluentFuture<? extends CommitInfo> commit() {
+ return delegate.commit();
+ }
+
@Override
public Object getIdentifier() {
return delegate.getIdentifier();
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FluentFuture;
import java.util.Map.Entry;
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;
+import org.opendaylight.mdsal.common.api.CommitInfo;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.Identifiable;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
getDelegate().delete(store, normalized);
}
- protected final CheckedFuture<Void,TransactionCommitFailedException> doSubmit() {
- return getDelegate().submit();
+ protected final FluentFuture<? extends CommitInfo> doCommit() {
+ return getDelegate().commit();
}
protected final boolean doCancel() {
package org.opendaylight.controller.md.sal.binding.impl;
import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FluentFuture;
import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.MoreExecutors;
import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
+import org.opendaylight.mdsal.common.api.CommitInfo;
import org.opendaylight.yangtools.concepts.Delegator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
return new BindingDOMReadWriteTransactionAdapter(delegateTx, codec) {
@Override
- public CheckedFuture<Void, TransactionCommitFailedException> submit() {
- return listenForFailure(this,super.submit());
+ public FluentFuture<? extends CommitInfo> commit() {
+ return listenForFailure(this, super.commit());
}
};
return new BindingDOMWriteTransactionAdapter<DOMDataWriteTransaction>(delegateTx, codec) {
@Override
- public CheckedFuture<Void,TransactionCommitFailedException> submit() {
- return listenForFailure(this,super.submit());
+ public FluentFuture<? extends CommitInfo> commit() {
+ return listenForFailure(this, super.commit());
}
};
}
- private CheckedFuture<Void, TransactionCommitFailedException> listenForFailure(
- final WriteTransaction tx, final CheckedFuture<Void, TransactionCommitFailedException> future) {
- Futures.addCallback(future, new FutureCallback<Void>() {
+ private FluentFuture<? extends CommitInfo> listenForFailure(
+ final WriteTransaction tx, final FluentFuture<? extends CommitInfo> future) {
+ future.addCallback(new FutureCallback<CommitInfo>() {
@Override
public void onFailure(final Throwable ex) {
failTransactionChain(tx,ex);
}
@Override
- public void onSuccess(final Void result) {
+ public void onSuccess(final CommitInfo result) {
// Intentionally NOOP
}
}, MoreExecutors.directExecutor());
package org.opendaylight.controller.md.sal.binding.impl;
import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FluentFuture;
+import com.google.common.util.concurrent.MoreExecutors;
import java.util.ArrayList;
import java.util.List;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException;
import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationOperation;
import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.controller.md.sal.dom.broker.impl.TransactionCommitFailedExceptionMapper;
+import org.opendaylight.mdsal.common.api.CommitInfo;
+import org.opendaylight.mdsal.common.api.MappingCheckedFuture;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
@Override
public CheckedFuture<Void,TransactionCommitFailedException> submit() {
- return doSubmit();
+ return MappingCheckedFuture.create(commit().transform(ignored -> null,
+ MoreExecutors.directExecutor()), TransactionCommitFailedExceptionMapper.COMMIT_ERROR_MAPPER);
+ }
+
+ @Override
+ public FluentFuture<? extends CommitInfo> commit() {
+ return doCommit();
}
@Override
import com.google.common.base.Optional;
import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FluentFuture;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.MoreExecutors;
import java.util.Collections;
import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
import org.opendaylight.controller.sal.binding.test.util.BindingBrokerTestFactory;
import org.opendaylight.controller.sal.binding.test.util.BindingTestContext;
+import org.opendaylight.mdsal.common.api.CommitInfo;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.of.migration.test.model.rev150210.List11SimpleAugment;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.of.migration.test.model.rev150210.TllComplexAugment;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.of.migration.test.model.rev150210.aug.grouping.List1;
throw new UnsupportedOperationException();
}
+ @Override
+ public FluentFuture<? extends CommitInfo> commit() {
+ throw new UnsupportedOperationException();
+ }
};
}
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-data-api</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.mdsal</groupId>
+ <artifactId>mdsal-common-api</artifactId>
+ </dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
package org.opendaylight.controller.md.sal.common.api.data;
import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FluentFuture;
import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.MoreExecutors;
+import javax.annotation.CheckReturnValue;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.mdsal.common.api.CommitInfo;
import org.opendaylight.yangtools.concepts.Path;
/**
*
* @throws IllegalStateException
* if the transaction is not new
+ * @deprecated Use {@link #commit()} instead.
*/
+ @Deprecated
CheckedFuture<Void,TransactionCommitFailedException> submit();
+
+ /**
+ * Submits this transaction to be asynchronously applied to update the logical data tree. The returned
+ * {@link FluentFuture} conveys the result of applying the data changes.
+ *
+ * <p>
+ * This call logically seals the transaction, which prevents the client from further changing the data tree using
+ * this transaction. Any subsequent calls to <code>put(LogicalDatastoreType, Path, Object)</code>,
+ * <code>merge(LogicalDatastoreType, Path, Object)</code>, <code>delete(LogicalDatastoreType, Path)</code> will fail
+ * with {@link IllegalStateException}. The transaction is marked as submitted and enqueued into the data store
+ * back-end for processing.
+ *
+ * <p>
+ * Whether or not the commit is successful is determined by versioning of the data tree and validation of registered
+ * commit participants if the transaction changes the data tree.
+ *
+ * <p>
+ * The effects of a successful commit of data depends on listeners and commit participants that are registered with
+ * the data broker.
+ *
+ * <p>
+ * A successful commit produces implementation-specific {@link CommitInfo} structure, which is used to communicate
+ * post-condition information to the caller. Such information can contain commit-id, timing information or any
+ * other information the implementation wishes to share.
+ *
+ * @return a FluentFuture containing the result of the commit information. The Future blocks until the commit
+ * operation is complete. A successful commit returns nothing. On failure, the Future will fail with a
+ * {@link TransactionCommitFailedException} or an exception derived from TransactionCommitFailedException.
+ * @throws IllegalStateException if the transaction is already committed or was canceled.
+ */
+ @CheckReturnValue
+ default @NonNull FluentFuture<? extends @NonNull CommitInfo> commit() {
+ return FluentFuture.from(submit()).transformAsync(ignored -> CommitInfo.emptyFluentFuture(),
+ MoreExecutors.directExecutor());
+ }
}
import com.google.common.base.MoreObjects.ToStringHelper;
import com.google.common.base.Preconditions;
import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FluentFuture;
import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.MoreExecutors;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
+import org.opendaylight.mdsal.common.api.CommitInfo;
import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.common.api.MappingCheckedFuture;
import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
import org.opendaylight.mdsal.dom.broker.TransactionCommitFailedExceptionMapper;
}
@Override
- @SuppressWarnings("checkstyle:illegalcatch")
public CheckedFuture<Void, TransactionCommitFailedException> submit() {
+ return MappingCheckedFuture.create(commit().transform(ignored -> null,
+ MoreExecutors.directExecutor()), TransactionCommitFailedExceptionMapper.COMMIT_ERROR_MAPPER);
+ }
+
+ @Override
+ @SuppressWarnings("checkstyle:IllegalCatch")
+ public FluentFuture<? extends CommitInfo> commit() {
final AbstractDOMTransactionFactory<?> impl = IMPL_UPDATER.getAndSet(this, null);
checkRunning(impl);
final Collection<T> txns = getSubtransactions();
final Collection<DOMStoreThreePhaseCommitCohort> cohorts = new ArrayList<>(txns.size());
- CheckedFuture<Void, TransactionCommitFailedException> ret;
+ FluentFuture<? extends CommitInfo> ret;
try {
for (final T txn : txns) {
cohorts.add(txn.ready());
}
- ret = impl.submit(this, cohorts);
+ ret = impl.commit(this, cohorts);
} catch (RuntimeException e) {
- ret = Futures.immediateFailedCheckedFuture(
- TransactionCommitFailedExceptionMapper.COMMIT_ERROR_MAPPER.apply(e));
+ ret = FluentFuture.from(Futures.immediateFailedFuture(
+ TransactionCommitFailedExceptionMapper.COMMIT_ERROR_MAPPER.apply(e)));
}
FUTURE_UPDATER.lazySet(this, ret);
return ret;
package org.opendaylight.controller.cluster.databroker;
import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FluentFuture;
import java.util.Collection;
import java.util.EnumMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
+import org.opendaylight.mdsal.common.api.CommitInfo;
import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
* @param cohorts the associated cohorts
* @return a resulting Future
*/
- protected abstract CheckedFuture<Void,TransactionCommitFailedException> submit(
- DOMDataTreeWriteTransaction transaction, Collection<DOMStoreThreePhaseCommitCohort> cohorts);
+ protected abstract FluentFuture<? extends CommitInfo> commit(DOMDataTreeWriteTransaction transaction,
+ Collection<DOMStoreThreePhaseCommitCohort> cohorts);
/**
* Creates a new read-only transaction.
import com.google.common.annotations.Beta;
import com.google.common.base.Preconditions;
import com.google.common.util.concurrent.AbstractFuture;
-import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FluentFuture;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import java.util.concurrent.Executor;
import org.opendaylight.controller.cluster.datastore.exceptions.NoShardLeaderException;
import org.opendaylight.controller.cluster.datastore.exceptions.ShardLeaderNotRespondingException;
+import org.opendaylight.mdsal.common.api.CommitInfo;
import org.opendaylight.mdsal.common.api.DataStoreUnavailableException;
import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.common.api.MappingCheckedFuture;
import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
import org.opendaylight.mdsal.dom.broker.TransactionCommitFailedExceptionMapper;
}
@Override
- protected CheckedFuture<Void, TransactionCommitFailedException> submit(
+ protected FluentFuture<? extends CommitInfo> commit(
final DOMDataTreeWriteTransaction transaction, final Collection<DOMStoreThreePhaseCommitCohort> cohorts) {
Preconditions.checkArgument(transaction != null, "Transaction must not be null.");
LOG.debug("Tx: {} is submitted for execution.", transaction.getIdentifier());
if (cohorts.isEmpty()) {
- return Futures.immediateCheckedFuture(null);
+ return CommitInfo.emptyFluentFuture();
}
final AsyncNotifyingSettableFuture clientSubmitFuture =
doCanCommit(clientSubmitFuture, transaction, cohorts);
- return MappingCheckedFuture.create(clientSubmitFuture, COMMIT_ERROR_MAPPER);
+ return FluentFuture.from(clientSubmitFuture).transform(ignored -> CommitInfo.empty(),
+ MoreExecutors.directExecutor());
}
private void doCanCommit(final AsyncNotifyingSettableFuture clientSubmitFuture,
package org.opendaylight.controller.cluster.databroker;
import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FluentFuture;
import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.MoreExecutors;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
+import org.opendaylight.mdsal.common.api.CommitInfo;
import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
import org.opendaylight.mdsal.common.api.TransactionChainListener;
-import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
import org.opendaylight.mdsal.dom.api.DOMTransactionChain;
import org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort;
}
@Override
- public CheckedFuture<Void, TransactionCommitFailedException> submit(
+ public FluentFuture<? extends CommitInfo> commit(
final DOMDataTreeWriteTransaction transaction, final Collection<DOMStoreThreePhaseCommitCohort> cohorts) {
checkNotFailed();
checkNotClosed();
- final CheckedFuture<Void, TransactionCommitFailedException> ret = broker.submit(transaction, cohorts);
+ final FluentFuture<? extends CommitInfo> ret = broker.commit(transaction, cohorts);
COUNTER_UPDATER.incrementAndGet(this);
- Futures.addCallback(ret, new FutureCallback<Void>() {
+ ret.addCallback(new FutureCallback<CommitInfo>() {
@Override
- public void onSuccess(final Void result) {
+ public void onSuccess(final CommitInfo result) {
transactionCompleted();
}
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FluentFuture;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import javax.annotation.Nonnull;
import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeIdentifier;
import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
+import org.opendaylight.mdsal.common.api.CommitInfo;
import org.opendaylight.mdsal.common.api.MappingCheckedFuture;
import org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohort;
import org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohortRegistration;
public CheckedFuture<Void, TransactionCommitFailedException> submit() {
return MappingCheckedFuture.create(writeDelegate().submit(), SUBMIT_EX_MAPPER);
}
+
+ @Override
+ public FluentFuture<? extends CommitInfo> commit() {
+ return writeDelegate().commit();
+ }
}
private static class DOMDataReadOnlyTransactionAdapter implements DOMDataReadOnlyTransaction {
@Test
public void submitRuntimeExceptionAndCancel() {
RuntimeException thrown = new RuntimeException();
- doThrow(thrown).when(abstractDOMTransactionFactory).submit(any(), any());
+ doThrow(thrown).when(abstractDOMTransactionFactory).commit(any(), any());
AbstractDOMBrokerWriteTransactionTestImpl abstractDOMBrokerWriteTransactionTestImpl
= new AbstractDOMBrokerWriteTransactionTestImpl();
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableMap;
import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FluentFuture;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import org.mockito.stubbing.Answer;
import org.opendaylight.controller.cluster.datastore.DistributedDataStore;
import org.opendaylight.controller.cluster.datastore.exceptions.NoShardLeaderException;
+import org.opendaylight.mdsal.common.api.CommitInfo;
import org.opendaylight.mdsal.common.api.DataStoreUnavailableException;
import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
import org.opendaylight.mdsal.common.api.TransactionChainListener;
import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
import org.opendaylight.mdsal.dom.api.DOMTransactionChain;
+import org.opendaylight.mdsal.dom.broker.TransactionCommitFailedExceptionMapper;
import org.opendaylight.mdsal.dom.spi.store.DOMStore;
import org.opendaylight.mdsal.dom.spi.store.DOMStoreReadTransaction;
import org.opendaylight.mdsal.dom.spi.store.DOMStoreReadWriteTransaction;
doReturn(Futures.immediateFuture(null)).when(mockCohort2).preCommit();
doReturn(Futures.immediateFuture(null)).when(mockCohort2).commit();
- ListenableFuture<Void> future = coordinator.submit(transaction, Arrays.asList(mockCohort1, mockCohort2));
+ 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<Void>() {
+ Futures.addCallback(future, new FutureCallback<CommitInfo>() {
@Override
- public void onSuccess(final Void result) {
+ public void onSuccess(final CommitInfo result) {
doneLatch.countDown();
}
doReturn(Futures.immediateFuture(false)).when(mockCohort3).canCommit();
doReturn(Futures.immediateFuture(null)).when(mockCohort3).abort();
- CheckedFuture<Void, TransactionCommitFailedException> future = coordinator.submit(
+ ListenableFuture<? extends CommitInfo> future = coordinator.commit(
transaction, Arrays.asList(mockCohort1, mockCohort2, mockCohort3));
assertFailure(future, null, mockCohort1, mockCohort2, mockCohort3);
}
- private static void assertFailure(final CheckedFuture<Void, TransactionCommitFailedException> future,
+ private static void assertFailure(final ListenableFuture<?> future,
final Exception expCause, final DOMStoreThreePhaseCommitCohort... mockCohorts)
throws Exception {
try {
- future.checkedGet(5, TimeUnit.SECONDS);
+ future.get(5, TimeUnit.SECONDS);
fail("Expected TransactionCommitFailedException");
- } catch (TransactionCommitFailedException e) {
+ } catch (ExecutionException e) {
+ TransactionCommitFailedException tcf = TransactionCommitFailedExceptionMapper.COMMIT_ERROR_MAPPER.apply(e);
if (expCause != null) {
- assertSame("Expected cause", expCause.getClass(), e.getCause().getClass());
+ assertSame("Expected cause", expCause.getClass(), tcf.getCause().getClass());
}
InOrder inOrder = inOrder((Object[])mockCohorts);
doReturn(Futures.immediateFailedFuture(cause)).when(mockCohort2).canCommit();
doReturn(Futures.immediateFuture(null)).when(mockCohort2).abort();
- CheckedFuture<Void, TransactionCommitFailedException> future = coordinator.submit(
+ FluentFuture<? extends CommitInfo> future = coordinator.commit(
transaction, Arrays.asList(mockCohort1, mockCohort2));
assertFailure(future, cause, mockCohort1, mockCohort2);
doReturn(Futures.immediateFailedFuture(rootCause)).when(mockCohort2).canCommit();
doReturn(Futures.immediateFuture(null)).when(mockCohort2).abort();
- CheckedFuture<Void, TransactionCommitFailedException> future = coordinator.submit(
+ FluentFuture<? extends CommitInfo> future = coordinator.commit(
transaction, Arrays.asList(mockCohort1, mockCohort2));
assertFailure(future, cause, mockCohort1, mockCohort2);
.when(mockCohort3).preCommit();
doReturn(Futures.immediateFuture(null)).when(mockCohort3).abort();
- CheckedFuture<Void, TransactionCommitFailedException> future = coordinator.submit(
+ FluentFuture<? extends CommitInfo> future = coordinator.commit(
transaction, Arrays.asList(mockCohort1, mockCohort2, mockCohort3));
assertFailure(future, cause, mockCohort1, mockCohort2, mockCohort3);
.when(mockCohort3).commit();
doReturn(Futures.immediateFuture(null)).when(mockCohort3).abort();
- CheckedFuture<Void, TransactionCommitFailedException> future = coordinator.submit(
+ FluentFuture<? extends CommitInfo> future = coordinator.commit(
transaction, Arrays.asList(mockCohort1, mockCohort2, mockCohort3));
assertFailure(future, cause, mockCohort1, mockCohort2, mockCohort3);
doReturn(Futures.immediateFailedFuture(cause)).when(mockCohort2).canCommit();
doReturn(Futures.immediateFuture(null)).when(mockCohort2).abort();
- CheckedFuture<Void, TransactionCommitFailedException> future = coordinator.submit(
+ FluentFuture<? extends CommitInfo> future = coordinator.commit(
transaction, Arrays.asList(mockCohort1, mockCohort2));
assertFailure(future, cause, mockCohort1, mockCohort2);
LogicalDatastoreType.OPERATIONAL, operationalDomStore, LogicalDatastoreType.CONFIGURATION,
configDomStore), futureExecutor) {
@Override
- public CheckedFuture<Void, TransactionCommitFailedException> submit(DOMDataTreeWriteTransaction writeTx,
+ public FluentFuture<? extends CommitInfo> commit(DOMDataTreeWriteTransaction writeTx,
Collection<DOMStoreThreePhaseCommitCohort> cohorts) {
commitCohorts.addAll(cohorts);
latch.countDown();
- return super.submit(writeTx, cohorts);
+ return super.commit(writeTx, cohorts);
}
}) {
DOMDataTreeReadWriteTransaction domDataReadWriteTransaction = dataBroker.newReadWriteTransaction();
configDomStore), futureExecutor) {
@Override
@SuppressWarnings("checkstyle:hiddenField")
- public CheckedFuture<Void, TransactionCommitFailedException> submit(DOMDataTreeWriteTransaction writeTx,
+ public FluentFuture<? extends CommitInfo> commit(DOMDataTreeWriteTransaction writeTx,
Collection<DOMStoreThreePhaseCommitCohort> cohorts) {
commitCohorts.addAll(cohorts);
latch.countDown();
- return super.submit(writeTx, cohorts);
+ return super.commit(writeTx, cohorts);
}
}) {
DOMDataTreeReadWriteTransaction domDataReadWriteTransaction = dataBroker.newReadWriteTransaction();
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableMap;
import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FluentFuture;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.MoreExecutors;
import java.util.Arrays;
import java.util.Collection;
import java.util.concurrent.TimeUnit;
+import org.eclipse.jdt.annotation.NonNull;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeIdentifier;
import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
+import org.opendaylight.mdsal.common.api.CommitInfo;
import org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohort;
import org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohortRegistration;
import org.opendaylight.mdsal.dom.spi.store.DOMStoreReadTransaction;
verify(mockConfigStore).registerChangeListener(TestModel.TEST_PATH, listener, DataChangeScope.ONE);
}
+ @Test
+ public void testCommit() throws Exception {
+ DOMDataWriteTransaction tx = adapter.newWriteOnlyTransaction();
+
+ tx.put(LogicalDatastoreType.CONFIGURATION, TestModel.TEST_PATH, dataNode);
+ verify(mockWriteTx).write(TestModel.TEST_PATH, dataNode);
+
+ @NonNull FluentFuture<? extends @NonNull CommitInfo> commitFuture = tx.commit();
+ commitFuture.get(5, TimeUnit.SECONDS);
+
+ InOrder inOrder = inOrder(mockCommitCohort);
+ inOrder.verify(mockCommitCohort).canCommit();
+ inOrder.verify(mockCommitCohort).preCommit();
+ inOrder.verify(mockCommitCohort).commit();
+ }
+
private interface TestDOMStore extends DistributedDataStoreInterface, DOMStoreTreeChangePublisher,
org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohortRegistry {
}
package org.opendaylight.controller.md.sal.dom.broker.impl;
import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.base.Supplier;
+import com.google.common.util.concurrent.ListenableFuture;
import java.util.Collection;
import java.util.EnumMap;
import java.util.Map;
protected abstract Object newTransactionIdentifier();
/**
- * User-supplied implementation of {@link DOMDataWriteTransaction#submit()}
+ * User-supplied implementation of {@link DOMDataWriteTransaction#commit()}
* for transaction.
*
* <p>
- * Callback invoked when {@link DOMDataWriteTransaction#submit()} is invoked
+ * Callback invoked when {@link DOMDataWriteTransaction#commit()} is invoked
* on transaction created by this factory.
*
* @param transaction
- * Transaction on which {@link DOMDataWriteTransaction#submit()}
+ * Transaction on which {@link DOMDataWriteTransaction#commit()}
* was invoked.
* @param cohorts
* Iteratable of cohorts for subtransactions associated with
* the transaction being committed.
- * @return a CheckedFuture. if commit coordination on cohorts finished successfully,
- * nothing is returned from the Future, On failure,
+ * @return a ListenableFuture. if commit coordination on cohorts finished successfully,
+ * a CommitInfo is returned from the Future, On failure,
* the Future fails with a {@link TransactionCommitFailedException}.
*/
- protected abstract CheckedFuture<Void,
- TransactionCommitFailedException>
- submit(DOMDataWriteTransaction transaction, Collection<DOMStoreThreePhaseCommitCohort> cohorts);
+ protected abstract <T> ListenableFuture<T> commit(DOMDataWriteTransaction transaction,
+ Collection<DOMStoreThreePhaseCommitCohort> cohorts, Supplier<T> futureValueSupplier);
/**
* Creates a new composite read-only transaction
* {@link DOMStoreWriteTransaction#delete(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier)} is
* invoked on
* selected subtransaction.
- * </li><li> {@link DOMDataWriteTransaction#submit()} - results in invoking
+ * </li><li> {@link DOMDataWriteTransaction#commit()} - results in invoking
* {@link DOMStoreWriteTransaction#ready()}, gathering all resulting cohorts
* and then invoking finalized implementation callback
- * {@link #submit(DOMDataWriteTransaction, Collection)} with transaction which
- * was commited and gathered results.
+ * {@link #commit} with transaction which was commited and gathered results.
* </li>
* </ul>
*
* {@link DOMStoreWriteTransaction#delete(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier)} is
* invoked on
* selected subtransaction.
- * <li> {@link DOMDataWriteTransaction#submit()} - results in invoking
+ * <li> {@link DOMDataWriteTransaction#commit()} - results in invoking
* {@link DOMStoreWriteTransaction#ready()}, gathering all resulting cohorts
* and then invoking finalized implementation callback
- * {@link #submit(DOMDataWriteTransaction, Collection)} with transaction which
- * was committed and gathered results.
+ * {@link #commit} with transaction which was committed and gathered results.
* <li>
* </ul>
*
package org.opendaylight.controller.md.sal.dom.broker.impl;
import com.google.common.base.Preconditions;
+import com.google.common.base.Supplier;
import com.google.common.base.Throwables;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
* Implementation of blocking three-phase commit-coordination tasks without
* support of cancellation.
*/
-final class CommitCoordinationTask implements Callable<Void> {
+final class CommitCoordinationTask<T> implements Callable<T> {
private enum Phase {
canCommit,
preCommit,
private final Collection<DOMStoreThreePhaseCommitCohort> cohorts;
private final DurationStatisticsTracker commitStatTracker;
private final DOMDataWriteTransaction tx;
+ private final Supplier<T> futureValueSupplier;
CommitCoordinationTask(final DOMDataWriteTransaction transaction,
final Collection<DOMStoreThreePhaseCommitCohort> cohorts,
- final DurationStatisticsTracker commitStatTracker) {
+ final DurationStatisticsTracker commitStatTracker,
+ final Supplier<T> futureValueSupplier) {
this.tx = Preconditions.checkNotNull(transaction, "transaction must not be null");
this.cohorts = Preconditions.checkNotNull(cohorts, "cohorts must not be null");
this.commitStatTracker = commitStatTracker;
+ this.futureValueSupplier = futureValueSupplier;
}
@Override
- public Void call() throws TransactionCommitFailedException {
+ public T call() throws TransactionCommitFailedException {
final long startTime = commitStatTracker != null ? System.nanoTime() : 0;
Phase phase = Phase.canCommit;
commitBlocking();
LOG.debug("Transaction {}: doCommit completed", tx.getIdentifier());
- return null;
+ return futureValueSupplier.get();
} catch (final TransactionCommitFailedException e) {
LOG.warn("Tx: {} Error during phase {}, starting Abort", tx.getIdentifier(), phase, e);
abortBlocking(e);
package org.opendaylight.controller.md.sal.dom.broker.impl;
import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.base.Supplier;
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 java.util.Collection;
import java.util.Map;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort;
}
@Override
- public CheckedFuture<Void, TransactionCommitFailedException> submit(final DOMDataWriteTransaction transaction,
- final
- Collection<DOMStoreThreePhaseCommitCohort>
- cohorts) {
+ public <T> ListenableFuture<T> commit(final DOMDataWriteTransaction transaction,
+ final Collection<DOMStoreThreePhaseCommitCohort> cohorts, final Supplier<T> futureValueSupplier) {
checkNotFailed();
checkNotClosed();
- final CheckedFuture<Void, TransactionCommitFailedException> ret = broker.submit(transaction, cohorts);
+ final ListenableFuture<T> ret = broker.commit(transaction, cohorts, futureValueSupplier);
COUNTER_UPDATER.incrementAndGet(this);
- Futures.addCallback(ret, new FutureCallback<Void>() {
+ Futures.addCallback(ret, new FutureCallback<T>() {
@Override
- public void onSuccess(final Void result) {
+ public void onSuccess(final T result) {
transactionCompleted();
}
public void onFailure(final Throwable throwable) {
transactionFailed(transaction, throwable);
}
- });
+ }, MoreExecutors.directExecutor());
return ret;
}
package org.opendaylight.controller.md.sal.dom.broker.impl;
import com.google.common.base.Preconditions;
+import com.google.common.base.Supplier;
import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FluentFuture;
import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort;
import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
+import org.opendaylight.mdsal.common.api.CommitInfo;
+import org.opendaylight.mdsal.common.api.MappingCheckedFuture;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.slf4j.Logger;
/**
* Future task of transaction commit. It starts off as null, but is
- * set appropriately on {@link #submit()} and {@link #cancel()} via
+ * set appropriately on {@link #commit()} and {@link #cancel()} via
* {@link AtomicReferenceFieldUpdater#lazySet(Object, Object)}.
*
* <p>
}
@Override
- @SuppressWarnings("checkstyle:illegalcatch")
public CheckedFuture<Void, TransactionCommitFailedException> submit() {
+ return MappingCheckedFuture.create(doCommit(() -> null),
+ TransactionCommitFailedExceptionMapper.COMMIT_ERROR_MAPPER);
+ }
+
+ @Override
+ public FluentFuture<? extends CommitInfo> commit() {
+ return FluentFuture.from(doCommit(CommitInfo::empty));
+ }
+
+ @SuppressWarnings("checkstyle:IllegalCatch")
+ private <V> ListenableFuture<V> doCommit(Supplier<V> futureValueSupplier) {
final AbstractDOMForwardedTransactionFactory<?> impl = IMPL_UPDATER.getAndSet(this, null);
checkRunning(impl);
final Collection<T> txns = getSubtransactions();
final Collection<DOMStoreThreePhaseCommitCohort> cohorts = new ArrayList<>(txns.size());
- CheckedFuture<Void, TransactionCommitFailedException> ret;
+ ListenableFuture<V> ret;
try {
for (DOMStoreWriteTransaction txn : txns) {
cohorts.add(txn.ready());
}
- ret = impl.submit(this, cohorts);
+ ret = impl.commit(this, cohorts, futureValueSupplier);
} catch (RuntimeException e) {
- ret = Futures.immediateFailedCheckedFuture(
- TransactionCommitFailedExceptionMapper.COMMIT_ERROR_MAPPER.apply(e));
+ ret = FluentFuture.from(Futures.immediateFailedFuture(
+ TransactionCommitFailedExceptionMapper.COMMIT_ERROR_MAPPER.apply(e)));
}
FUTURE_UPDATER.lazySet(this, ret);
return ret;
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, 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.controller.md.sal.dom.broker.impl;
-
-import com.google.common.util.concurrent.AbstractCheckedFuture;
-import com.google.common.util.concurrent.ListenableFuture;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-
-/**
- * A {@link java.util.concurrent.Future} used to report the status of an future
- * {@link java.util.concurrent.Future}.
- */
-final class PingPongFuture extends AbstractCheckedFuture<Void, TransactionCommitFailedException> {
- protected PingPongFuture(final ListenableFuture<Void> delegate) {
- super(delegate);
- }
-
- @Override
- protected TransactionCommitFailedException mapException(final Exception exception) {
- final Throwable cause = exception.getCause();
- if (cause instanceof TransactionCommitFailedException) {
- return (TransactionCommitFailedException) cause;
- } else {
- return new TransactionCommitFailedException(exception.getMessage(), cause);
- }
- }
-}
-
import com.google.common.base.MoreObjects;
import com.google.common.base.MoreObjects.ToStringHelper;
import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.CheckedFuture;
import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
+import org.opendaylight.mdsal.common.api.CommitInfo;
/**
* Transaction context. Tracks the relationship with the backend transaction.
* We never leak this class to the user and have it implement the {@link FutureCallback}
* interface so we have a simple way of propagating the result.
*/
-final class PingPongTransaction implements FutureCallback<Void> {
- private final CheckedFuture<Void, TransactionCommitFailedException> submitFuture;
+final class PingPongTransaction implements FutureCallback<CommitInfo> {
private final DOMDataReadWriteTransaction delegate;
- private final SettableFuture<Void> future;
+ private final SettableFuture<CommitInfo> future;
private DOMDataReadWriteTransaction frontendTransaction;
PingPongTransaction(final DOMDataReadWriteTransaction delegate) {
this.delegate = Preconditions.checkNotNull(delegate);
future = SettableFuture.create();
- submitFuture = new PingPongFuture(future);
}
DOMDataReadWriteTransaction getTransaction() {
return frontendTransaction;
}
- CheckedFuture<Void, TransactionCommitFailedException> getSubmitFuture() {
- return submitFuture;
+ ListenableFuture<CommitInfo> getSubmitFuture() {
+ return future;
}
@Override
- public void onSuccess(final Void result) {
+ public void onSuccess(final CommitInfo result) {
future.set(result);
}
import com.google.common.base.Preconditions;
import com.google.common.base.Verify;
import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FluentFuture;
import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.MoreExecutors;
import java.util.AbstractMap.SimpleImmutableEntry;
import java.util.Map.Entry;
import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
import org.opendaylight.controller.md.sal.dom.spi.ForwardingDOMDataReadWriteTransaction;
+import org.opendaylight.mdsal.common.api.CommitInfo;
+import org.opendaylight.mdsal.common.api.MappingCheckedFuture;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.slf4j.Logger;
return slowAllocateTransaction();
}
- // Fast path: reuse current transaction. We will check failures and similar on submit().
+ // Fast path: reuse current transaction. We will check failures and similar on commit().
if (!LOCKED_UPDATER.compareAndSet(this, null, oldTx)) {
// Ouch. Delegate chain has not detected a duplicate transaction allocation. This is the best we can do.
oldTx.getTransaction().cancel();
LOG.warn("Submitting transaction {} while {} is still running", tx, inflightTx);
}
- Futures.addCallback(tx.getTransaction().submit(), new FutureCallback<Void>() {
+ tx.getTransaction().commit().addCallback(new FutureCallback<CommitInfo>() {
@Override
- public void onSuccess(final Void result) {
+ public void onSuccess(final CommitInfo result) {
transactionSuccessful(tx, result);
}
}
}
- void transactionSuccessful(final PingPongTransaction tx, final Void result) {
+ void transactionSuccessful(final PingPongTransaction tx, final CommitInfo result) {
LOG.debug("Transaction {} completed successfully", tx);
tx.onSuccess(result);
@Override
public CheckedFuture<Void, TransactionCommitFailedException> submit() {
+ return MappingCheckedFuture.create(commit().transform(ignored -> null,
+ MoreExecutors.directExecutor()), TransactionCommitFailedExceptionMapper.COMMIT_ERROR_MAPPER);
+ }
+
+ @Override
+ public FluentFuture<? extends CommitInfo> commit() {
readyTransaction(tx);
isOpen = false;
- return tx.getSubmitFuture();
+ return FluentFuture.from(tx.getSubmitFuture()).transformAsync(
+ ignored -> CommitInfo.emptyFluentFuture(), MoreExecutors.directExecutor());
}
@Override
package org.opendaylight.controller.md.sal.dom.broker.impl;
import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.base.Supplier;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
import org.opendaylight.controller.sal.core.spi.data.DOMStore;
import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort;
-import org.opendaylight.mdsal.common.api.MappingCheckedFuture;
import org.opendaylight.yangtools.util.DurationStatisticsTracker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
}
@Override
- protected CheckedFuture<Void, TransactionCommitFailedException> submit(final DOMDataWriteTransaction transaction,
- final
- Collection<DOMStoreThreePhaseCommitCohort>
- cohorts) {
+ protected <T> ListenableFuture<T> commit(final DOMDataWriteTransaction transaction,
+ final Collection<DOMStoreThreePhaseCommitCohort> cohorts, final Supplier<T> futureValueSupplier) {
Preconditions.checkArgument(transaction != null, "Transaction must not be null.");
Preconditions.checkArgument(cohorts != null, "Cohorts must not be null.");
LOG.debug("Tx: {} is submitted for execution.", transaction.getIdentifier());
- ListenableFuture<Void> commitFuture = null;
+ ListenableFuture<T> commitFuture;
try {
- commitFuture = executor.submit(new CommitCoordinationTask(transaction, cohorts, commitStatsTracker));
+ commitFuture = executor.submit(new CommitCoordinationTask<>(transaction, cohorts, commitStatsTracker,
+ futureValueSupplier));
} catch (RejectedExecutionException e) {
LOG.error("The commit executor's queue is full - submit task was rejected. \n" + executor, e);
- return Futures.immediateFailedCheckedFuture(new TransactionCommitFailedException(
+ commitFuture = Futures.immediateFailedFuture(new TransactionCommitFailedException(
"Could not submit the commit task - the commit queue capacity has been exceeded.", e));
}
- return MappingCheckedFuture.create(commitFuture, TransactionCommitFailedExceptionMapper.COMMIT_ERROR_MAPPER);
+ return commitFuture;
}
}
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FluentFuture;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.mdsal.common.api.CommitInfo;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
return writeTxDelegate.submit();
}
+ @Override
+ public FluentFuture<? extends CommitInfo> commit() {
+ return writeTxDelegate.commit();
+ }
+
@Override
public CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> read(final LogicalDatastoreType store,
final YangInstanceIdentifier path) {
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FluentFuture;
import com.google.common.util.concurrent.Futures;
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;
import org.opendaylight.controller.md.sal.dom.broker.impl.TransactionCommitFailedExceptionMapper;
+import org.opendaylight.mdsal.common.api.CommitInfo;
import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
return Futures.makeChecked(delegateTx.submit(), TransactionCommitFailedExceptionMapper.COMMIT_ERROR_MAPPER);
}
+ @Override
+ public FluentFuture<? extends CommitInfo> commit() {
+ return delegateTx.commit();
+ }
+
@Override
public Object getIdentifier() {
return txIdentifier;
public void submitRuntimeExceptionAndCancel() {
RuntimeException thrown = new RuntimeException();
doReturn(null).when(domStoreWriteTransaction).ready();
- doThrow(thrown).when(abstractDOMForwardedTransactionFactory).submit(any(), any());
+ doThrow(thrown).when(abstractDOMForwardedTransactionFactory).commit(any(), any(), any());
DOMForwardedWriteTransaction<DOMStoreWriteTransaction> domForwardedWriteTransaction =
new DOMForwardedWriteTransaction<>(
new Object(),
domForwardedWriteTransaction.cancel();
}
}
-}
\ No newline at end of file
+}
import com.google.common.base.Optional;
import com.google.common.collect.ForwardingObject;
import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FluentFuture;
import javax.annotation.Nonnull;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
+import org.opendaylight.mdsal.common.api.CommitInfo;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
public CheckedFuture<Void, TransactionCommitFailedException> submit() {
return delegate().submit();
}
+
+ @Override
+ public FluentFuture<? extends CommitInfo> commit() {
+ return delegate().commit();
+ }
}
import com.google.common.collect.ForwardingObject;
import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FluentFuture;
import javax.annotation.Nonnull;
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;
+import org.opendaylight.mdsal.common.api.CommitInfo;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
public CheckedFuture<Void, TransactionCommitFailedException> submit() {
return delegate().submit();
}
+
+ @Override
+ public FluentFuture<? extends CommitInfo> commit() {
+ return delegate().commit();
+ }
}