remove mdsal StreamWriterGenerator
[transportpce.git] / common / src / main / java / org / opendaylight / transportpce / common / DataStoreContextImpl.java
1 /*
2  * Copyright © 2016 AT&T 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.transportpce.common;
9
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;
16 import java.util.Map;
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;
49
50 public class DataStoreContextImpl implements DataStoreContext {
51
52     private static final Logger LOG = LoggerFactory.getLogger(DataStoreContextImpl.class);
53
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;
61
62     public DataStoreContextImpl() {
63         this(false);
64     }
65
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);
77         }
78     }
79
80     @Override
81     public DataBroker getDataBroker() {
82         return this.dataBroker;
83     }
84
85     @Override
86     public DOMDataBroker getDOMDataBroker() {
87         return this.domDataBroker;
88     }
89
90     @Override
91     public NotificationService createNotificationService() {
92         return new BindingDOMNotificationServiceAdapter(this.domNotificationRouter,
93                 this.mockedSchemaContext.bindingStreamCodecs);
94     }
95
96     @Override
97     public NotificationPublishService createNotificationPublishService() {
98         return new BindingDOMNotificationPublishServiceAdapter(this.domNotificationRouter,
99                 this.mockedSchemaContext.bindingToNormalized);
100     }
101
102     @Override
103     public SchemaContext getSchemaContext() {
104         return this.mockedSchemaContext.schemaContext;
105     }
106
107     @Override
108     public BindingNormalizedNodeCodecRegistry getBindingToNormalizedNodeCodec() {
109         return this.mockedSchemaContext.bindingStreamCodecs;
110     }
111
112     @Override
113     public NotificationService getNotificationService() {
114         return this.notificationService;
115     }
116
117     @Override
118     public NotificationPublishService getNotificationPublishService() {
119         return this.notificationPublishService;
120     }
121
122     private DOMDataBroker createDOMDataBroker() {
123         return new SerializedDOMDataBroker(this.datastores,
124                 MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor()));
125     }
126
127     private ListeningExecutorService getDataTreeChangeListenerExecutor() {
128         return MoreExecutors.newDirectExecutorService();
129     }
130
131     private DataBroker createDataBroker() {
132         return new BindingDOMDataBrokerAdapter(getDOMDataBroker(), this.mockedSchemaContext.bindingToNormalized);
133     }
134
135     private Map<LogicalDatastoreType, DOMStore> createDatastores() {
136         return ImmutableMap.<LogicalDatastoreType, DOMStore>builder()
137                 .put(LogicalDatastoreType.OPERATIONAL, createOperationalDatastore())
138                 .put(LogicalDatastoreType.CONFIGURATION, createConfigurationDatastore()).build();
139     }
140
141     private DOMStore createConfigurationDatastore() {
142         final InMemoryDOMDataStore store = new InMemoryDOMDataStore("CFG", getDataTreeChangeListenerExecutor());
143         this.mockedSchemaContext.registerSchemaContextListener(store);
144         return store;
145     }
146
147     private DOMStore createOperationalDatastore() {
148         final InMemoryDOMDataStore store = new InMemoryDOMDataStore("OPER", getDataTreeChangeListenerExecutor());
149         this.mockedSchemaContext.registerSchemaContextListener(store);
150         return store;
151     }
152
153     private final class SchemaContextHolder implements DOMSchemaService, SchemaContextProvider {
154
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;
160
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);
170         }
171
172         @Override
173         public SchemaContext getSchemaContext() {
174             return this.schemaContext;
175         }
176
177         /**
178          * Get the schemacontext from loaded modules on classpath.
179          *
180          * @param moduleInfos a list of Yang module Infos
181          * @return SchemaContext a schema context
182          */
183         private SchemaContext getSchemaContext(List<YangModuleInfo> moduleInfos) {
184             this.moduleInfoBackedCntxt.addModuleInfos(moduleInfos);
185             Optional<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();
190             }
191             return tryToCreateSchemaContext.get();
192         }
193
194         @Override
195         public SchemaContext getGlobalContext() {
196             return this.schemaContext;
197         }
198
199         @Override
200         public SchemaContext getSessionContext() {
201             return this.schemaContext;
202         }
203
204         @Override
205         public ListenerRegistration<SchemaContextListener> registerSchemaContextListener(
206                 SchemaContextListener listener) {
207             return this.listeners.register(listener);
208         }
209
210         /**
211          * Loads all {@link YangModelBindingProvider} on the classpath.
212          *
213          * @return list of known {@link YangModuleInfo}
214          */
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());
222             }
223             return moduleInfos;
224         }
225
226         /**
227          * Creates binding registry.
228          *
229          * @return BindingNormalizedNodeCodecRegistry the resulting binding registry
230          */
231         private BindingNormalizedNodeCodecRegistry createBindingRegistry() {
232             BindingRuntimeContext bindingContext =
233                 BindingRuntimeContext.create(this.moduleInfoBackedCntxt, this.schemaContext);
234             BindingNormalizedNodeCodecRegistry bindingNormalizedNodeCodecRegistry =
235                     new BindingNormalizedNodeCodecRegistry(bindingContext);
236             return bindingNormalizedNodeCodecRegistry;
237         }
238
239         /* (non-Javadoc)
240          * @see org.opendaylight.mdsal.dom.api.DOMExtensibleService#getExtensions()
241          */
242         @Override
243         public @NonNull ClassToInstanceMap<DOMSchemaServiceExtension> getExtensions() {
244             // TODO Auto-generated method stub
245             return null;
246         }
247     }
248 }