Convert sal-distributed-datastore to OSGi DS
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / main / java / org / opendaylight / controller / cluster / databroker / OSGiDOMDataBroker.java
1 /*
2  * Copyright (c) 2020 PANTHEON.tech, s.r.o. 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;
9
10 import com.google.common.annotations.Beta;
11 import com.google.common.collect.ClassToInstanceMap;
12 import com.google.common.collect.ImmutableMap;
13 import java.util.concurrent.ExecutorService;
14 import java.util.concurrent.TimeUnit;
15 import org.opendaylight.controller.cluster.datastore.jmx.mbeans.CommitStatsMXBeanImpl;
16 import org.opendaylight.controller.md.sal.common.util.jmx.ThreadExecutorStatsMXBeanImpl;
17 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
18 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
19 import org.opendaylight.mdsal.dom.api.DOMDataBrokerExtension;
20 import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
21 import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
22 import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
23 import org.opendaylight.mdsal.dom.api.DOMTransactionChain;
24 import org.opendaylight.mdsal.dom.api.DOMTransactionChainListener;
25 import org.opendaylight.mdsal.dom.spi.store.DOMStore;
26 import org.opendaylight.yangtools.util.DurationStatisticsTracker;
27 import org.opendaylight.yangtools.util.concurrent.SpecialExecutors;
28 import org.osgi.service.component.annotations.Activate;
29 import org.osgi.service.component.annotations.Component;
30 import org.osgi.service.component.annotations.Deactivate;
31 import org.osgi.service.component.annotations.Reference;
32 import org.osgi.service.metatype.annotations.AttributeDefinition;
33 import org.osgi.service.metatype.annotations.Designate;
34 import org.osgi.service.metatype.annotations.ObjectClassDefinition;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38 @Beta
39 @Component(immediate = true, configurationPid = "org.opendaylight.controller.cluster.datastore.broker",
40     property = "type=default")
41 @Designate(ocd = OSGiDOMDataBroker.Config.class)
42 public final class OSGiDOMDataBroker implements DOMDataBroker {
43     @ObjectClassDefinition
44     public @interface Config {
45         @AttributeDefinition(name = "max-data-broker-future-callback-queue-size")
46         int callbackQueueSize() default 1000;
47         @AttributeDefinition(name = "max-data-broker-future-callback-pool-size")
48         int callbackPoolSize() default 20;
49     }
50
51     private static final Logger LOG = LoggerFactory.getLogger(OSGiDOMDataBroker.class);
52
53     @Reference(target = "(type=distributed-config)")
54     DOMStore configDatastore = null;
55     @Reference(target = "(type=distributed-operational)")
56     DOMStore operDatastore = null;
57
58     private ExecutorService executorService;
59     private ConcurrentDOMDataBroker delegate;
60     private CommitStatsMXBeanImpl commitStats;
61     private ThreadExecutorStatsMXBeanImpl threadStats;
62
63     @Override
64     public DOMDataTreeReadTransaction newReadOnlyTransaction() {
65         return delegate.newReadOnlyTransaction();
66     }
67
68     @Override
69     public DOMDataTreeWriteTransaction newWriteOnlyTransaction() {
70         return delegate.newWriteOnlyTransaction();
71     }
72
73     @Override
74     public DOMDataTreeReadWriteTransaction newReadWriteTransaction() {
75         return delegate.newReadWriteTransaction();
76     }
77
78     @Override
79     public ClassToInstanceMap<DOMDataBrokerExtension> getExtensions() {
80         return delegate.getExtensions();
81     }
82
83     @Override
84     public DOMTransactionChain createTransactionChain(final DOMTransactionChainListener listener) {
85         return delegate.createTransactionChain(listener);
86     }
87
88     @Override
89     public DOMTransactionChain createMergingTransactionChain(final DOMTransactionChainListener listener) {
90         return delegate.createMergingTransactionChain(listener);
91     }
92
93     @Activate
94     void activate(final Config config) {
95         LOG.info("DOM Data Broker starting");
96         final DurationStatisticsTracker commitStatsTracker = DurationStatisticsTracker.createConcurrent();
97
98         executorService = SpecialExecutors.newBlockingBoundedCachedThreadPool(config.callbackPoolSize(),
99             config.callbackQueueSize(), "CommitFutures", ConcurrentDOMDataBroker.class);
100         delegate = new ConcurrentDOMDataBroker(ImmutableMap.of(
101             LogicalDatastoreType.CONFIGURATION, configDatastore, LogicalDatastoreType.OPERATIONAL, operDatastore),
102             executorService, commitStatsTracker);
103
104         commitStats = new CommitStatsMXBeanImpl(commitStatsTracker, "DOMDataBroker");
105         commitStats.register();
106         threadStats = ThreadExecutorStatsMXBeanImpl.create(executorService, "CommitFutureExecutorStats",
107             "DOMDataBroker");
108
109         LOG.info("DOM Data Broker started");
110     }
111
112     @Deactivate
113     void deactivate() {
114         LOG.info("DOM Data Broker stopping");
115         commitStats.unregister();
116         if (threadStats != null) {
117             threadStats.unregister();
118         }
119
120         delegate.close();
121         executorService.shutdown();
122         try {
123             executorService.awaitTermination(1, TimeUnit.MINUTES);
124         } catch (InterruptedException e) {
125             LOG.warn("Future executor failed to finish in time, giving up", e);
126         }
127         LOG.info("DOM Data Broker stopped");
128     }
129 }