X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;ds=sidebyside;f=opendaylight%2Fmd-sal%2Fsal-distributed-datastore%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fcluster%2Fdatabroker%2Factors%2Fdds%2FAbstractProxyTransaction.java;h=9b9b86f11b84b04bda361e1b56ad837a60c393db;hb=ac9b62ec80da4d68e5d867bde0ceaa73062de444;hp=51f528150d22a717034cc4281618591645cca92f;hpb=7991491f2854dde2ec625ed6c08b44df7d258795;p=controller.git diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/actors/dds/AbstractProxyTransaction.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/actors/dds/AbstractProxyTransaction.java index 51f528150d..9b9b86f11b 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/actors/dds/AbstractProxyTransaction.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/actors/dds/AbstractProxyTransaction.java @@ -7,26 +7,29 @@ */ package org.opendaylight.controller.cluster.databroker.actors.dds; +import static com.google.common.base.Preconditions.checkState; +import static com.google.common.base.Verify.verify; +import static com.google.common.base.Verify.verifyNotNull; +import static java.util.Objects.requireNonNull; + import akka.actor.ActorRef; import com.google.common.base.MoreObjects; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.common.base.Verify; import com.google.common.collect.Iterables; -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.SettableFuture; import java.util.ArrayDeque; import java.util.Deque; import java.util.Iterator; +import java.util.Optional; +import java.util.OptionalLong; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; import java.util.function.Consumer; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import javax.annotation.concurrent.GuardedBy; -import javax.annotation.concurrent.NotThreadSafe; +import org.checkerframework.checker.lock.qual.GuardedBy; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; import org.opendaylight.controller.cluster.access.client.ConnectionEntry; import org.opendaylight.controller.cluster.access.commands.AbstractLocalTransactionRequest; import org.opendaylight.controller.cluster.access.commands.ClosedTransactionException; @@ -45,8 +48,8 @@ import org.opendaylight.controller.cluster.access.concepts.Request; import org.opendaylight.controller.cluster.access.concepts.RequestFailure; import org.opendaylight.controller.cluster.access.concepts.Response; import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier; -import org.opendaylight.mdsal.common.api.ReadFailedException; import org.opendaylight.yangtools.concepts.Identifiable; +import org.opendaylight.yangtools.yang.common.Empty; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.slf4j.Logger; @@ -65,12 +68,12 @@ import org.slf4j.LoggerFactory; * * @author Robert Varga */ +// FIXME: sealed when we have JDK17+ abstract class AbstractProxyTransaction implements Identifiable { /** * Marker object used instead of read-type of requests, which are satisfied only once. This has a lower footprint - * and allows compressing multiple requests into a single entry. + * and allows compressing multiple requests into a single entry. This class is not thread-safe. */ - @NotThreadSafe private static final class IncrementSequence { private final long sequence; private long delta = 0; @@ -100,7 +103,7 @@ abstract class AbstractProxyTransaction implements Identifiable data) { + final void merge(final YangInstanceIdentifier path, final NormalizedNode data) { checkReadWrite(); checkNotSealed(); doMerge(path, data); } - final void write(final YangInstanceIdentifier path, final NormalizedNode data) { + final void write(final YangInstanceIdentifier path, final NormalizedNode data) { checkReadWrite(); checkNotSealed(); doWrite(path, data); } - final CheckedFuture exists(final YangInstanceIdentifier path) { + final FluentFuture exists(final YangInstanceIdentifier path) { checkNotSealed(); return doExists(path); } - final CheckedFuture>, ReadFailedException> read(final YangInstanceIdentifier path) { + final FluentFuture> read(final YangInstanceIdentifier path) { checkNotSealed(); return doRead(path); } @@ -333,9 +336,9 @@ abstract class AbstractProxyTransaction implements Identifiable optState = flushState(); + final Optional optState = flushState(); if (optState.isPresent()) { forwardToSuccessor(successor, optState.get(), null); } @@ -359,15 +362,19 @@ abstract class AbstractProxyTransaction implements Identifiable enqueuedTicks) { - parent.onTransactionSealed(this); + boolean sealAndSend(final OptionalLong enqueuedTicks) { + return sealState(); + } + private boolean sealState() { + parent.onTransactionSealed(this); // Transition internal state to sealed and detect presence of a successor return STATE_UPDATER.compareAndSet(this, OPEN, SEALED); } @@ -394,16 +404,16 @@ abstract class AbstractProxyTransaction implements Identifiable req) { - successfulRequests.add(Verify.verifyNotNull(req)); + final void recordSuccessfulRequest(final @NonNull TransactionRequest req) { + successfulRequests.add(verifyNotNull(req)); } final void recordFinishedRequest(final Response response) { @@ -440,7 +450,7 @@ abstract class AbstractProxyTransaction implements Identifiable ret) { + final void abort(final VotingFuture ret) { checkSealed(); sendDoAbort(t -> { @@ -449,7 +459,7 @@ abstract class AbstractProxyTransaction implements Identifiable) t).getCause().unwrap()); } else { - ret.voteNo(new IllegalStateException("Unhandled response " + t.getClass())); + ret.voteNo(unhandledResponseException(t)); } // This is a terminal request, hence we do not need to record it @@ -494,7 +504,7 @@ abstract class AbstractProxyTransaction implements Identifiable ret = SettableFuture.create(); - sendRequest(Verify.verifyNotNull(commitRequest(false)), t -> { + sendRequest(verifyNotNull(commitRequest(false)), t -> { if (t instanceof TransactionCommitSuccess) { ret.set(Boolean.TRUE); } else if (t instanceof RequestFailure) { @@ -507,7 +517,7 @@ abstract class AbstractProxyTransaction implements Identifiable req = Verify.verifyNotNull(commitRequest(true)); + final TransactionRequest req = verifyNotNull(commitRequest(true)); sendRequest(req, t -> { if (t instanceof TransactionCanCommitSuccess) { @@ -538,7 +548,7 @@ abstract class AbstractProxyTransaction implements Identifiable) t).getCause().unwrap()); } else { - ret.voteNo(new IllegalStateException("Unhandled response " + t.getClass())); + ret.voteNo(unhandledResponseException(t)); } recordSuccessfulRequest(req); @@ -569,7 +579,7 @@ abstract class AbstractProxyTransaction implements Identifiable) t).getCause().unwrap()); } else { - ret.voteNo(new IllegalStateException("Unhandled response " + t.getClass())); + ret.voteNo(unhandledResponseException(t)); } onPreCommitComplete(req); @@ -602,7 +612,7 @@ abstract class AbstractProxyTransaction implements Identifiable) t).getCause().unwrap()); } else { - ret.voteNo(new IllegalStateException("Unhandled response " + t.getClass())); + ret.voteNo(unhandledResponseException(t)); } LOG.debug("Transaction {} doCommit completed", this); @@ -656,7 +666,7 @@ abstract class AbstractProxyTransaction implements Identifiable) obj, resp -> { }, now); + successor.doReplayRequest((TransactionRequest) obj, resp -> { /*NOOP*/ }, now); } else { - Verify.verify(obj instanceof IncrementSequence); + verify(obj instanceof IncrementSequence); final IncrementSequence increment = (IncrementSequence) obj; successor.doReplayRequest(new IncrementTransactionSequenceRequest(getIdentifier(), - increment.getSequence(), localActor(), isSnapshotOnly(), increment.getDelta()), resp -> { }, - now); + increment.getSequence(), localActor(), isSnapshotOnly(), + increment.getDelta()), resp -> { /*NOOP*/ }, now); LOG.debug("Incrementing sequence {} to successor {}", obj, successor); } } @@ -708,7 +718,7 @@ abstract class AbstractProxyTransaction implements Identifiable req = e.getRequest(); if (getIdentifier().equals(req.getTarget())) { - Verify.verify(req instanceof TransactionRequest, "Unhandled request %s", req); + verify(req instanceof TransactionRequest, "Unhandled request %s", req); LOG.debug("Replaying queued request {} to successor {}", req, successor); successor.doReplayRequest((TransactionRequest) req, e.getCallback(), e.getEnqueuedTicks()); it.remove(); @@ -723,12 +733,12 @@ abstract class AbstractProxyTransaction implements Identifiable optState = flushState(); + final Optional optState = flushState(); if (optState.isPresent()) { successor.handleReplayedRemoteRequest(optState.get(), null, enqueuedTicks); } if (successor.markSealed()) { - successor.sealAndSend(Optional.of(enqueuedTicks)); + successor.sealAndSend(OptionalLong.of(enqueuedTicks)); } } } @@ -793,16 +803,16 @@ abstract class AbstractProxyTransaction implements Identifiable data); + abstract void doMerge(YangInstanceIdentifier path, NormalizedNode data); - abstract void doWrite(YangInstanceIdentifier path, NormalizedNode data); + abstract void doWrite(YangInstanceIdentifier path, NormalizedNode data); - abstract CheckedFuture doExists(YangInstanceIdentifier path); + abstract FluentFuture doExists(YangInstanceIdentifier path); - abstract CheckedFuture>, ReadFailedException> doRead(YangInstanceIdentifier path); + abstract FluentFuture> doRead(YangInstanceIdentifier path); @GuardedBy("this") - abstract java.util.Optional flushState(); + abstract Optional flushState(); abstract TransactionRequest abortRequest(); @@ -846,6 +856,14 @@ abstract class AbstractProxyTransaction implements Identifiable request, @Nullable Consumer> callback, long enqueuedTicks); + static final @NonNull IllegalArgumentException unhandledRequest(final TransactionRequest request) { + return new IllegalArgumentException("Unhandled request " + request); + } + + private static @NonNull IllegalStateException unhandledResponseException(final Response resp) { + return new IllegalStateException("Unhandled response " + resp.getClass()); + } + @Override public final String toString() { return MoreObjects.toStringHelper(this).add("identifier", getIdentifier()).add("state", state).toString();