import com.google.common.base.Preconditions;
import com.google.common.base.Verify;
+import java.util.Optional;
import java.util.function.Consumer;
import javax.annotation.concurrent.NotThreadSafe;
-import org.opendaylight.controller.cluster.access.commands.AbortLocalTransactionRequest;
import org.opendaylight.controller.cluster.access.commands.CommitLocalTransactionRequest;
import org.opendaylight.controller.cluster.access.commands.ModifyTransactionRequest;
import org.opendaylight.controller.cluster.access.commands.PersistenceProtocol;
-import org.opendaylight.controller.cluster.access.commands.TransactionRequest;
import org.opendaylight.controller.cluster.access.concepts.Response;
import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
-import org.opendaylight.controller.cluster.datastore.util.AbstractDataTreeModificationCursor;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* A read-only specialization of {@link LocalProxyTransaction}.
*/
@NotThreadSafe
final class LocalReadOnlyProxyTransaction extends LocalProxyTransaction {
- private static final Logger LOG = LoggerFactory.getLogger(LocalReadOnlyProxyTransaction.class);
private final DataTreeSnapshot snapshot;
LocalReadOnlyProxyTransaction(final ProxyHistory parent, final TransactionIdentifier identifier,
final DataTreeSnapshot snapshot) {
- super(parent, identifier);
+ super(parent, identifier, false);
this.snapshot = Preconditions.checkNotNull(snapshot);
}
+ LocalReadOnlyProxyTransaction(final ProxyHistory parent, final TransactionIdentifier identifier) {
+ super(parent, identifier, true);
+ // It is an error to touch snapshot once we are DONE
+ this.snapshot = null;
+ }
+
@Override
boolean isSnapshotOnly() {
return true;
@Override
DataTreeSnapshot readOnlyView() {
- return snapshot;
+ return Preconditions.checkNotNull(snapshot, "Transaction %s is DONE", getIdentifier());
}
@Override
void doDelete(final YangInstanceIdentifier path) {
- throw new UnsupportedOperationException("Read-only snapshot");
+ throw new UnsupportedOperationException("doDelete");
}
@Override
void doMerge(final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
- throw new UnsupportedOperationException("Read-only snapshot");
+ throw new UnsupportedOperationException("doMerge");
}
@Override
void doWrite(final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
- throw new UnsupportedOperationException("Read-only snapshot");
+ throw new UnsupportedOperationException("doWrite");
}
@Override
CommitLocalTransactionRequest commitRequest(final boolean coordinated) {
- throw new UnsupportedOperationException("Read-only snapshot");
+ throw new UnsupportedOperationException("commitRequest");
}
@Override
- void doSeal() {
+ Optional<ModifyTransactionRequest> flushState() {
// No-op
+ return Optional.empty();
}
@Override
- void flushState(final AbstractProxyTransaction successor) {
- // No-op
+ void applyForwardedModifyTransactionRequest(final ModifyTransactionRequest request,
+ final Consumer<Response<?, ?>> callback) {
+ commonModifyTransactionRequest(request);
+ abort();
}
@Override
- void applyModifyTransactionRequest(final ModifyTransactionRequest request,
- final Consumer<Response<?, ?>> callback) {
+ void replayModifyTransactionRequest(final ModifyTransactionRequest request,
+ final Consumer<Response<?, ?>> callback, final long enqueuedTicks) {
+ commonModifyTransactionRequest(request);
+ enqueueAbort(callback, enqueuedTicks);
+ }
+
+ private static void commonModifyTransactionRequest(final ModifyTransactionRequest request) {
Verify.verify(request.getModifications().isEmpty());
final PersistenceProtocol protocol = request.getPersistenceProtocol().get();
Verify.verify(protocol == PersistenceProtocol.ABORT);
- abort();
- }
-
- @Override
- void forwardToRemote(final RemoteProxyTransaction successor, final TransactionRequest<?> request,
- final Consumer<Response<?, ?>> callback) {
- if (request instanceof CommitLocalTransactionRequest) {
- final CommitLocalTransactionRequest req = (CommitLocalTransactionRequest) request;
- final DataTreeModification mod = req.getModification();
-
- LOG.debug("Applying modification {} to successor {}", mod, successor);
- mod.applyToCursor(new AbstractDataTreeModificationCursor() {
- @Override
- public void write(final PathArgument child, final NormalizedNode<?, ?> data) {
- successor.write(current().node(child), data);
- }
-
- @Override
- public void merge(final PathArgument child, final NormalizedNode<?, ?> data) {
- successor.merge(current().node(child), data);
- }
-
- @Override
- public void delete(final PathArgument child) {
- successor.delete(current().node(child));
- }
- });
-
- successor.ensureSealed();
-
- final ModifyTransactionRequest successorReq = successor.commitRequest(req.isCoordinated());
- successor.sendRequest(successorReq, callback);
- } else if (request instanceof AbortLocalTransactionRequest) {
- LOG.debug("Forwarding abort {} to successor {}", request, successor);
- successor.abort();
- } else {
- throw new IllegalArgumentException("Unhandled request" + request);
- }
}
}