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.test.common;
10 import com.google.common.collect.ImmutableMap;
11 import com.google.common.util.concurrent.ListeningExecutorService;
12 import com.google.common.util.concurrent.MoreExecutors;
13 import java.util.LinkedList;
14 import java.util.List;
16 import java.util.Optional;
17 import java.util.ServiceLoader;
18 import java.util.concurrent.Executors;
19 import javassist.ClassPool;
20 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
21 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
22 import org.opendaylight.controller.md.sal.binding.api.NotificationService;
23 import org.opendaylight.controller.md.sal.binding.impl.BindingDOMDataBrokerAdapter;
24 import org.opendaylight.controller.md.sal.binding.impl.BindingDOMNotificationPublishServiceAdapter;
25 import org.opendaylight.controller.md.sal.binding.impl.BindingDOMNotificationServiceAdapter;
26 import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
27 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
28 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
29 import org.opendaylight.controller.md.sal.dom.broker.impl.DOMNotificationRouter;
30 import org.opendaylight.controller.md.sal.dom.broker.impl.SerializedDOMDataBroker;
31 import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
32 import org.opendaylight.controller.sal.core.spi.data.DOMStore;
33 import org.opendaylight.mdsal.binding.generator.impl.GeneratedClassLoadingStrategy;
34 import org.opendaylight.mdsal.binding.generator.impl.ModuleInfoBackedContext;
35 import org.opendaylight.mdsal.binding.generator.util.BindingRuntimeContext;
36 import org.opendaylight.mdsal.binding.generator.util.JavassistUtils;
37 import org.opendaylight.mdsal.dom.api.DOMSchemaService;
38 import org.opendaylight.yangtools.binding.data.codec.gen.impl.StreamWriterGenerator;
39 import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry;
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<SchemaContextListener> listener : mockedSchemaContext.listeners) {
75 listener.getInstance().onGlobalContextUpdated(mockedSchemaContext.schemaContext);
80 public DataBroker getDataBroker() {
81 return this.dataBroker;
85 public DOMDataBroker getDOMDataBroker() {
86 return this.domDataBroker;
90 public NotificationService createNotificationService() {
91 return new BindingDOMNotificationServiceAdapter(this.mockedSchemaContext.bindingStreamCodecs,
92 this.domNotificationRouter);
96 public NotificationPublishService createNotificationPublishService() {
97 return new BindingDOMNotificationPublishServiceAdapter(this.mockedSchemaContext.bindingToNormalized,
98 this.domNotificationRouter);
102 public SchemaContext getSchemaContext() {
103 return mockedSchemaContext.schemaContext;
107 public BindingNormalizedNodeCodecRegistry getBindingToNormalizedNodeCodec() {
108 return mockedSchemaContext.bindingStreamCodecs;
112 public NotificationService getNotificationService() {
113 return notificationService;
117 public NotificationPublishService getNotificationPublishService() {
118 return notificationPublishService;
121 private DOMDataBroker createDOMDataBroker() {
122 return new SerializedDOMDataBroker(datastores,
123 MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor()));
126 private ListeningExecutorService getDataTreeChangeListenerExecutor() {
127 return MoreExecutors.newDirectExecutorService();
130 private DataBroker createDataBroker() {
131 return new BindingDOMDataBrokerAdapter(getDOMDataBroker(), this.mockedSchemaContext.bindingToNormalized);
134 private Map<LogicalDatastoreType, DOMStore> createDatastores() {
135 return ImmutableMap.<LogicalDatastoreType, DOMStore>builder()
136 .put(LogicalDatastoreType.OPERATIONAL, createOperationalDatastore())
137 .put(LogicalDatastoreType.CONFIGURATION, createConfigurationDatastore()).build();
140 private DOMStore createConfigurationDatastore() {
141 final InMemoryDOMDataStore store = new InMemoryDOMDataStore("CFG", getDataTreeChangeListenerExecutor());
142 this.mockedSchemaContext.registerSchemaContextListener(store);
146 private DOMStore createOperationalDatastore() {
147 final InMemoryDOMDataStore store = new InMemoryDOMDataStore("OPER", getDataTreeChangeListenerExecutor());
148 this.mockedSchemaContext.registerSchemaContextListener(store);
152 private class SchemaContextHolder implements DOMSchemaService, SchemaContextProvider {
154 private final SchemaContext schemaContext;
155 private final ListenerRegistry<SchemaContextListener> listeners;
156 private final BindingNormalizedNodeCodecRegistry bindingStreamCodecs;
157 private final BindingToNormalizedNodeCodec bindingToNormalized;
158 private final ModuleInfoBackedContext moduleInfoBackedCntxt;
160 private SchemaContextHolder(boolean fromClasspath) {
161 List<YangModuleInfo> moduleInfos = loadModuleInfos();
162 this.moduleInfoBackedCntxt = ModuleInfoBackedContext.create();
163 this.schemaContext = getSchemaContext(moduleInfos);
164 this.listeners = ListenerRegistry.create();
165 this.bindingStreamCodecs = createBindingRegistry();
166 GeneratedClassLoadingStrategy loading = GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy();
167 this.bindingToNormalized = new BindingToNormalizedNodeCodec(loading, bindingStreamCodecs);
168 registerSchemaContextListener(this.bindingToNormalized);
172 public SchemaContext getSchemaContext() {
173 return schemaContext;
177 * Get the schemacontext from loaded modules on classpath.
179 * @param moduleInfos a list of Yang module Infos
180 * @return SchemaContext a schema context
182 private SchemaContext getSchemaContext(List<YangModuleInfo> moduleInfos) {
183 moduleInfoBackedCntxt.addModuleInfos(moduleInfos);
184 Optional<SchemaContext> tryToCreateSchemaContext =
185 moduleInfoBackedCntxt.tryToCreateSchemaContext().toJavaUtil();
186 if (!tryToCreateSchemaContext.isPresent()) {
187 LOG.error("Could not create the initial schema context. Schema context is empty");
188 throw new IllegalStateException();
190 return tryToCreateSchemaContext.get();
194 public SchemaContext getGlobalContext() {
195 return schemaContext;
199 public SchemaContext getSessionContext() {
200 return schemaContext;
204 public ListenerRegistration<SchemaContextListener> registerSchemaContextListener(
205 SchemaContextListener listener) {
206 return listeners.register(listener);
210 * Loads all {@link YangModelBindingProvider} on the classpath.
212 * @return list of known {@link YangModuleInfo}
214 private List<YangModuleInfo> loadModuleInfos() {
215 List<YangModuleInfo> moduleInfos = new LinkedList<>();
216 ServiceLoader<YangModelBindingProvider> yangProviderLoader =
217 ServiceLoader.load(YangModelBindingProvider.class);
218 for (YangModelBindingProvider yangModelBindingProvider : yangProviderLoader) {
219 moduleInfos.add(yangModelBindingProvider.getModuleInfo());
220 LOG.debug("Adding [{}] module into known modules", yangModelBindingProvider.getModuleInfo());
226 * Creates binding registry.
228 * @return BindingNormalizedNodeCodecRegistry the resulting binding registry
230 private BindingNormalizedNodeCodecRegistry createBindingRegistry() {
231 BindingRuntimeContext bindingContext = BindingRuntimeContext.create(moduleInfoBackedCntxt, schemaContext);
232 BindingNormalizedNodeCodecRegistry bindingNormalizedNodeCodecRegistry =
233 new BindingNormalizedNodeCodecRegistry(
234 StreamWriterGenerator.create(JavassistUtils.forClassPool(ClassPool.getDefault())));
235 bindingNormalizedNodeCodecRegistry.onBindingRuntimeContextUpdated(bindingContext);
236 return bindingNormalizedNodeCodecRegistry;