Convert CDS implementation to use msdal APIs
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / main / java / org / opendaylight / controller / cluster / databroker / AbstractDOMBroker.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
9 package org.opendaylight.controller.cluster.databroker;
10
11 import static com.google.common.base.Preconditions.checkState;
12
13 import com.google.common.collect.ImmutableMap;
14 import com.google.common.collect.ImmutableMap.Builder;
15 import java.util.EnumMap;
16 import java.util.Map;
17 import java.util.concurrent.atomic.AtomicLong;
18 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
19 import org.opendaylight.mdsal.common.api.TransactionChainListener;
20 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
21 import org.opendaylight.mdsal.dom.api.DOMDataBrokerExtension;
22 import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeListener;
23 import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeService;
24 import org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohort;
25 import org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohortRegistration;
26 import org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohortRegistry;
27 import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
28 import org.opendaylight.mdsal.dom.api.DOMTransactionChain;
29 import org.opendaylight.mdsal.dom.spi.store.DOMStore;
30 import org.opendaylight.mdsal.dom.spi.store.DOMStoreTransactionChain;
31 import org.opendaylight.mdsal.dom.spi.store.DOMStoreTreeChangePublisher;
32 import org.opendaylight.yangtools.concepts.ListenerRegistration;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36 public abstract class AbstractDOMBroker extends AbstractDOMTransactionFactory<DOMStore> implements DOMDataBroker {
37
38     private static final Logger LOG = LoggerFactory.getLogger(AbstractDOMBroker.class);
39
40     private final AtomicLong txNum = new AtomicLong();
41     private final AtomicLong chainNum = new AtomicLong();
42     private final Map<Class<? extends DOMDataBrokerExtension>, DOMDataBrokerExtension> extensions;
43     private volatile AutoCloseable closeable;
44
45     protected AbstractDOMBroker(final Map<LogicalDatastoreType, DOMStore> datastores) {
46         super(datastores);
47
48         Builder<Class<? extends DOMDataBrokerExtension>, DOMDataBrokerExtension> extBuilder = ImmutableMap.builder();
49         if (isSupported(datastores, DOMStoreTreeChangePublisher.class)) {
50             extBuilder.put(DOMDataTreeChangeService.class, new DOMDataTreeChangeService() {
51                 @Override
52                 public <L extends DOMDataTreeChangeListener> ListenerRegistration<L> registerDataTreeChangeListener(
53                         final DOMDataTreeIdentifier treeId, final L listener) {
54                     DOMStore store = getDOMStore(treeId.getDatastoreType());
55                     return ((DOMStoreTreeChangePublisher) store).registerTreeChangeListener(
56                             treeId.getRootIdentifier(), listener);
57                 }
58             });
59         }
60
61         if (isSupported(datastores, DOMDataTreeCommitCohortRegistry.class)) {
62             extBuilder.put(DOMDataTreeCommitCohortRegistry.class, new DOMDataTreeCommitCohortRegistry() {
63                 @Override
64                 public <T extends DOMDataTreeCommitCohort> DOMDataTreeCommitCohortRegistration<T> registerCommitCohort(
65                         DOMDataTreeIdentifier path, T cohort) {
66                     DOMStore store = getDOMStore(path.getDatastoreType());
67                     return ((DOMDataTreeCommitCohortRegistry) store).registerCommitCohort(path, cohort);
68                 }
69             });
70         }
71
72         extensions = extBuilder.build();
73     }
74
75     private static boolean isSupported(Map<LogicalDatastoreType, DOMStore> datastores,
76             Class<?> expDOMStoreInterface) {
77         for (DOMStore ds : datastores.values()) {
78             if (!expDOMStoreInterface.isAssignableFrom(ds.getClass())) {
79                 return false;
80             }
81         }
82
83         return true;
84     }
85
86     public void setCloseable(final AutoCloseable closeable) {
87         this.closeable = closeable;
88     }
89
90     @Override
91     @SuppressWarnings("checkstyle:IllegalCatch")
92     public void close() {
93         super.close();
94
95         if (closeable != null) {
96             try {
97                 closeable.close();
98             } catch (Exception e) {
99                 LOG.debug("Error closing instance", e);
100             }
101         }
102     }
103
104     @Override
105     protected Object newTransactionIdentifier() {
106         return "DOM-" + txNum.getAndIncrement();
107     }
108
109     @Override
110     public Map<Class<? extends DOMDataBrokerExtension>, DOMDataBrokerExtension> getSupportedExtensions() {
111         return extensions;
112     }
113
114     @Override
115     public DOMTransactionChain createTransactionChain(final TransactionChainListener listener) {
116         checkNotClosed();
117
118         final Map<LogicalDatastoreType, DOMStoreTransactionChain> backingChains =
119                 new EnumMap<>(LogicalDatastoreType.class);
120         for (Map.Entry<LogicalDatastoreType, DOMStore> entry : getTxFactories().entrySet()) {
121             backingChains.put(entry.getKey(), entry.getValue().createTransactionChain());
122         }
123
124         final long chainId = chainNum.getAndIncrement();
125         LOG.debug("Transaction chain {} created with listener {}, backing store chains {}", chainId, listener,
126                 backingChains);
127         return new DOMBrokerTransactionChain(chainId, backingChains, this, listener);
128     }
129
130     private DOMStore getDOMStore(final LogicalDatastoreType type) {
131         DOMStore store = getTxFactories().get(type);
132         checkState(store != null, "Requested logical data store is not available.");
133         return store;
134     }
135 }