BUG-5280: add READY protocol
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / main / java / org / opendaylight / controller / cluster / databroker / actors / dds / LocalReadOnlyProxyTransaction.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.controller.cluster.databroker.actors.dds;
9
10 import com.google.common.base.Preconditions;
11 import com.google.common.base.Verify;
12 import java.util.function.Consumer;
13 import javax.annotation.concurrent.NotThreadSafe;
14 import org.opendaylight.controller.cluster.access.commands.AbortLocalTransactionRequest;
15 import org.opendaylight.controller.cluster.access.commands.CommitLocalTransactionRequest;
16 import org.opendaylight.controller.cluster.access.commands.ModifyTransactionRequest;
17 import org.opendaylight.controller.cluster.access.commands.PersistenceProtocol;
18 import org.opendaylight.controller.cluster.access.commands.TransactionRequest;
19 import org.opendaylight.controller.cluster.access.concepts.Response;
20 import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
21 import org.opendaylight.controller.cluster.datastore.util.AbstractDataTreeModificationCursor;
22 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
23 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
24 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
25 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
26 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29
30 /**
31  * A read-only specialization of {@link LocalProxyTransaction}.
32  *
33  * @author Robert Varga
34  */
35 @NotThreadSafe
36 final class LocalReadOnlyProxyTransaction extends LocalProxyTransaction {
37     private static final Logger LOG = LoggerFactory.getLogger(LocalReadOnlyProxyTransaction.class);
38
39     private final DataTreeSnapshot snapshot;
40
41     LocalReadOnlyProxyTransaction(final ProxyHistory parent, final TransactionIdentifier identifier,
42         final DataTreeSnapshot snapshot) {
43         super(parent, identifier);
44         this.snapshot = Preconditions.checkNotNull(snapshot);
45     }
46
47     @Override
48     boolean isSnapshotOnly() {
49         return true;
50     }
51
52     @Override
53     DataTreeSnapshot readOnlyView() {
54         return snapshot;
55     }
56
57     @Override
58     void doDelete(final YangInstanceIdentifier path) {
59         throw new UnsupportedOperationException("Read-only snapshot");
60     }
61
62     @Override
63     void doMerge(final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
64         throw new UnsupportedOperationException("Read-only snapshot");
65     }
66
67     @Override
68     void doWrite(final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
69         throw new UnsupportedOperationException("Read-only snapshot");
70     }
71
72     @Override
73     CommitLocalTransactionRequest commitRequest(final boolean coordinated) {
74         throw new UnsupportedOperationException("Read-only snapshot");
75     }
76
77     @Override
78     void doSeal() {
79         // No-op
80     }
81
82     @Override
83     void flushState(final AbstractProxyTransaction successor) {
84         // No-op
85     }
86
87     @Override
88     void applyModifyTransactionRequest(final ModifyTransactionRequest request,
89             final Consumer<Response<?, ?>> callback) {
90         Verify.verify(request.getModifications().isEmpty());
91
92         final PersistenceProtocol protocol = request.getPersistenceProtocol().get();
93         Verify.verify(protocol == PersistenceProtocol.ABORT);
94         abort();
95     }
96
97     @Override
98     void forwardToRemote(final RemoteProxyTransaction successor, final TransactionRequest<?> request,
99             final Consumer<Response<?, ?>> callback) {
100         if (request instanceof CommitLocalTransactionRequest) {
101             final CommitLocalTransactionRequest req = (CommitLocalTransactionRequest) request;
102             final DataTreeModification mod = req.getModification();
103
104             LOG.debug("Applying modification {} to successor {}", mod, successor);
105             mod.applyToCursor(new AbstractDataTreeModificationCursor() {
106                 @Override
107                 public void write(final PathArgument child, final NormalizedNode<?, ?> data) {
108                     successor.write(current().node(child), data);
109                 }
110
111                 @Override
112                 public void merge(final PathArgument child, final NormalizedNode<?, ?> data) {
113                     successor.merge(current().node(child), data);
114                 }
115
116                 @Override
117                 public void delete(final PathArgument child) {
118                     successor.delete(current().node(child));
119                 }
120             });
121
122             successor.ensureSealed();
123
124             final ModifyTransactionRequest successorReq = successor.commitRequest(req.isCoordinated());
125             successor.sendRequest(successorReq, callback);
126         } else if (request instanceof AbortLocalTransactionRequest) {
127             LOG.debug("Forwarding abort {} to successor {}", request, successor);
128             successor.abort();
129         } else {
130             throw new IllegalArgumentException("Unhandled request" + request);
131         }
132     }
133 }