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.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 javassist.ClassPool;
21 import org.eclipse.jdt.annotation.NonNull;
22 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
23 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
24 import org.opendaylight.controller.md.sal.binding.api.NotificationService;
25 import org.opendaylight.controller.md.sal.binding.impl.BindingDOMDataBrokerAdapter;
26 import org.opendaylight.controller.md.sal.binding.impl.BindingDOMNotificationPublishServiceAdapter;
27 import org.opendaylight.controller.md.sal.binding.impl.BindingDOMNotificationServiceAdapter;
28 import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
29 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
30 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
31 import org.opendaylight.controller.md.sal.dom.broker.impl.DOMNotificationRouter;
32 import org.opendaylight.controller.md.sal.dom.broker.impl.SerializedDOMDataBroker;
33 import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
34 import org.opendaylight.controller.sal.core.spi.data.DOMStore;
35 import org.opendaylight.mdsal.binding.dom.codec.gen.impl.StreamWriterGenerator;
36 import org.opendaylight.mdsal.binding.dom.codec.impl.BindingNormalizedNodeCodecRegistry;
37 import org.opendaylight.mdsal.binding.generator.impl.GeneratedClassLoadingStrategy;
38 import org.opendaylight.mdsal.binding.generator.impl.ModuleInfoBackedContext;
39 import org.opendaylight.mdsal.binding.generator.util.BindingRuntimeContext;
40 import org.opendaylight.mdsal.binding.generator.util.JavassistUtils;
41 import org.opendaylight.mdsal.dom.api.DOMSchemaService;
42 import org.opendaylight.mdsal.dom.api.DOMSchemaServiceExtension;
43 import org.opendaylight.yangtools.concepts.ListenerRegistration;
44 import org.opendaylight.yangtools.util.ListenerRegistry;
45 import org.opendaylight.yangtools.yang.binding.YangModelBindingProvider;
46 import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
47 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
48 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
49 import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
50 import org.slf4j.Logger;
51 import org.slf4j.LoggerFactory;
53 public class DataStoreContextImpl implements DataStoreContext {
55 private static final Logger LOG = LoggerFactory.getLogger(DataStoreContextImpl.class);
57 private final Map<LogicalDatastoreType, DOMStore> datastores;
58 private final SchemaContextHolder mockedSchemaContext;
59 private final DOMNotificationRouter domNotificationRouter;
60 private final DOMDataBroker domDataBroker;
61 private final DataBroker dataBroker;
62 private final NotificationService notificationService;
63 private final NotificationPublishService notificationPublishService;
65 public DataStoreContextImpl() {
69 public DataStoreContextImpl(boolean fromClasspath) {
70 this.mockedSchemaContext = new SchemaContextHolder(fromClasspath);
71 this.datastores = createDatastores();
72 this.domNotificationRouter = DOMNotificationRouter.create(16);
73 this.domDataBroker = createDOMDataBroker();
74 this.dataBroker = createDataBroker();
75 this.notificationService = createNotificationService();
76 this.notificationPublishService = createNotificationPublishService();
77 for (ListenerRegistration<SchemaContextListener> listener : this.mockedSchemaContext.listeners) {
78 listener.getInstance().onGlobalContextUpdated(this.mockedSchemaContext.schemaContext);
83 public DataBroker getDataBroker() {
84 return this.dataBroker;
88 public DOMDataBroker getDOMDataBroker() {
89 return this.domDataBroker;
93 public NotificationService createNotificationService() {
94 return new BindingDOMNotificationServiceAdapter(this.mockedSchemaContext.bindingStreamCodecs,
95 this.domNotificationRouter);
99 public NotificationPublishService createNotificationPublishService() {
100 return new BindingDOMNotificationPublishServiceAdapter(this.mockedSchemaContext.bindingToNormalized,
101 this.domNotificationRouter);
105 public SchemaContext getSchemaContext() {
106 return this.mockedSchemaContext.schemaContext;
110 public BindingNormalizedNodeCodecRegistry getBindingToNormalizedNodeCodec() {
111 return this.mockedSchemaContext.bindingStreamCodecs;
115 public NotificationService getNotificationService() {
116 return this.notificationService;
120 public NotificationPublishService getNotificationPublishService() {
121 return this.notificationPublishService;
124 private DOMDataBroker createDOMDataBroker() {
125 return new SerializedDOMDataBroker(this.datastores,
126 MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor()));
129 private ListeningExecutorService getDataTreeChangeListenerExecutor() {
130 return MoreExecutors.newDirectExecutorService();
133 private DataBroker createDataBroker() {
134 return new BindingDOMDataBrokerAdapter(getDOMDataBroker(), this.mockedSchemaContext.bindingToNormalized);
137 private Map<LogicalDatastoreType, DOMStore> createDatastores() {
138 return ImmutableMap.<LogicalDatastoreType, DOMStore>builder()
139 .put(LogicalDatastoreType.OPERATIONAL, createOperationalDatastore())
140 .put(LogicalDatastoreType.CONFIGURATION, createConfigurationDatastore()).build();
143 private DOMStore createConfigurationDatastore() {
144 final InMemoryDOMDataStore store = new InMemoryDOMDataStore("CFG", getDataTreeChangeListenerExecutor());
145 this.mockedSchemaContext.registerSchemaContextListener(store);
149 private DOMStore createOperationalDatastore() {
150 final InMemoryDOMDataStore store = new InMemoryDOMDataStore("OPER", getDataTreeChangeListenerExecutor());
151 this.mockedSchemaContext.registerSchemaContextListener(store);
155 private final class SchemaContextHolder implements DOMSchemaService, SchemaContextProvider {
157 private final SchemaContext schemaContext;
158 private final ListenerRegistry<SchemaContextListener> listeners;
159 private final BindingNormalizedNodeCodecRegistry bindingStreamCodecs;
160 private final BindingToNormalizedNodeCodec bindingToNormalized;
161 private final ModuleInfoBackedContext moduleInfoBackedCntxt;
163 private SchemaContextHolder(boolean fromClasspath) {
164 List<YangModuleInfo> moduleInfos = loadModuleInfos();
165 this.moduleInfoBackedCntxt = ModuleInfoBackedContext.create();
166 this.schemaContext = getSchemaContext(moduleInfos);
167 this.listeners = ListenerRegistry.create();
168 this.bindingStreamCodecs = createBindingRegistry();
169 GeneratedClassLoadingStrategy loading = GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy();
170 this.bindingToNormalized = new BindingToNormalizedNodeCodec(loading, this.bindingStreamCodecs);
171 registerSchemaContextListener(this.bindingToNormalized);
175 public SchemaContext getSchemaContext() {
176 return this.schemaContext;
180 * Get the schemacontext from loaded modules on classpath.
182 * @param moduleInfos a list of Yang module Infos
183 * @return SchemaContext a schema context
185 private SchemaContext getSchemaContext(List<YangModuleInfo> moduleInfos) {
186 this.moduleInfoBackedCntxt.addModuleInfos(moduleInfos);
187 Optional<SchemaContext> tryToCreateSchemaContext =
188 this.moduleInfoBackedCntxt.tryToCreateSchemaContext().toJavaUtil();
189 if (!tryToCreateSchemaContext.isPresent()) {
190 LOG.error("Could not create the initial schema context. Schema context is empty");
191 throw new IllegalStateException();
193 return tryToCreateSchemaContext.get();
197 public SchemaContext getGlobalContext() {
198 return this.schemaContext;
202 public SchemaContext getSessionContext() {
203 return this.schemaContext;
207 public ListenerRegistration<SchemaContextListener> registerSchemaContextListener(
208 SchemaContextListener listener) {
209 return this.listeners.register(listener);
213 * Loads all {@link YangModelBindingProvider} on the classpath.
215 * @return list of known {@link YangModuleInfo}
217 private List<YangModuleInfo> loadModuleInfos() {
218 List<YangModuleInfo> moduleInfos = new LinkedList<>();
219 ServiceLoader<YangModelBindingProvider> yangProviderLoader =
220 ServiceLoader.load(YangModelBindingProvider.class);
221 for (YangModelBindingProvider yangModelBindingProvider : yangProviderLoader) {
222 moduleInfos.add(yangModelBindingProvider.getModuleInfo());
223 LOG.debug("Adding [{}] module into known modules", yangModelBindingProvider.getModuleInfo());
229 * Creates binding registry.
231 * @return BindingNormalizedNodeCodecRegistry the resulting binding registry
233 private BindingNormalizedNodeCodecRegistry createBindingRegistry() {
234 BindingRuntimeContext bindingContext = BindingRuntimeContext.create(this.moduleInfoBackedCntxt, this.schemaContext);
235 BindingNormalizedNodeCodecRegistry bindingNormalizedNodeCodecRegistry =
236 new BindingNormalizedNodeCodecRegistry(
237 StreamWriterGenerator.create(JavassistUtils.forClassPool(ClassPool.getDefault())));
238 bindingNormalizedNodeCodecRegistry.onBindingRuntimeContextUpdated(bindingContext);
239 return bindingNormalizedNodeCodecRegistry;
243 * @see org.opendaylight.mdsal.dom.api.DOMExtensibleService#getExtensions()
246 public @NonNull ClassToInstanceMap<DOMSchemaServiceExtension> getExtensions() {
247 // TODO Auto-generated method stub