799e94a3caf533c910cce0849bb015fd31b17cbd
[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                         final DOMDataTreeIdentifier path, final 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(final Map<LogicalDatastoreType, DOMStore> datastores,
76             final Class<?> expDOMStoreInterface) {
77         return datastores.values().stream().allMatch(expDOMStoreInterface::isInstance);
78     }
79
80     public void setCloseable(final AutoCloseable closeable) {
81         this.closeable = closeable;
82     }
83
84     @Override
85     @SuppressWarnings("checkstyle:IllegalCatch")
86     public void close() {
87         super.close();
88
89         if (closeable != null) {
90             try {
91                 closeable.close();
92             } catch (Exception e) {
93                 LOG.debug("Error closing instance", e);
94             }
95         }
96     }
97
98     @Override
99     protected Object newTransactionIdentifier() {
100         return "DOM-" + txNum.getAndIncrement();
101     }
102
103     @Override
104     public Map<Class<? extends DOMDataBrokerExtension>, DOMDataBrokerExtension> getSupportedExtensions() {
105         return extensions;
106     }
107
108     @Override
109     public DOMTransactionChain createTransactionChain(final TransactionChainListener listener) {
110         checkNotClosed();
111
112         final Map<LogicalDatastoreType, DOMStoreTransactionChain> backingChains =
113                 new EnumMap<>(LogicalDatastoreType.class);
114         for (Map.Entry<LogicalDatastoreType, DOMStore> entry : getTxFactories().entrySet()) {
115             backingChains.put(entry.getKey(), entry.getValue().createTransactionChain());
116         }
117
118         final long chainId = chainNum.getAndIncrement();
119         LOG.debug("Transaction chain {} created with listener {}, backing store chains {}", chainId, listener,
120                 backingChains);
121         return new DOMBrokerTransactionChain(chainId, backingChains, this, listener);
122     }
123
124     private DOMStore getDOMStore(final LogicalDatastoreType type) {
125         DOMStore store = getTxFactories().get(type);
126         checkState(store != null, "Requested logical data store is not available.");
127         return store;
128     }
129 }