2 * Copyright © 2016 AT&T and others. All rights reserved.
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
8 package org.opendaylight.transportpce.common;
10 import com.google.common.collect.ClassToInstanceMap;
11 import com.google.common.collect.ImmutableMap;
12 import com.google.common.util.concurrent.ListeningExecutorService;
13 import com.google.common.util.concurrent.MoreExecutors;
14 import java.util.LinkedList;
15 import java.util.List;
17 import java.util.Optional;
18 import java.util.ServiceLoader;
19 import java.util.concurrent.Executors;
20 import org.eclipse.jdt.annotation.NonNull;
21 import org.opendaylight.mdsal.binding.api.DataBroker;
22 import org.opendaylight.mdsal.binding.api.NotificationPublishService;
23 import org.opendaylight.mdsal.binding.api.NotificationService;
24 import org.opendaylight.mdsal.binding.dom.adapter.BindingDOMDataBrokerAdapter;
25 import org.opendaylight.mdsal.binding.dom.adapter.BindingDOMNotificationPublishServiceAdapter;
26 import org.opendaylight.mdsal.binding.dom.adapter.BindingDOMNotificationServiceAdapter;
27 import org.opendaylight.mdsal.binding.dom.adapter.BindingToNormalizedNodeCodec;
28 import org.opendaylight.mdsal.binding.dom.codec.impl.BindingNormalizedNodeCodecRegistry;
29 import org.opendaylight.mdsal.binding.generator.impl.GeneratedClassLoadingStrategy;
30 import org.opendaylight.mdsal.binding.generator.impl.ModuleInfoBackedContext;
31 import org.opendaylight.mdsal.binding.generator.util.BindingRuntimeContext;
32 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
33 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
34 import org.opendaylight.mdsal.dom.api.DOMSchemaService;
35 import org.opendaylight.mdsal.dom.api.DOMSchemaServiceExtension;
36 import org.opendaylight.mdsal.dom.broker.DOMNotificationRouter;
37 import org.opendaylight.mdsal.dom.broker.SerializedDOMDataBroker;
38 import org.opendaylight.mdsal.dom.spi.store.DOMStore;
39 import org.opendaylight.mdsal.dom.store.inmemory.InMemoryDOMDataStore;
40 import org.opendaylight.yangtools.concepts.ListenerRegistration;
41 import org.opendaylight.yangtools.util.ListenerRegistry;
42 import org.opendaylight.yangtools.yang.binding.YangModelBindingProvider;
43 import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
44 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
45 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
46 import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
50 public class DataStoreContextImpl implements DataStoreContext {
52 private static final Logger LOG = LoggerFactory.getLogger(DataStoreContextImpl.class);
54 private final Map<LogicalDatastoreType, DOMStore> datastores;
55 private final SchemaContextHolder mockedSchemaContext;
56 private final DOMNotificationRouter domNotificationRouter;
57 private final DOMDataBroker domDataBroker;
58 private final DataBroker dataBroker;
59 private final NotificationService notificationService;
60 private final NotificationPublishService notificationPublishService;
62 public DataStoreContextImpl() {
66 public DataStoreContextImpl(boolean fromClasspath) {
67 this.mockedSchemaContext = new SchemaContextHolder(fromClasspath);
68 this.datastores = createDatastores();
69 this.domNotificationRouter = DOMNotificationRouter.create(16);
70 this.domDataBroker = createDOMDataBroker();
71 this.dataBroker = createDataBroker();
72 this.notificationService = createNotificationService();
73 this.notificationPublishService = createNotificationPublishService();
74 for (ListenerRegistration<? extends SchemaContextListener> listener :
75 this.mockedSchemaContext.listeners.getRegistrations()) {
76 listener.getInstance().onGlobalContextUpdated(this.mockedSchemaContext.schemaContext);
81 public DataBroker getDataBroker() {
82 return this.dataBroker;
86 public DOMDataBroker getDOMDataBroker() {
87 return this.domDataBroker;
91 public NotificationService createNotificationService() {
92 return new BindingDOMNotificationServiceAdapter(this.domNotificationRouter,
93 this.mockedSchemaContext.bindingStreamCodecs);
97 public NotificationPublishService createNotificationPublishService() {
98 return new BindingDOMNotificationPublishServiceAdapter(this.domNotificationRouter,
99 this.mockedSchemaContext.bindingToNormalized);
103 public SchemaContext getSchemaContext() {
104 return this.mockedSchemaContext.schemaContext;
108 public BindingNormalizedNodeCodecRegistry getBindingToNormalizedNodeCodec() {
109 return this.mockedSchemaContext.bindingStreamCodecs;
113 public NotificationService getNotificationService() {
114 return this.notificationService;
118 public NotificationPublishService getNotificationPublishService() {
119 return this.notificationPublishService;
122 private DOMDataBroker createDOMDataBroker() {
123 return new SerializedDOMDataBroker(this.datastores,
124 MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor()));
127 private ListeningExecutorService getDataTreeChangeListenerExecutor() {
128 return MoreExecutors.newDirectExecutorService();
131 private DataBroker createDataBroker() {
132 return new BindingDOMDataBrokerAdapter(getDOMDataBroker(), this.mockedSchemaContext.bindingToNormalized);
135 private Map<LogicalDatastoreType, DOMStore> createDatastores() {
136 return ImmutableMap.<LogicalDatastoreType, DOMStore>builder()
137 .put(LogicalDatastoreType.OPERATIONAL, createOperationalDatastore())
138 .put(LogicalDatastoreType.CONFIGURATION, createConfigurationDatastore()).build();
141 private DOMStore createConfigurationDatastore() {
142 final InMemoryDOMDataStore store = new InMemoryDOMDataStore("CFG", getDataTreeChangeListenerExecutor());
143 this.mockedSchemaContext.registerSchemaContextListener(store);
147 private DOMStore createOperationalDatastore() {
148 final InMemoryDOMDataStore store = new InMemoryDOMDataStore("OPER", getDataTreeChangeListenerExecutor());
149 this.mockedSchemaContext.registerSchemaContextListener(store);
153 private static final class SchemaContextHolder implements DOMSchemaService, SchemaContextProvider {
155 private final SchemaContext schemaContext;
156 private final ListenerRegistry<SchemaContextListener> listeners;
157 private final BindingNormalizedNodeCodecRegistry bindingStreamCodecs;
158 private final BindingToNormalizedNodeCodec bindingToNormalized;
159 private final ModuleInfoBackedContext moduleInfoBackedCntxt;
161 private SchemaContextHolder(boolean fromClasspath) {
162 List<YangModuleInfo> moduleInfos = loadModuleInfos();
163 this.moduleInfoBackedCntxt = ModuleInfoBackedContext.create();
164 this.schemaContext = getSchemaContext(moduleInfos);
165 this.listeners = ListenerRegistry.create();
166 this.bindingStreamCodecs = createBindingRegistry();
167 GeneratedClassLoadingStrategy loading = GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy();
168 this.bindingToNormalized = new BindingToNormalizedNodeCodec(loading, this.bindingStreamCodecs);
169 registerSchemaContextListener(this.bindingToNormalized);
173 public SchemaContext getSchemaContext() {
174 return this.schemaContext;
178 * Get the schemacontext from loaded modules on classpath.
180 * @param moduleInfos a list of Yang module Infos
181 * @return SchemaContext a schema context
183 private SchemaContext getSchemaContext(List<YangModuleInfo> moduleInfos) {
184 this.moduleInfoBackedCntxt.addModuleInfos(moduleInfos);
185 Optional<? extends SchemaContext> tryToCreateSchemaContext =
186 this.moduleInfoBackedCntxt.tryToCreateSchemaContext();
187 if (!tryToCreateSchemaContext.isPresent()) {
188 LOG.error("Could not create the initial schema context. Schema context is empty");
189 throw new IllegalStateException();
191 return tryToCreateSchemaContext.get();
195 public SchemaContext getGlobalContext() {
196 return this.schemaContext;
200 public SchemaContext getSessionContext() {
201 return this.schemaContext;
205 public ListenerRegistration<SchemaContextListener> registerSchemaContextListener(
206 SchemaContextListener listener) {
207 return this.listeners.register(listener);
211 * Loads all {@link YangModelBindingProvider} on the classpath.
213 * @return list of known {@link YangModuleInfo}
215 private List<YangModuleInfo> loadModuleInfos() {
216 List<YangModuleInfo> moduleInfos = new LinkedList<>();
217 ServiceLoader<YangModelBindingProvider> yangProviderLoader =
218 ServiceLoader.load(YangModelBindingProvider.class);
219 for (YangModelBindingProvider yangModelBindingProvider : yangProviderLoader) {
220 moduleInfos.add(yangModelBindingProvider.getModuleInfo());
221 LOG.debug("Adding [{}] module into known modules", yangModelBindingProvider.getModuleInfo());
227 * Creates binding registry.
229 * @return BindingNormalizedNodeCodecRegistry the resulting binding registry
231 private BindingNormalizedNodeCodecRegistry createBindingRegistry() {
232 BindingRuntimeContext bindingContext =
233 BindingRuntimeContext.create(this.moduleInfoBackedCntxt, this.schemaContext);
234 BindingNormalizedNodeCodecRegistry bindingNormalizedNodeCodecRegistry =
235 new BindingNormalizedNodeCodecRegistry(bindingContext);
236 return bindingNormalizedNodeCodecRegistry;
240 * @see org.opendaylight.mdsal.dom.api.DOMExtensibleService#getExtensions()
243 public @NonNull ClassToInstanceMap<DOMSchemaServiceExtension> getExtensions() {
244 // TODO Auto-generated method stub