X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-dom-spi%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Fcore%2Fspi%2Fdata%2FAbstractSnapshotBackedTransactionChain.java;h=e0dc0dc8de3aad229d00ca10c0d0f0f4ca4bd995;hp=b7776b2a397940745501a6c87ffcdd5625d10dcc;hb=a885056d2fddd17e3879aca9b75fe597e3be7953;hpb=2727bea09c83646b6cbd2ef9672d0b7f6cf3b22f diff --git a/opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/sal/core/spi/data/AbstractSnapshotBackedTransactionChain.java b/opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/sal/core/spi/data/AbstractSnapshotBackedTransactionChain.java index b7776b2a39..e0dc0dc8de 100644 --- a/opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/sal/core/spi/data/AbstractSnapshotBackedTransactionChain.java +++ b/opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/sal/core/spi/data/AbstractSnapshotBackedTransactionChain.java @@ -12,6 +12,7 @@ import com.google.common.base.Preconditions; import java.util.AbstractMap.SimpleEntry; import java.util.Map.Entry; import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; +import org.opendaylight.controller.sal.core.spi.data.SnapshotBackedReadTransaction.TransactionClosePrototype; import org.opendaylight.controller.sal.core.spi.data.SnapshotBackedWriteTransaction.TransactionReadyPrototype; import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification; import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot; @@ -19,20 +20,21 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * Abstract implementation of the {@link DOMStoreTransactionChain} interface relying on {@link DataTreeSnapshot} supplier - * and backend commit coordinator. + * Abstract implementation of the {@link DOMStoreTransactionChain} interface relying on {@link DataTreeSnapshot} + * supplier and backend commit coordinator. * * @param transaction identifier type */ @Beta -public abstract class AbstractSnapshotBackedTransactionChain extends TransactionReadyPrototype implements DOMStoreTransactionChain { - private static abstract class State { +public abstract class AbstractSnapshotBackedTransactionChain extends TransactionReadyPrototype + implements DOMStoreTransactionChain, TransactionClosePrototype { + private abstract static class State { /** * Allocate a new snapshot. * * @return A new snapshot */ - protected abstract DataTreeSnapshot getSnapshot(); + protected abstract DataTreeSnapshot getSnapshot(Object transactionId); } private static final class Idle extends State { @@ -43,7 +45,7 @@ public abstract class AbstractSnapshotBackedTransactionChain extends Transact } @Override - protected DataTreeSnapshot getSnapshot() { + protected DataTreeSnapshot getSnapshot(Object transactionId) { return chain.takeSnapshot(); } } @@ -66,15 +68,18 @@ public abstract class AbstractSnapshotBackedTransactionChain extends Transact } @Override - protected DataTreeSnapshot getSnapshot() { + protected DataTreeSnapshot getSnapshot(Object transactionId) { final DataTreeSnapshot ret = snapshot; - Preconditions.checkState(ret != null, "Previous transaction %s is not ready yet", transaction.getIdentifier()); + Preconditions.checkState(ret != null, + "Could not get snapshot for transaction %s - previous transaction %s is not ready yet", + transactionId, transaction.getIdentifier()); return ret; } void setSnapshot(final DataTreeSnapshot snapshot) { final boolean success = SNAPSHOT_UPDATER.compareAndSet(this, null, snapshot); - Preconditions.checkState(success, "Transaction %s has already been marked as ready", transaction.getIdentifier()); + Preconditions.checkState(success, "Transaction %s has already been marked as ready", + transaction.getIdentifier()); } } @@ -89,7 +94,7 @@ public abstract class AbstractSnapshotBackedTransactionChain extends Transact } @Override - protected DataTreeSnapshot getSnapshot() { + protected DataTreeSnapshot getSnapshot(Object transactionId) { throw new IllegalStateException(message); } } @@ -108,31 +113,45 @@ public abstract class AbstractSnapshotBackedTransactionChain extends Transact state = idleState; } - private Entry getSnapshot() { + private Entry getSnapshot(T transactionId) { final State localState = state; - return new SimpleEntry<>(localState, localState.getSnapshot()); + return new SimpleEntry<>(localState, localState.getSnapshot(transactionId)); } private boolean recordTransaction(final State expected, final DOMStoreWriteTransaction transaction) { - final State state = new Allocated(transaction); - return STATE_UPDATER.compareAndSet(this, expected, state); + final State localState = new Allocated(transaction); + return STATE_UPDATER.compareAndSet(this, expected, localState); } @Override public final DOMStoreReadTransaction newReadOnlyTransaction() { - final Entry entry = getSnapshot(); - return SnapshotBackedTransactions.newReadTransaction(nextTransactionIdentifier(), getDebugTransactions(), entry.getValue()); + return newReadOnlyTransaction(nextTransactionIdentifier()); + } + + protected DOMStoreReadTransaction newReadOnlyTransaction(T transactionId) { + final Entry entry = getSnapshot(transactionId); + return SnapshotBackedTransactions.newReadTransaction(transactionId, getDebugTransactions(), entry.getValue(), + this); + } + + @Override + public void transactionClosed(final SnapshotBackedReadTransaction tx) { + // Defaults to no-op } @Override public final DOMStoreReadWriteTransaction newReadWriteTransaction() { + return newReadWriteTransaction(nextTransactionIdentifier()); + } + + protected DOMStoreReadWriteTransaction newReadWriteTransaction(T transactionId) { Entry entry; DOMStoreReadWriteTransaction ret; do { - entry = getSnapshot(); - ret = new SnapshotBackedReadWriteTransaction(nextTransactionIdentifier(), - getDebugTransactions(), entry.getValue(), this); + entry = getSnapshot(transactionId); + ret = new SnapshotBackedReadWriteTransaction<>(transactionId, getDebugTransactions(), entry.getValue(), + this); } while (!recordTransaction(entry.getKey(), ret)); return ret; @@ -140,13 +159,16 @@ public abstract class AbstractSnapshotBackedTransactionChain extends Transact @Override public final DOMStoreWriteTransaction newWriteOnlyTransaction() { + return newWriteOnlyTransaction(nextTransactionIdentifier()); + } + + protected DOMStoreWriteTransaction newWriteOnlyTransaction(T transactionId) { Entry entry; DOMStoreWriteTransaction ret; do { - entry = getSnapshot(); - ret = new SnapshotBackedWriteTransaction(nextTransactionIdentifier(), - getDebugTransactions(), entry.getValue(), this); + entry = getSnapshot(transactionId); + ret = new SnapshotBackedWriteTransaction<>(transactionId, getDebugTransactions(), entry.getValue(), this); } while (!recordTransaction(entry.getKey(), ret)); return ret; @@ -160,7 +182,8 @@ public abstract class AbstractSnapshotBackedTransactionChain extends Transact if (allocated.getTransaction().equals(tx)) { final boolean success = STATE_UPDATER.compareAndSet(this, localState, idleState); if (!success) { - LOG.warn("Transaction {} aborted, but chain {} state already transitioned from {} to {}, very strange", + LOG.warn( + "Transaction {} aborted, but chain {} state already transitioned from {} to {}, very strange", tx, this, localState, state); } } @@ -168,19 +191,24 @@ public abstract class AbstractSnapshotBackedTransactionChain extends Transact } @Override - protected final DOMStoreThreePhaseCommitCohort transactionReady(final SnapshotBackedWriteTransaction tx, final DataTreeModification tree) { + protected final DOMStoreThreePhaseCommitCohort transactionReady( + final SnapshotBackedWriteTransaction tx, + final DataTreeModification tree, + final Exception readyError) { + final State localState = state; if (localState instanceof Allocated) { final Allocated allocated = (Allocated)localState; final DOMStoreWriteTransaction transaction = allocated.getTransaction(); - Preconditions.checkState(tx.equals(transaction), "Mis-ordered ready transaction %s last allocated was %s", tx, transaction); + Preconditions.checkState(tx.equals(transaction), "Mis-ordered ready transaction %s last allocated was %s", + tx, transaction); allocated.setSnapshot(tree); } else { LOG.debug("Ignoring transaction {} readiness due to state {}", tx, localState); } - return createCohort(tx, tree); + return createCohort(tx, tree, readyError); } @Override @@ -188,7 +216,7 @@ public abstract class AbstractSnapshotBackedTransactionChain extends Transact final State localState = state; do { - Preconditions.checkState(!CLOSED.equals(localState), "Transaction chain {} has been closed", this); + Preconditions.checkState(!CLOSED.equals(localState), "Transaction chain %s has been closed", this); if (FAILED.equals(localState)) { LOG.debug("Ignoring user close in failed state"); @@ -223,7 +251,8 @@ public abstract class AbstractSnapshotBackedTransactionChain extends Transact } if (!STATE_UPDATER.compareAndSet(this, localState, idleState)) { - LOG.debug("Transaction chain {} has already transitioned from {} to {}, not making it idle", this, localState, state); + LOG.debug("Transaction chain {} has already transitioned from {} to {}, not making it idle", + this, localState, state); } } @@ -233,7 +262,8 @@ public abstract class AbstractSnapshotBackedTransactionChain extends Transact * @param transaction Transaction which failed. * @param cause Failure cause */ - protected final void onTransactionFailed(final SnapshotBackedWriteTransaction transaction, final Throwable cause) { + protected final void onTransactionFailed(final SnapshotBackedWriteTransaction transaction, + final Throwable cause) { LOG.debug("Transaction chain {} failed on transaction {}", this, transaction, cause); state = FAILED; } @@ -264,7 +294,10 @@ public abstract class AbstractSnapshotBackedTransactionChain extends Transact * * @param transaction Transaction handle * @param modification {@link DataTreeModification} which needs to be applied to the backend + * @param operationError Any previous error that could be reported through three phase commit * @return A {@link DOMStoreThreePhaseCommitCohort} cohort. */ - protected abstract DOMStoreThreePhaseCommitCohort createCohort(final SnapshotBackedWriteTransaction transaction, final DataTreeModification modification); + protected abstract DOMStoreThreePhaseCommitCohort createCohort(SnapshotBackedWriteTransaction transaction, + DataTreeModification modification, + Exception operationError); }