BUG-8618: improve logging
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / main / java / org / opendaylight / controller / cluster / datastore / ShardDataTreeCohort.java
index 11b3ca8ed707e12f8456650fb423ca468a845660..d989cbf50cf17efddaa931ebf12f9df27b0bede8 100644 (file)
@@ -7,72 +7,65 @@
  */
 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 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 org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
+import org.opendaylight.yangtools.concepts.Identifiable;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
 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;
 
-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();
+
+    // FIXME: Should return rebased DataTreeCandidateTip
+    @VisibleForTesting
+    public abstract void canCommit(FutureCallback<Void> callback);
+
+    @VisibleForTesting
+    public abstract void preCommit(FutureCallback<DataTreeCandidate> callback);
+
+    @VisibleForTesting
+    public abstract void abort(FutureCallback<Void> 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());
     }
 }