Migrate common module to Aluminium Step 2
[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.ImmutableClassToInstanceMap;
12 import com.google.common.collect.ImmutableMap;
13 import com.google.common.util.concurrent.ListeningExecutorService;
14 import com.google.common.util.concurrent.MoreExecutors;
15 import java.util.LinkedList;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.ServiceLoader;
19 import java.util.concurrent.Executors;
20 import org.eclipse.jdt.annotation.NonNull;
21 import org.opendaylight.binding.runtime.api.BindingRuntimeContext;
22 import org.opendaylight.binding.runtime.spi.BindingRuntimeHelpers;
23 import org.opendaylight.mdsal.binding.api.DataBroker;
24 import org.opendaylight.mdsal.binding.api.NotificationPublishService;
25 import org.opendaylight.mdsal.binding.api.NotificationService;
26 import org.opendaylight.mdsal.binding.dom.adapter.AdapterContext;
27 import org.opendaylight.mdsal.binding.dom.adapter.BindingDOMDataBrokerAdapter;
28 import org.opendaylight.mdsal.binding.dom.adapter.BindingDOMNotificationPublishServiceAdapter;
29 import org.opendaylight.mdsal.binding.dom.adapter.BindingDOMNotificationServiceAdapter;
30 import org.opendaylight.mdsal.binding.dom.adapter.ConstantAdapterContext;
31 import org.opendaylight.mdsal.binding.dom.adapter.CurrentAdapterSerializer;
32 import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
33 import org.opendaylight.mdsal.binding.dom.codec.impl.BindingCodecContext;
34 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
35 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
36 import org.opendaylight.mdsal.dom.api.DOMSchemaService;
37 import org.opendaylight.mdsal.dom.api.DOMSchemaServiceExtension;
38 import org.opendaylight.mdsal.dom.broker.DOMNotificationRouter;
39 import org.opendaylight.mdsal.dom.broker.SerializedDOMDataBroker;
40 import org.opendaylight.mdsal.dom.spi.store.DOMStore;
41 import org.opendaylight.mdsal.dom.store.inmemory.InMemoryDOMDataStore;
42 import org.opendaylight.yangtools.concepts.ListenerRegistration;
43 import org.opendaylight.yangtools.util.ListenerRegistry;
44 import org.opendaylight.yangtools.yang.binding.YangModelBindingProvider;
45 import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
46 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
47 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContextListener;
48 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContextProvider;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
51
52 public class DataStoreContextImpl implements DataStoreContext {
53
54     private static final Logger LOG = LoggerFactory.getLogger(DataStoreContextImpl.class);
55
56     private final Map<LogicalDatastoreType, DOMStore> datastores;
57     private final SchemaContextHolder mockedSchemaContext;
58     private final DOMNotificationRouter domNotificationRouter;
59     private final DOMDataBroker domDataBroker;
60     private final DataBroker dataBroker;
61     private final NotificationService notificationService;
62     private final NotificationPublishService notificationPublishService;
63
64
65     public DataStoreContextImpl() {
66         this.mockedSchemaContext = new SchemaContextHolder();
67         this.datastores = createDatastores();
68         this.domNotificationRouter = DOMNotificationRouter.create(16);
69         this.domDataBroker = createDOMDataBroker();
70         this.dataBroker = createDataBroker();
71         this.notificationService = createNotificationService();
72         this.notificationPublishService = createNotificationPublishService();
73         this.mockedSchemaContext.listeners.streamListeners()
74             .forEach(l -> l.onModelContextUpdated(this.mockedSchemaContext.schemaContext));
75     }
76
77     @Override
78     public DataBroker getDataBroker() {
79         return this.dataBroker;
80     }
81
82     @Override
83     public DOMDataBroker getDOMDataBroker() {
84         return this.domDataBroker;
85     }
86
87     @Override
88     public NotificationService createNotificationService() {
89         return new BindingDOMNotificationServiceAdapter(this.mockedSchemaContext.adapterContext,
90                 this.domNotificationRouter);
91     }
92
93     @Override
94     public NotificationPublishService createNotificationPublishService() {
95         return new BindingDOMNotificationPublishServiceAdapter(this.mockedSchemaContext.adapterContext,
96                 this.domNotificationRouter);
97     }
98
99     @Override
100     public EffectiveModelContext getSchemaContext() {
101         return this.mockedSchemaContext.schemaContext;
102     }
103
104     @Override
105     public BindingNormalizedNodeSerializer getBindingToNormalizedNodeCodec() {
106         return this.mockedSchemaContext.bindingStreamCodecs;
107     }
108
109     @Override
110     public NotificationService getNotificationService() {
111         return this.notificationService;
112     }
113
114     @Override
115     public NotificationPublishService getNotificationPublishService() {
116         return this.notificationPublishService;
117     }
118
119     private DOMDataBroker createDOMDataBroker() {
120         return new SerializedDOMDataBroker(this.datastores,
121                 MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor()));
122     }
123
124     private ListeningExecutorService getDataTreeChangeListenerExecutor() {
125         return MoreExecutors.newDirectExecutorService();
126     }
127
128     private DataBroker createDataBroker() {
129         return new BindingDOMDataBrokerAdapter(this.mockedSchemaContext.adapterContext, getDOMDataBroker());
130     }
131
132     private Map<LogicalDatastoreType, DOMStore> createDatastores() {
133         return ImmutableMap.<LogicalDatastoreType, DOMStore>builder()
134                 .put(LogicalDatastoreType.OPERATIONAL, createOperationalDatastore())
135                 .put(LogicalDatastoreType.CONFIGURATION, createConfigurationDatastore()).build();
136     }
137
138     private DOMStore createConfigurationDatastore() {
139         final InMemoryDOMDataStore store = new InMemoryDOMDataStore("CFG", getDataTreeChangeListenerExecutor());
140         this.mockedSchemaContext.registerSchemaContextListener(store);
141         return store;
142     }
143
144     private DOMStore createOperationalDatastore() {
145         final InMemoryDOMDataStore store = new InMemoryDOMDataStore("OPER", getDataTreeChangeListenerExecutor());
146         this.mockedSchemaContext.registerSchemaContextListener(store);
147         return store;
148     }
149
150     private static final class SchemaContextHolder implements DOMSchemaService, EffectiveModelContextProvider {
151
152         private final EffectiveModelContext schemaContext;
153         private final ListenerRegistry<EffectiveModelContextListener> listeners;
154         private final BindingNormalizedNodeSerializer bindingStreamCodecs;
155         private final CurrentAdapterSerializer bindingToNormalized;
156         private final AdapterContext adapterContext;
157
158         private SchemaContextHolder() {
159             List<YangModuleInfo> moduleInfos = loadModuleInfos();
160             this.schemaContext = BindingRuntimeHelpers.createEffectiveModel(moduleInfos);
161             this.listeners = ListenerRegistry.create();
162             BindingRuntimeContext bindingContext =
163                     BindingRuntimeHelpers.createRuntimeContext();
164             this.bindingStreamCodecs = new BindingCodecContext(bindingContext);
165             this.bindingToNormalized = new CurrentAdapterSerializer(new BindingCodecContext(bindingContext));
166             adapterContext = new ConstantAdapterContext(this.bindingToNormalized);
167         }
168
169         @Override
170         public EffectiveModelContext getGlobalContext() {
171             return this.schemaContext;
172         }
173
174
175         /**
176          * Loads all {@link YangModelBindingProvider} on the classpath.
177          *
178          * @return list of known {@link YangModuleInfo}
179          */
180         private List<YangModuleInfo> loadModuleInfos() {
181             List<YangModuleInfo> moduleInfos = new LinkedList<>();
182             ServiceLoader<YangModelBindingProvider> yangProviderLoader =
183                     ServiceLoader.load(YangModelBindingProvider.class);
184             for (YangModelBindingProvider yangModelBindingProvider : yangProviderLoader) {
185                 moduleInfos.add(yangModelBindingProvider.getModuleInfo());
186                 LOG.debug("Adding [{}] module into known modules", yangModelBindingProvider.getModuleInfo());
187             }
188             return moduleInfos;
189         }
190
191         @Override
192         public ListenerRegistration<EffectiveModelContextListener> registerSchemaContextListener(
193                 EffectiveModelContextListener listener) {
194             return this.listeners.register(listener);
195         }
196
197         @Override
198         public @NonNull EffectiveModelContext getEffectiveModelContext() {
199             return this.schemaContext;
200         }
201
202         @Override
203         public @NonNull ClassToInstanceMap<DOMSchemaServiceExtension> getExtensions() {
204             return ImmutableClassToInstanceMap.of();
205         }
206
207
208     }
209 }