BUG-5280: add AbstractClientConnection
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / main / java / org / opendaylight / controller / cluster / databroker / actors / dds / ClientLocalHistory.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.annotations.Beta;
11 import com.google.common.base.Preconditions;
12 import org.opendaylight.controller.cluster.access.client.AbstractClientConnection;
13 import org.opendaylight.controller.cluster.access.concepts.LocalHistoryIdentifier;
14 import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
15
16 /**
17  * Client-side view of a local history. This class tracks all state related to a particular history and routes
18  * frontend requests towards the backend.
19  *
20  * <p>
21  * This interface is used by the world outside of the actor system and in the actor system it is manifested via
22  * its client actor. That requires some state transfer with {@link AbstractDataStoreClientBehavior}. In order to
23  * reduce request latency, all messages are carbon-copied (and enqueued first) to the client actor.
24  *
25  * @author Robert Varga
26  */
27 @Beta
28 public final class ClientLocalHistory extends AbstractClientHistory implements AutoCloseable {
29     ClientLocalHistory(final AbstractDataStoreClientBehavior client, final LocalHistoryIdentifier historyId) {
30         super(client, historyId);
31     }
32
33     @Override
34     public void close() {
35         final State local = state();
36         if (local != State.CLOSED) {
37             Preconditions.checkState(local == State.IDLE, "Local history %s has an open transaction", this);
38             updateState(local, State.CLOSED);
39         }
40     }
41
42     @Override
43     ClientTransaction doCreateTransaction() {
44         final State local = state();
45         Preconditions.checkState(local == State.IDLE, "Local history %s state is %s", this, local);
46         updateState(local, State.TX_OPEN);
47
48         return new ClientTransaction(this, new TransactionIdentifier(getIdentifier(), nextTx()));
49     }
50
51     @Override
52     AbstractTransactionCommitCohort onTransactionReady(final TransactionIdentifier txId,
53             final AbstractTransactionCommitCohort cohort) {
54         final State local = state();
55         switch (local) {
56             case CLOSED:
57                 return super.onTransactionReady(txId, cohort);
58             case IDLE:
59                 throw new IllegalStateException(String.format("Local history %s is idle when readying transaction %s",
60                     this, txId));
61             case TX_OPEN:
62                 updateState(local, State.IDLE);
63                 return super.onTransactionReady(txId, cohort);
64             default:
65                 throw new IllegalStateException(String.format("Local history %s in unhandled state %s", this, local));
66
67         }
68     }
69
70     @Override
71     ProxyHistory createHistoryProxy(final LocalHistoryIdentifier historyId,
72             final AbstractClientConnection<ShardBackendInfo> connection) {
73         return ProxyHistory.createClient(connection, historyId);
74     }
75 }