Merge "Revert "Revert "BUG-1425: Integrated new Binding to Normalized Node codec...
[controller.git] / opendaylight / md-sal / sal-binding-broker / src / test / java / org / opendaylight / controller / sal / binding / test / util / BindingTestContext.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. 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.controller.sal.binding.test.util;
9
10 import static com.google.common.base.Preconditions.checkState;
11
12 import com.google.common.annotations.Beta;
13 import com.google.common.collect.ClassToInstanceMap;
14 import com.google.common.collect.ImmutableClassToInstanceMap;
15 import com.google.common.collect.ImmutableMap;
16 import com.google.common.collect.ImmutableSet;
17 import com.google.common.collect.MutableClassToInstanceMap;
18 import com.google.common.util.concurrent.ListeningExecutorService;
19 import com.google.common.util.concurrent.MoreExecutors;
20 import java.util.Set;
21 import java.util.concurrent.Future;
22 import javassist.ClassPool;
23 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
24 import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
25 import org.opendaylight.controller.md.sal.binding.impl.ForwardedBackwardsCompatibleDataBroker;
26 import org.opendaylight.controller.md.sal.binding.impl.ForwardedBindingDataBroker;
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.DOMDataBrokerImpl;
30 import org.opendaylight.controller.md.sal.dom.broker.impl.compat.BackwardsCompatibleDataBroker;
31 import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
32 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
33 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
34 import org.opendaylight.controller.sal.binding.api.mount.MountProviderService;
35 import org.opendaylight.controller.sal.binding.impl.DataBrokerImpl;
36 import org.opendaylight.controller.sal.binding.impl.NotificationBrokerImpl;
37 import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl;
38 import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingDomConnectorDeployer;
39 import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector;
40 import org.opendaylight.controller.sal.binding.impl.forward.DomForwardedBindingBrokerImpl;
41 import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
42 import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration;
43 import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration;
44 import org.opendaylight.controller.sal.core.api.BrokerService;
45 import org.opendaylight.controller.sal.core.api.RpcImplementation;
46 import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
47 import org.opendaylight.controller.sal.core.api.RpcRegistrationListener;
48 import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
49 import org.opendaylight.controller.sal.core.spi.data.DOMStore;
50 import org.opendaylight.controller.sal.dom.broker.BrokerImpl;
51 import org.opendaylight.controller.sal.dom.broker.MountPointManagerImpl;
52 import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareRpcBroker;
53 import org.opendaylight.yangtools.binding.data.codec.gen.impl.DataObjectSerializerGenerator;
54 import org.opendaylight.yangtools.binding.data.codec.gen.impl.StreamWriterGenerator;
55 import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry;
56 import org.opendaylight.yangtools.concepts.ListenerRegistration;
57 import org.opendaylight.yangtools.sal.binding.generator.impl.GeneratedClassLoadingStrategy;
58 import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext;
59 import org.opendaylight.yangtools.sal.binding.generator.impl.RuntimeGeneratedMappingServiceImpl;
60 import org.opendaylight.yangtools.sal.binding.generator.util.JavassistUtils;
61 import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
62 import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
63 import org.opendaylight.yangtools.yang.common.QName;
64 import org.opendaylight.yangtools.yang.common.RpcResult;
65 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
66 import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
67 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
68 import org.slf4j.Logger;
69 import org.slf4j.LoggerFactory;
70
71 @Beta
72 public class BindingTestContext implements AutoCloseable {
73
74     public static final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier TREE_ROOT = org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier
75             .builder().toInstance();
76
77     private static final Logger LOG = LoggerFactory.getLogger(BindingTestContext.class);
78
79     private RuntimeGeneratedMappingServiceImpl mappingServiceImpl;
80     private BindingToNormalizedNodeCodec codec;
81
82     private DomForwardedBindingBrokerImpl baBrokerImpl;
83     private DataBrokerImpl baDataImpl;
84     private NotificationBrokerImpl baNotifyImpl;
85     private BindingIndependentConnector baConnectImpl;
86
87     private org.opendaylight.controller.sal.dom.broker.DataBrokerImpl biDataImpl;
88     @SuppressWarnings("deprecation")
89     private org.opendaylight.controller.sal.core.api.data.DataProviderService biDataLegacyBroker;
90     private BrokerImpl biBrokerImpl;
91
92     private final ListeningExecutorService executor;
93     private final ClassPool classPool;
94
95     private final boolean startWithSchema;
96
97     private MountPointManagerImpl biMountImpl;
98
99
100
101     private ImmutableMap<LogicalDatastoreType, DOMStore> newDatastores;
102
103     private BackwardsCompatibleDataBroker biCompatibleBroker;
104
105     @SuppressWarnings("deprecation")
106     private DataProviderService baData;
107
108     private DOMDataBroker newDOMDataBroker;
109
110     private final MockSchemaService mockSchemaService = new MockSchemaService();
111
112     private DataBroker dataBroker;
113
114
115
116     public DOMDataBroker getDomAsyncDataBroker() {
117         return newDOMDataBroker;
118     }
119
120     protected BindingTestContext(final ListeningExecutorService executor, final ClassPool classPool, final boolean startWithSchema) {
121         this.executor = executor;
122         this.classPool = classPool;
123         this.startWithSchema = startWithSchema;
124     }
125
126     public void startDomDataBroker() {
127         checkState(executor != null, "Executor needs to be set");
128         biDataImpl = new org.opendaylight.controller.sal.dom.broker.DataBrokerImpl();
129         biDataImpl.setExecutor(executor);
130         biDataLegacyBroker = biDataImpl;
131     }
132
133     public void startNewDataBroker() {
134         checkState(executor != null, "Executor needs to be set");
135         checkState(newDOMDataBroker != null, "DOM Data Broker must be set");
136         dataBroker = new ForwardedBindingDataBroker(newDOMDataBroker, codec, mockSchemaService);
137     }
138
139     public void startNewDomDataBroker() {
140         checkState(executor != null, "Executor needs to be set");
141         InMemoryDOMDataStore operStore = new InMemoryDOMDataStore("OPER", executor,
142                 MoreExecutors.sameThreadExecutor());
143         InMemoryDOMDataStore configStore = new InMemoryDOMDataStore("CFG", executor,
144                 MoreExecutors.sameThreadExecutor());
145         newDatastores = ImmutableMap.<LogicalDatastoreType, DOMStore>builder()
146                 .put(LogicalDatastoreType.OPERATIONAL, operStore)
147                 .put(LogicalDatastoreType.CONFIGURATION, configStore)
148                 .build();
149
150         newDOMDataBroker = new DOMDataBrokerImpl(newDatastores, executor);
151
152         biCompatibleBroker = new BackwardsCompatibleDataBroker(newDOMDataBroker,mockSchemaService);
153
154         mockSchemaService.registerSchemaContextListener(configStore);
155         mockSchemaService.registerSchemaContextListener(operStore);
156         biDataLegacyBroker = biCompatibleBroker;
157     }
158
159     public void startBindingDataBroker() {
160         checkState(executor != null, "Executor needs to be set");
161         baDataImpl = new DataBrokerImpl();
162         baDataImpl.setExecutor(executor);
163         baData = baDataImpl;
164     }
165
166     public void startBindingBroker() {
167         checkState(executor != null, "Executor needs to be set");
168         checkState(baData != null, "Binding Data Broker must be started");
169         checkState(baNotifyImpl != null, "Notification Service must be started");
170         baBrokerImpl = new DomForwardedBindingBrokerImpl("test");
171
172         baBrokerImpl.getMountManager().setDataCommitExecutor(executor);
173         baBrokerImpl.getMountManager().setNotificationExecutor(executor);
174         baBrokerImpl.setRpcBroker(new RpcProviderRegistryImpl("test"));
175         baBrokerImpl.setLegacyDataBroker(baData);
176         baBrokerImpl.setNotificationBroker(baNotifyImpl);
177         baBrokerImpl.start();
178     }
179
180     public void startForwarding() {
181         checkState(baData != null, "Binding Data Broker needs to be started");
182         checkState(biDataLegacyBroker != null, "DOM Data Broker needs to be started.");
183         checkState(mappingServiceImpl != null, "DOM Mapping Service needs to be started.");
184
185         baConnectImpl = BindingDomConnectorDeployer.createConnector(getBindingToDomMappingService());
186         baConnectImpl.setDomRpcRegistry(getDomRpcRegistry());
187         baBrokerImpl.setConnector(baConnectImpl);
188         baBrokerImpl.setDomProviderContext(createMockContext());
189         baBrokerImpl.startForwarding();
190     }
191
192     private ProviderSession createMockContext() {
193
194         @SuppressWarnings("deprecation")
195         final ClassToInstanceMap<BrokerService> domBrokerServices = ImmutableClassToInstanceMap
196                 .<BrokerService> builder()
197                 //
198                 .put(org.opendaylight.controller.sal.core.api.data.DataProviderService.class, biDataLegacyBroker) //
199                 .put(RpcProvisionRegistry.class, biBrokerImpl.getRouter()) //
200                 .put(MountProvisionService.class, biMountImpl) //
201                 .build();
202
203         return new ProviderSession() {
204
205             @Override
206             public Future<RpcResult<CompositeNode>> rpc(final QName rpc, final CompositeNode input) {
207                 throw new UnsupportedOperationException();
208             }
209
210             @Override
211             public <T extends BrokerService> T getService(final Class<T> service) {
212                 return domBrokerServices.getInstance(service);
213             }
214
215             @Override
216             public boolean isClosed() {
217                 return false;
218             }
219
220             @Override
221             public Set<QName> getSupportedRpcs() {
222                 return null;
223             }
224
225             @Override
226             public void close() {
227             }
228
229             @Override
230             public ListenerRegistration<RpcRegistrationListener> addRpcRegistrationListener(
231                     final RpcRegistrationListener listener) {
232                 return null;
233             }
234
235             @Override
236             public RpcRegistration addRpcImplementation(final QName rpcType, final RpcImplementation implementation)
237                     throws IllegalArgumentException {
238                 return null;
239             }
240
241             @Override
242             public RoutedRpcRegistration addRoutedRpcImplementation(final QName rpcType, final RpcImplementation implementation) {
243                 return null;
244             }
245
246             @Override
247             public RoutedRpcRegistration addMountedRpcImplementation(final QName rpcType, final RpcImplementation implementation) {
248                 return null;
249             }
250         };
251     }
252
253     public void startBindingToDomMappingService() {
254         checkState(classPool != null, "ClassPool needs to be present");
255         mappingServiceImpl = new RuntimeGeneratedMappingServiceImpl(classPool);
256         mockSchemaService.registerSchemaContextListener(mappingServiceImpl);
257
258         DataObjectSerializerGenerator generator = StreamWriterGenerator.create(JavassistUtils.forClassPool(classPool));
259         BindingNormalizedNodeCodecRegistry codecRegistry = new BindingNormalizedNodeCodecRegistry(generator);
260         GeneratedClassLoadingStrategy loading = GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy();
261         codec = new BindingToNormalizedNodeCodec(loading, mappingServiceImpl, codecRegistry);
262         mockSchemaService.registerSchemaContextListener(codec);
263     }
264
265     private void updateYangSchema(final ImmutableSet<YangModuleInfo> moduleInfos) {
266         mockSchemaService.changeSchema(getContext(moduleInfos));
267     }
268
269     private SchemaContext getContext(final ImmutableSet<YangModuleInfo> moduleInfos) {
270         ModuleInfoBackedContext ctx = ModuleInfoBackedContext.create();
271         ctx.addModuleInfos(moduleInfos);
272         return ctx.tryToCreateSchemaContext().get();
273     }
274
275     public void start() {
276         startNewDomDataBroker();
277
278         startDomBroker();
279         startDomMountPoint();
280         startBindingToDomMappingService();
281         startNewDataBroker();
282         startNewBindingDataBroker();
283         startBindingNotificationBroker();
284         startBindingBroker();
285
286         startForwarding();
287         if (startWithSchema) {
288             loadYangSchemaFromClasspath();
289         }
290     }
291
292     public void startNewBindingDataBroker() {
293         ForwardedBackwardsCompatibleDataBroker forwarded = new ForwardedBackwardsCompatibleDataBroker(newDOMDataBroker, codec,mockSchemaService, executor);
294         baData = forwarded;
295     }
296
297     private void startDomMountPoint() {
298         biMountImpl = new MountPointManagerImpl();
299         biMountImpl.setDataBroker(getDomDataBroker());
300     }
301
302     private void startDomBroker() {
303         checkState(executor != null);
304
305         SchemaAwareRpcBroker router = new SchemaAwareRpcBroker("/", mockSchemaService);
306         ClassToInstanceMap<BrokerService> services = MutableClassToInstanceMap.create();
307         biBrokerImpl = new BrokerImpl(router,services);
308
309     }
310
311     public void startBindingNotificationBroker() {
312         checkState(executor != null);
313         baNotifyImpl = new NotificationBrokerImpl(executor);
314
315     }
316
317     public void loadYangSchemaFromClasspath() {
318         ImmutableSet<YangModuleInfo> moduleInfos = BindingReflections.loadModuleInfos();
319         updateYangSchema(moduleInfos);
320     }
321
322     @SuppressWarnings("deprecation")
323     public DataProviderService getBindingDataBroker() {
324         return baData;
325     }
326
327     @SuppressWarnings("deprecation")
328     public org.opendaylight.controller.sal.core.api.data.DataProviderService getDomDataBroker() {
329         return biDataLegacyBroker;
330     }
331
332     public BindingIndependentMappingService getBindingToDomMappingService() {
333         return mappingServiceImpl;
334     }
335
336     public RpcProviderRegistry getBindingRpcRegistry() {
337         return baBrokerImpl.getRoot();
338     }
339
340     public RpcProvisionRegistry getDomRpcRegistry() {
341         if (biBrokerImpl == null) {
342             return null;
343         }
344         return biBrokerImpl.getRouter();
345     }
346
347     public RpcImplementation getDomRpcInvoker() {
348         return biBrokerImpl.getRouter();
349     }
350
351     @Override
352     public void close() throws Exception {
353
354     }
355
356     public MountProviderService getBindingMountProviderService() {
357         return baBrokerImpl.getMountManager();
358     }
359
360     public MountProvisionService getDomMountProviderService() {
361         return biMountImpl;
362     }
363
364     public DataBroker getDataBroker() {
365         return dataBroker;
366     }
367
368
369 }