Convert sal-distributed-datastore to OSGi DS
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / main / java / org / opendaylight / controller / cluster / datastore / AbstractOSGiDOMStore.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.datastore;
9
10 import static java.util.Objects.requireNonNull;
11
12 import com.google.common.annotations.Beta;
13 import java.util.Map;
14 import org.opendaylight.controller.cluster.ActorSystemProvider;
15 import org.opendaylight.controller.cluster.datastore.config.ConfigurationImpl;
16 import org.opendaylight.controller.cluster.datastore.config.ModuleShardConfigProvider;
17 import org.opendaylight.controller.cluster.datastore.utils.ActorUtils;
18 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
19 import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeListener;
20 import org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohort;
21 import org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohortRegistration;
22 import org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohortRegistry;
23 import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
24 import org.opendaylight.mdsal.dom.api.DOMSchemaService;
25 import org.opendaylight.mdsal.dom.spi.store.DOMStore;
26 import org.opendaylight.mdsal.dom.spi.store.DOMStoreReadTransaction;
27 import org.opendaylight.mdsal.dom.spi.store.DOMStoreReadWriteTransaction;
28 import org.opendaylight.mdsal.dom.spi.store.DOMStoreTransactionChain;
29 import org.opendaylight.mdsal.dom.spi.store.DOMStoreTreeChangePublisher;
30 import org.opendaylight.mdsal.dom.spi.store.DOMStoreWriteTransaction;
31 import org.opendaylight.yangtools.concepts.ListenerRegistration;
32 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
33 import org.osgi.service.component.annotations.Activate;
34 import org.osgi.service.component.annotations.Component;
35 import org.osgi.service.component.annotations.Deactivate;
36 import org.osgi.service.component.annotations.Modified;
37 import org.osgi.service.component.annotations.Reference;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40
41 @Beta
42 public abstract class AbstractOSGiDOMStore
43         implements DistributedDataStoreInterface, DOMStoreTreeChangePublisher, DOMDataTreeCommitCohortRegistry {
44     @Component(immediate = true, service = { DOMStore.class,  DistributedDataStoreInterface.class },
45             configurationPid = "org.opendaylight.controller.cluster.datastore",
46             property = "type=distributed-config")
47     public static final class Configuration extends AbstractOSGiDOMStore {
48         @Reference
49         DOMSchemaService schemaService = null;
50         @Reference
51         ActorSystemProvider actorSystemProvider = null;
52         @Reference
53         DatastoreContextIntrospectorFactory introspectorFactory = null;
54         @Reference
55         DatastoreSnapshotRestore snapshotRestore = null;
56
57         public Configuration() {
58             super(LogicalDatastoreType.CONFIGURATION);
59         }
60
61         @Activate
62         void activate(final Map<String, Object> properties) throws InterruptedException {
63             start(schemaService, actorSystemProvider, introspectorFactory, snapshotRestore, null);
64         }
65
66         @Modified
67         void modified(final Map<String, Object> properties) {
68             update(properties);
69         }
70
71         @Deactivate
72         void deactivate() {
73             stop();
74         }
75     }
76
77     @Component(immediate = true, service = { DOMStore.class, DistributedDataStoreInterface.class },
78             configurationPid = "org.opendaylight.controller.cluster.datastore",
79             property = "type=distributed-operational")
80     public static final class Operational extends AbstractOSGiDOMStore {
81         @Reference
82         DOMSchemaService schemaService = null;
83         @Reference
84         ActorSystemProvider actorSystemProvider = null;
85         @Reference
86         DatastoreContextIntrospectorFactory introspectorFactory = null;
87         @Reference
88         DatastoreSnapshotRestore snapshotRestore = null;
89         @Reference
90         ModuleShardConfigProvider configProvider = null;
91
92         public Operational() {
93             super(LogicalDatastoreType.OPERATIONAL);
94         }
95
96         @Activate
97         void activate(final Map<String, Object> properties) throws InterruptedException {
98             start(schemaService, actorSystemProvider, introspectorFactory, snapshotRestore,
99                 new ConfigurationImpl(configProvider));
100         }
101
102         @Modified
103         void modified(final Map<String, Object> properties) {
104             update(properties);
105         }
106
107         @Deactivate
108         void deactivate() {
109             stop();
110         }
111     }
112
113     private static final Logger LOG = LoggerFactory.getLogger(AbstractOSGiDOMStore.class);
114
115     private final LogicalDatastoreType datastoreType;
116
117     private ListenerRegistration<?> schemaRegistration;
118     private DatastoreContextIntrospector introspector;
119     private AbstractDataStore datastore;
120
121     AbstractOSGiDOMStore(final LogicalDatastoreType datastoreType) {
122         this.datastoreType = requireNonNull(datastoreType);
123     }
124
125     @Override
126     public final ActorUtils getActorUtils() {
127         return datastore.getActorUtils();
128     }
129
130     @Override
131     public final <L extends DOMDataTreeChangeListener> ListenerRegistration<L> registerShardConfigListener(
132             final YangInstanceIdentifier internalPath, final DOMDataTreeChangeListener delegate) {
133         return datastore.registerShardConfigListener(internalPath, delegate);
134     }
135
136     @Override
137     public final <L extends DOMDataTreeChangeListener> ListenerRegistration<L> registerProxyListener(
138             final YangInstanceIdentifier shardLookup, final YangInstanceIdentifier insideShard,
139             final DOMDataTreeChangeListener delegate) {
140         return datastore.registerProxyListener(shardLookup, insideShard, delegate);
141     }
142
143     @Override
144     public final <L extends DOMDataTreeChangeListener> ListenerRegistration<L> registerTreeChangeListener(
145             final YangInstanceIdentifier treeId, final L listener) {
146         return datastore.registerTreeChangeListener(treeId, listener);
147     }
148
149     @Override
150     public final <T extends DOMDataTreeCommitCohort> DOMDataTreeCommitCohortRegistration<T> registerCommitCohort(
151             final DOMDataTreeIdentifier path, final T cohort) {
152         return datastore.registerCommitCohort(path, cohort);
153     }
154
155     @Override
156     public final DOMStoreTransactionChain createTransactionChain() {
157         return datastore.createTransactionChain();
158     }
159
160     @Override
161     public final DOMStoreReadTransaction newReadOnlyTransaction() {
162         return datastore.newReadOnlyTransaction();
163     }
164
165     @Override
166     public final DOMStoreWriteTransaction newWriteOnlyTransaction() {
167         return datastore.newWriteOnlyTransaction();
168     }
169
170     @Override
171     public final DOMStoreReadWriteTransaction newReadWriteTransaction() {
172         return datastore.newReadWriteTransaction();
173     }
174
175     final void start(final DOMSchemaService schemaService, final ActorSystemProvider actorSystemProvider,
176             final DatastoreContextIntrospectorFactory introspectorFactory,
177             final DatastoreSnapshotRestore snapshotRestore,
178             final org.opendaylight.controller.cluster.datastore.config.Configuration config)
179                     throws InterruptedException {
180         LOG.info("Distributed Datastore type {} starting", datastoreType);
181         introspector = introspectorFactory.newInstance(datastoreType);
182
183         datastore = DistributedDataStoreFactory.createInstance(actorSystemProvider, introspector.getContext(),
184             introspector, snapshotRestore, config);
185         schemaRegistration = schemaService.registerSchemaContextListener(datastore);
186
187         datastore.awaitReadiness();
188         LOG.info("Distributed Datastore type {} started", datastoreType);
189     }
190
191     final void update(final Map<String, Object> properties) {
192         LOG.debug("Overlaying settings: {}", properties);
193         if (introspector.update(properties)) {
194             datastore.onDatastoreContextUpdated(introspector.newContextFactory());
195         }
196     }
197
198     final void stop() {
199         LOG.info("Distributed Datastore type {} stopping", datastoreType);
200         schemaRegistration.close();
201         datastore.close();
202         LOG.info("Distributed Datastore type {} stopped", datastoreType);
203     }
204 }