CDS: Implement front-end support for local transactions
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / main / java / org / opendaylight / controller / cluster / datastore / TransactionContextFactory.java
1 /*
2  * Copyright (c) 2015 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.datastore;
9
10 import akka.actor.ActorSelection;
11 import java.util.ArrayList;
12 import java.util.Collection;
13 import javax.annotation.concurrent.GuardedBy;
14 import org.opendaylight.controller.cluster.datastore.identifiers.TransactionIdentifier;
15 import org.opendaylight.controller.cluster.datastore.messages.PrimaryShardInfo;
16 import org.opendaylight.controller.cluster.datastore.utils.ActorContext;
17 import org.opendaylight.controller.cluster.datastore.utils.ShardInfoListenerRegistration;
18 import org.opendaylight.controller.sal.core.spi.data.DOMStoreTransactionChain;
19 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
20 import scala.concurrent.Future;
21
22 /**
23  * An {@link AbstractTransactionContextFactory} which produces TransactionContext instances for single
24  * transactions (ie not chained).
25  */
26 final class TransactionContextFactory extends AbstractTransactionContextFactory<LocalTransactionFactoryImpl> {
27
28     @GuardedBy("childChains")
29     private final Collection<TransactionChainProxy> childChains = new ArrayList<>();
30
31     private final ShardInfoListenerRegistration<TransactionContextFactory> reg;
32
33     private TransactionContextFactory(final ActorContext actorContext) {
34         super(actorContext);
35         this.reg = actorContext.registerShardInfoListener(this);
36     }
37
38     static TransactionContextFactory create(final ActorContext actorContext) {
39         return new TransactionContextFactory(actorContext);
40     }
41
42     @Override
43     public void close() {
44         reg.close();
45     }
46
47     @Override
48     protected TransactionIdentifier nextIdentifier() {
49         return TransactionIdentifier.create(getMemberName(), TX_COUNTER.getAndIncrement(), null);
50     }
51
52     @Override
53     protected LocalTransactionFactoryImpl factoryForShard(final String shardName, final ActorSelection shardLeader, final DataTree dataTree) {
54         return new LocalTransactionFactoryImpl(getActorContext(), shardLeader, dataTree);
55     }
56
57     @Override
58     protected Future<PrimaryShardInfo> findPrimaryShard(final String shardName) {
59         return getActorContext().findPrimaryShardAsync(shardName);
60     }
61
62     @Override
63     protected <T> void onTransactionReady(final TransactionIdentifier transaction, final Collection<Future<T>> cohortFutures) {
64         // Transactions are disconnected, this is a no-op
65     }
66
67     DOMStoreTransactionChain createTransactionChain() {
68         final TransactionChainProxy ret = new TransactionChainProxy(this);
69
70         synchronized (childChains) {
71             childChains.add(ret);
72         }
73
74         return ret;
75     }
76
77     void removeTransactionChain(final TransactionChainProxy chain) {
78         synchronized (childChains) {
79             childChains.remove(chain);
80         }
81     }
82
83     @Override
84     public void onShardInfoUpdated(final String shardName, final PrimaryShardInfo primaryShardInfo) {
85         synchronized (childChains) {
86             for (TransactionChainProxy chain : childChains) {
87                 chain.onShardInfoUpdated(shardName, primaryShardInfo);
88             }
89             super.onShardInfoUpdated(shardName, primaryShardInfo);
90         }
91     }
92
93     @Override
94     protected DataTree dataTreeForFactory(final LocalTransactionFactoryImpl factory) {
95         return factory.getDataTree();
96     }
97 }