*/
package org.opendaylight.controller.cluster.datastore;
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateTip;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
+import com.google.common.primitives.UnsignedLong;
+import com.google.common.util.concurrent.FutureCallback;
+import java.util.Optional;
+import java.util.SortedSet;
+import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
+import org.opendaylight.yangtools.concepts.Identifiable;
+import org.opendaylight.yangtools.yang.common.Empty;
+import org.opendaylight.yangtools.yang.data.tree.api.DataTreeCandidate;
+import org.opendaylight.yangtools.yang.data.tree.api.DataTreeCandidateTip;
+import org.opendaylight.yangtools.yang.data.tree.api.DataTreeModification;
-final class ShardDataTreeCohort implements DOMStoreThreePhaseCommitCohort {
- private static final Logger LOG = LoggerFactory.getLogger(ShardDataTreeCohort.class);
- private static final ListenableFuture<Boolean> TRUE_FUTURE = Futures.immediateFuture(Boolean.TRUE);
- private static final ListenableFuture<Void> VOID_FUTURE = Futures.immediateFuture(null);
- private final DataTreeModification transaction;
- private final ShardDataTree dataTree;
- private DataTreeCandidateTip candidate;
+@VisibleForTesting
+public abstract class ShardDataTreeCohort implements Identifiable<TransactionIdentifier> {
+ public enum State {
+ READY,
+ CAN_COMMIT_PENDING,
+ CAN_COMMIT_COMPLETE,
+ PRE_COMMIT_PENDING,
+ PRE_COMMIT_COMPLETE,
+ COMMIT_PENDING,
- ShardDataTreeCohort(final ShardDataTree dataTree, final DataTreeModification transaction) {
- this.dataTree = Preconditions.checkNotNull(dataTree);
- this.transaction = Preconditions.checkNotNull(transaction);
+ ABORTED,
+ COMMITTED,
+ FAILED,
}
- @Override
- public ListenableFuture<Boolean> canCommit() {
- try {
- dataTree.getDataTree().validate(transaction);
- LOG.debug("Transaction {} validated", transaction);
- return TRUE_FUTURE;
- } catch (Exception e) {
- return Futures.immediateFailedFuture(e);
- }
+ ShardDataTreeCohort() {
+ // Prevent foreign instantiation
}
- @Override
- public ListenableFuture<Void> preCommit() {
- try {
- candidate = dataTree.getDataTree().prepare(transaction);
- /*
- * FIXME: this is the place where we should be interacting with persistence, specifically by invoking
- * persist on the candidate (which gives us a Future).
- */
- LOG.debug("Transaction {} prepared candidate {}", transaction, candidate);
- return VOID_FUTURE;
- } catch (Exception e) {
- LOG.debug("Transaction {} failed to prepare", transaction, e);
- return Futures.immediateFailedFuture(e);
- }
- }
+ // FIXME: This leaks internal state generated in preCommit,
+ // should be result of canCommit
+ abstract DataTreeCandidateTip getCandidate();
- @Override
- public ListenableFuture<Void> abort() {
- // No-op, really
- return VOID_FUTURE;
- }
+ abstract DataTreeModification getDataTreeModification();
+
+ abstract Optional<SortedSet<String>> getParticipatingShardNames();
+
+ // FIXME: Should return rebased DataTreeCandidateTip
+ @VisibleForTesting
+ public abstract void canCommit(FutureCallback<Empty> callback);
+
+ @VisibleForTesting
+ public abstract void preCommit(FutureCallback<DataTreeCandidate> callback);
+
+ @VisibleForTesting
+ public abstract void abort(FutureCallback<Empty> callback);
+
+ @VisibleForTesting
+ public abstract void commit(FutureCallback<UnsignedLong> callback);
+
+ public abstract boolean isFailed();
+
+ public abstract State getState();
@Override
- public ListenableFuture<Void> commit() {
- try {
- dataTree.getDataTree().commit(candidate);
- } catch (Exception e) {
- LOG.error("Transaction {} failed to commit", transaction, e);
- return Futures.immediateFailedFuture(e);
- }
+ public final String toString() {
+ return addToStringAttributes(MoreObjects.toStringHelper(this).omitNullValues()).toString();
+ }
- LOG.debug("Transaction {} committed, proceeding to notify", transaction);
- dataTree.notifyListeners(candidate);
- return VOID_FUTURE;
+ ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
+ return toStringHelper.add("id", getIdentifier()).add("state", getState());
}
}