Merge (Abstract)TransactionContext
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / main / java / org / opendaylight / controller / cluster / datastore / TransactionContext.java
index 4eea785964b1e8ef9b4023390547a813408863e4..549136b589fb1db11842ce1b9a2b7d5a83820844 100644 (file)
@@ -8,32 +8,85 @@
 package org.opendaylight.controller.cluster.datastore;
 
 import akka.actor.ActorSelection;
-import com.google.common.base.Optional;
 import com.google.common.util.concurrent.SettableFuture;
+import java.util.Optional;
+import java.util.SortedSet;
+import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
+import org.opendaylight.controller.cluster.datastore.messages.AbstractRead;
+import org.opendaylight.yangtools.concepts.AbstractSimpleIdentifiable;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import scala.concurrent.Future;
 
-/*
- * FIXME: why do we need this interface? It should be possible to integrate it with
- *        AbstractTransactionContext, which is the only implementation anyway.
- */
-interface TransactionContext {
-    void closeTransaction();
+abstract class TransactionContext extends AbstractSimpleIdentifiable<TransactionIdentifier> {
+    private static final Logger LOG = LoggerFactory.getLogger(TransactionContext.class);
+
+    private final short transactionVersion;
+
+    private long modificationCount = 0;
+    private boolean handOffComplete;
+
+    TransactionContext(final TransactionIdentifier transactionIdentifier) {
+        this(transactionIdentifier, DataStoreVersions.CURRENT_VERSION);
+    }
+
+    TransactionContext(final TransactionIdentifier transactionIdentifier, final short transactionVersion) {
+        super(transactionIdentifier);
+        this.transactionVersion = transactionVersion;
+    }
+
+    final short getTransactionVersion() {
+        return transactionVersion;
+    }
+
+    final void incrementModificationCount() {
+        modificationCount++;
+    }
+
+    final void logModificationCount() {
+        LOG.debug("Total modifications on Tx {} = [ {} ]", getIdentifier(), modificationCount);
+    }
+
+    /**
+     * Invoked by {@link AbstractTransactionContextWrapper} when it has finished handing
+     * off operations to this context. From this point on, the context is responsible
+     * for throttling operations.
+     *
+     * <p>
+     * Implementations can rely on the wrapper calling this operation in a synchronized
+     * block, so they do not need to ensure visibility of this state transition themselves.
+     */
+    final void operationHandOffComplete() {
+        handOffComplete = true;
+    }
+
+    final boolean isOperationHandOffComplete() {
+        return handOffComplete;
+    }
 
-    Future<ActorSelection> readyTransaction();
+    /**
+     * A TransactionContext that uses operation limiting should return true else false.
+     *
+     * @return true if operation limiting is used, false otherwise
+     */
+    boolean usesOperationLimiting() {
+        return false;
+    }
 
-    void writeData(YangInstanceIdentifier path, NormalizedNode<?, ?> data);
+    abstract void executeDelete(YangInstanceIdentifier path, Boolean havePermit);
 
-    void deleteData(YangInstanceIdentifier path);
+    abstract void executeMerge(YangInstanceIdentifier path, NormalizedNode data, Boolean havePermit);
 
-    void mergeData(YangInstanceIdentifier path, NormalizedNode<?, ?> data);
+    abstract void executeWrite(YangInstanceIdentifier path, NormalizedNode data, Boolean havePermit);
 
-    void readData(final YangInstanceIdentifier path, SettableFuture<Optional<NormalizedNode<?, ?>>> proxyFuture);
+    abstract <T> void executeRead(AbstractRead<T> readCmd, SettableFuture<T> proxyFuture, Boolean havePermit);
 
-    void dataExists(YangInstanceIdentifier path, SettableFuture<Boolean> proxyFuture);
+    abstract Future<ActorSelection> readyTransaction(Boolean havePermit,
+            Optional<SortedSet<String>> participatingShardNames);
 
-    boolean supportsDirectCommit();
+    abstract Future<Object> directCommit(Boolean havePermit);
 
-    Future<Object> directCommit();
+    abstract void closeTransaction();
 }