Fix warnings/javadocs in sal-distributed-datastore
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / main / java / org / opendaylight / controller / cluster / datastore / ShardTransaction.java
1 /*
2  * Copyright (c) 2014 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
9 package org.opendaylight.controller.cluster.datastore;
10
11 import akka.actor.ActorRef;
12 import akka.actor.PoisonPill;
13 import akka.actor.Props;
14 import akka.actor.ReceiveTimeout;
15 import akka.japi.Creator;
16 import com.google.common.base.Optional;
17 import com.google.common.base.Preconditions;
18 import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
19 import org.opendaylight.controller.cluster.common.actor.AbstractUntypedActorWithMetering;
20 import org.opendaylight.controller.cluster.datastore.jmx.mbeans.shard.ShardStats;
21 import org.opendaylight.controller.cluster.datastore.messages.CloseTransaction;
22 import org.opendaylight.controller.cluster.datastore.messages.CloseTransactionReply;
23 import org.opendaylight.controller.cluster.datastore.messages.DataExists;
24 import org.opendaylight.controller.cluster.datastore.messages.DataExistsReply;
25 import org.opendaylight.controller.cluster.datastore.messages.ReadData;
26 import org.opendaylight.controller.cluster.datastore.messages.ReadDataReply;
27 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
28 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
29 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
30
31 /**
32  * The ShardTransaction Actor represents a remote transaction that delegates all actions to DOMDataReadWriteTransaction.
33  */
34 public abstract class ShardTransaction extends AbstractUntypedActorWithMetering {
35     private final ActorRef shardActor;
36     private final ShardStats shardStats;
37     private final TransactionIdentifier transactionID;
38
39     protected ShardTransaction(ActorRef shardActor, ShardStats shardStats, TransactionIdentifier transactionID) {
40         super("shard-tx"); //actor name override used for metering. This does not change the "real" actor name
41         this.shardActor = shardActor;
42         this.shardStats = shardStats;
43         this.transactionID = Preconditions.checkNotNull(transactionID);
44     }
45
46     public static Props props(TransactionType type, AbstractShardDataTreeTransaction<?> transaction,
47             ActorRef shardActor, DatastoreContext datastoreContext, ShardStats shardStats) {
48         return Props.create(new ShardTransactionCreator(type, transaction, shardActor, datastoreContext, shardStats));
49     }
50
51     protected abstract AbstractShardDataTreeTransaction<?> getDOMStoreTransaction();
52
53     protected ActorRef getShardActor() {
54         return shardActor;
55     }
56
57     protected final TransactionIdentifier getTransactionID() {
58         return transactionID;
59     }
60
61     @Override
62     public void handleReceive(Object message) {
63         if (CloseTransaction.isSerializedType(message)) {
64             closeTransaction(true);
65         } else if (message instanceof ReceiveTimeout) {
66             LOG.debug("Got ReceiveTimeout for inactivity - closing transaction {}", transactionID);
67             closeTransaction(false);
68         } else {
69             unknownMessage(message);
70         }
71     }
72
73     protected boolean returnCloseTransactionReply() {
74         return true;
75     }
76
77     private void closeTransaction(boolean sendReply) {
78         getDOMStoreTransaction().abort();
79
80         if (sendReply && returnCloseTransactionReply()) {
81             getSender().tell(new CloseTransactionReply(), getSelf());
82         }
83
84         getSelf().tell(PoisonPill.getInstance(), getSelf());
85     }
86
87     private boolean checkClosed(AbstractShardDataTreeTransaction<?> transaction) {
88         final boolean ret = transaction.isClosed();
89         if (ret) {
90             shardStats.incrementFailedReadTransactionsCount();
91             getSender().tell(new akka.actor.Status.Failure(new ReadFailedException("Transaction is closed")),
92                     getSelf());
93         }
94         return ret;
95     }
96
97     protected void readData(AbstractShardDataTreeTransaction<?> transaction, ReadData message) {
98         if (checkClosed(transaction)) {
99             return;
100         }
101
102         final YangInstanceIdentifier path = message.getPath();
103         Optional<NormalizedNode<?, ?>> optional = transaction.getSnapshot().readNode(path);
104         ReadDataReply readDataReply = new ReadDataReply(optional.orNull(), message.getVersion());
105         sender().tell(readDataReply.toSerializable(), self());
106     }
107
108     protected void dataExists(AbstractShardDataTreeTransaction<?> transaction, DataExists message) {
109         if (checkClosed(transaction)) {
110             return;
111         }
112
113         final YangInstanceIdentifier path = message.getPath();
114         boolean exists = transaction.getSnapshot().readNode(path).isPresent();
115         getSender().tell(new DataExistsReply(exists, message.getVersion()).toSerializable(), getSelf());
116     }
117
118     private static class ShardTransactionCreator implements Creator<ShardTransaction> {
119
120         private static final long serialVersionUID = 1L;
121
122         final AbstractShardDataTreeTransaction<?> transaction;
123         final ActorRef shardActor;
124         final DatastoreContext datastoreContext;
125         final ShardStats shardStats;
126         final TransactionType type;
127
128         ShardTransactionCreator(TransactionType type, AbstractShardDataTreeTransaction<?> transaction,
129                 ActorRef shardActor, DatastoreContext datastoreContext, ShardStats shardStats) {
130             this.transaction = Preconditions.checkNotNull(transaction);
131             this.shardActor = shardActor;
132             this.shardStats = shardStats;
133             this.datastoreContext = datastoreContext;
134             this.type = type;
135         }
136
137         @Override
138         public ShardTransaction create() throws Exception {
139             final ShardTransaction tx;
140             switch (type) {
141                 case READ_ONLY:
142                     tx = new ShardReadTransaction(transaction, shardActor, shardStats);
143                     break;
144                 case READ_WRITE:
145                     tx = new ShardReadWriteTransaction((ReadWriteShardDataTreeTransaction)transaction, shardActor,
146                             shardStats);
147                     break;
148                 case WRITE_ONLY:
149                     tx = new ShardWriteTransaction((ReadWriteShardDataTreeTransaction)transaction, shardActor,
150                             shardStats);
151                     break;
152                 default:
153                     throw new IllegalArgumentException("Unhandled transaction type " + type);
154             }
155
156             tx.getContext().setReceiveTimeout(datastoreContext.getShardTransactionIdleTimeout());
157             return tx;
158         }
159     }
160 }