Merge "Add netconf-cli temporary files to .gitignore"
[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 java.io.InputStream;
13 import java.util.ArrayList;
14 import java.util.List;
15 import java.util.Set;
16 import java.util.concurrent.Future;
17
18 import javassist.ClassPool;
19
20 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
21 import org.opendaylight.controller.md.sal.binding.impl.ForwardedBackwardsCompatibleDataBroker;
22 import org.opendaylight.controller.md.sal.binding.impl.ForwardedBindingDataBroker;
23 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
24 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
25 import org.opendaylight.controller.md.sal.dom.broker.impl.DOMDataBrokerImpl;
26 import org.opendaylight.controller.md.sal.dom.broker.impl.compat.BackwardsCompatibleDataBroker;
27 import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
28 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
29 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
30 import org.opendaylight.controller.sal.binding.api.mount.MountProviderService;
31 import org.opendaylight.controller.sal.binding.impl.DataBrokerImpl;
32 import org.opendaylight.controller.sal.binding.impl.NotificationBrokerImpl;
33 import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl;
34 import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingDomConnectorDeployer;
35 import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector;
36 import org.opendaylight.controller.sal.binding.impl.forward.DomForwardedBindingBrokerImpl;
37 import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
38 import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration;
39 import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration;
40 import org.opendaylight.controller.sal.core.api.BrokerService;
41 import org.opendaylight.controller.sal.core.api.RpcImplementation;
42 import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
43 import org.opendaylight.controller.sal.core.api.RpcRegistrationListener;
44 import org.opendaylight.controller.sal.core.api.data.DataStore;
45 import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
46 import org.opendaylight.controller.sal.core.spi.data.DOMStore;
47 import org.opendaylight.controller.sal.dom.broker.BrokerImpl;
48 import org.opendaylight.controller.sal.dom.broker.MountPointManagerImpl;
49 import org.opendaylight.controller.sal.dom.broker.impl.DataStoreStatsWrapper;
50 import org.opendaylight.controller.sal.dom.broker.impl.HashMapDataStore;
51 import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareDataStoreAdapter;
52 import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareRpcBroker;
53 import org.opendaylight.yangtools.concepts.ListenerRegistration;
54 import org.opendaylight.yangtools.sal.binding.generator.impl.RuntimeGeneratedMappingServiceImpl;
55 import org.opendaylight.yangtools.yang.common.QName;
56 import org.opendaylight.yangtools.yang.common.RpcResult;
57 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
58 import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
59 import org.opendaylight.yangtools.yang.model.api.Module;
60 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
61 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
62 import org.reflections.Reflections;
63 import org.reflections.scanners.ResourcesScanner;
64 import org.slf4j.Logger;
65 import org.slf4j.LoggerFactory;
66
67 import com.google.common.base.Predicate;
68 import com.google.common.collect.ClassToInstanceMap;
69 import com.google.common.collect.ImmutableClassToInstanceMap;
70 import com.google.common.collect.ImmutableMap;
71 import com.google.common.collect.MutableClassToInstanceMap;
72 import com.google.common.util.concurrent.ListeningExecutorService;
73
74 public class BindingTestContext implements AutoCloseable {
75
76     public static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier TREE_ROOT = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
77             .builder().toInstance();
78
79     private static final Logger LOG = LoggerFactory.getLogger(BindingTestContext.class);
80
81     private RuntimeGeneratedMappingServiceImpl mappingServiceImpl;
82
83     private DomForwardedBindingBrokerImpl baBrokerImpl;
84     private DataBrokerImpl baDataImpl;
85     private NotificationBrokerImpl baNotifyImpl;
86     private BindingIndependentConnector baConnectImpl;
87
88     private org.opendaylight.controller.sal.dom.broker.DataBrokerImpl biDataImpl;
89     private org.opendaylight.controller.sal.core.api.data.DataProviderService biDataLegacyBroker;
90     private BrokerImpl biBrokerImpl;
91     private HashMapDataStore rawDataStore;
92     private SchemaAwareDataStoreAdapter schemaAwareDataStore;
93     private DataStoreStatsWrapper dataStoreStats;
94     private DataStore dataStore;
95
96     private final boolean dataStoreStatisticsEnabled = false;
97
98     private final ListeningExecutorService executor;
99     private final ClassPool classPool;
100
101     private final boolean startWithSchema;
102
103     private MountPointManagerImpl biMountImpl;
104
105
106
107     private ImmutableMap<LogicalDatastoreType, DOMStore> newDatastores;
108
109     private BackwardsCompatibleDataBroker biCompatibleBroker;
110
111     private DataProviderService baData;
112
113     private DOMDataBroker newDOMDataBroker;
114
115     private final MockSchemaService mockSchemaService = new MockSchemaService();
116
117     private DataBroker dataBroker;
118
119
120
121     public DOMDataBroker getDomAsyncDataBroker() {
122         return newDOMDataBroker;
123     }
124
125     protected BindingTestContext(final ListeningExecutorService executor, final ClassPool classPool, final boolean startWithSchema) {
126         this.executor = executor;
127         this.classPool = classPool;
128         this.startWithSchema = startWithSchema;
129     }
130
131     @Deprecated
132     public void startDomDataStore() {
133         checkState(dataStore == null, "DataStore already started.");
134         checkState(biDataImpl != null, "Dom Data Broker not present");
135         rawDataStore = new HashMapDataStore();
136         schemaAwareDataStore = new SchemaAwareDataStoreAdapter();
137         schemaAwareDataStore.changeDelegate(rawDataStore);
138         if (dataStoreStatisticsEnabled) {
139             dataStoreStats = new DataStoreStatsWrapper(schemaAwareDataStore);
140             dataStore = dataStoreStats;
141         } else {
142             dataStore = schemaAwareDataStore;
143         }
144         mockSchemaService.registerSchemaServiceListener(schemaAwareDataStore);
145         biDataImpl.registerConfigurationReader(TREE_ROOT, dataStore);
146         biDataImpl.registerOperationalReader(TREE_ROOT, dataStore);
147         biDataImpl.registerCommitHandler(TREE_ROOT, dataStore);
148     }
149
150     public void startDomDataBroker() {
151         checkState(executor != null, "Executor needs to be set");
152         biDataImpl = new org.opendaylight.controller.sal.dom.broker.DataBrokerImpl();
153         biDataImpl.setExecutor(executor);
154         biDataLegacyBroker = biDataImpl;
155     }
156
157     public void startNewDataBroker() {
158         checkState(executor != null, "Executor needs to be set");
159         checkState(newDOMDataBroker != null, "DOM Data Broker must be set");
160         dataBroker = new ForwardedBindingDataBroker(newDOMDataBroker, mappingServiceImpl, mockSchemaService);
161     }
162
163     public void startNewDomDataBroker() {
164         checkState(executor != null, "Executor needs to be set");
165         InMemoryDOMDataStore operStore = new InMemoryDOMDataStore("OPER", executor);
166         InMemoryDOMDataStore configStore = new InMemoryDOMDataStore("CFG", executor);
167         newDatastores = ImmutableMap.<LogicalDatastoreType, DOMStore>builder()
168                 .put(LogicalDatastoreType.OPERATIONAL, operStore)
169                 .put(LogicalDatastoreType.CONFIGURATION, configStore)
170                 .build();
171
172         newDOMDataBroker = new DOMDataBrokerImpl(newDatastores, executor);
173
174         biCompatibleBroker = new BackwardsCompatibleDataBroker(newDOMDataBroker,mockSchemaService);
175
176         mockSchemaService.registerSchemaServiceListener(configStore);
177         mockSchemaService.registerSchemaServiceListener(operStore);
178         biDataLegacyBroker = biCompatibleBroker;
179     }
180
181     public void startBindingDataBroker() {
182         checkState(executor != null, "Executor needs to be set");
183         baDataImpl = new DataBrokerImpl();
184         baDataImpl.setExecutor(executor);
185         baData = baDataImpl;
186     }
187
188     public void startBindingBroker() {
189         checkState(executor != null, "Executor needs to be set");
190         checkState(baData != null, "Binding Data Broker must be started");
191         checkState(baNotifyImpl != null, "Notification Service must be started");
192         baBrokerImpl = new DomForwardedBindingBrokerImpl("test");
193
194         baBrokerImpl.getMountManager().setDataCommitExecutor(executor);
195         baBrokerImpl.getMountManager().setNotificationExecutor(executor);
196         baBrokerImpl.setRpcBroker(new RpcProviderRegistryImpl("test"));
197         baBrokerImpl.setLegacyDataBroker(baData);
198         baBrokerImpl.setNotificationBroker(baNotifyImpl);
199         baBrokerImpl.start();
200     }
201
202     public void startForwarding() {
203         checkState(baData != null, "Binding Data Broker needs to be started");
204         checkState(biDataLegacyBroker != null, "DOM Data Broker needs to be started.");
205         checkState(mappingServiceImpl != null, "DOM Mapping Service needs to be started.");
206
207         baConnectImpl = BindingDomConnectorDeployer.createConnector(getBindingToDomMappingService());
208         baConnectImpl.setDomRpcRegistry(getDomRpcRegistry());
209         baBrokerImpl.setConnector(baConnectImpl);
210         baBrokerImpl.setDomProviderContext(createMockContext());
211         baBrokerImpl.startForwarding();
212     }
213
214     private ProviderSession createMockContext() {
215
216         final ClassToInstanceMap<BrokerService> domBrokerServices = ImmutableClassToInstanceMap
217                 .<BrokerService> builder()
218                 //
219                 .put(org.opendaylight.controller.sal.core.api.data.DataProviderService.class, biDataLegacyBroker) //
220                 .put(RpcProvisionRegistry.class, biBrokerImpl.getRouter()) //
221                 .put(MountProvisionService.class, biMountImpl) //
222                 .build();
223
224         return new ProviderSession() {
225
226             @Override
227             public Future<RpcResult<CompositeNode>> rpc(final QName rpc, final CompositeNode input) {
228                 throw new UnsupportedOperationException();
229             }
230
231             @Override
232             public <T extends BrokerService> T getService(final Class<T> service) {
233                 return domBrokerServices.getInstance(service);
234             }
235
236             @Override
237             public boolean isClosed() {
238                 return false;
239             }
240
241             @Override
242             public Set<QName> getSupportedRpcs() {
243                 return null;
244             }
245
246             @Override
247             public void close() {
248             }
249
250             @Override
251             public ListenerRegistration<RpcRegistrationListener> addRpcRegistrationListener(
252                     final RpcRegistrationListener listener) {
253                 return null;
254             }
255
256             @Override
257             public RpcRegistration addRpcImplementation(final QName rpcType, final RpcImplementation implementation)
258                     throws IllegalArgumentException {
259                 return null;
260             }
261
262             @Override
263             public RoutedRpcRegistration addRoutedRpcImplementation(final QName rpcType, final RpcImplementation implementation) {
264                 return null;
265             }
266
267             @Override
268             public RoutedRpcRegistration addMountedRpcImplementation(final QName rpcType, final RpcImplementation implementation) {
269                 return null;
270             }
271         };
272     }
273
274     public void startBindingToDomMappingService() {
275         checkState(classPool != null, "ClassPool needs to be present");
276         mappingServiceImpl = new RuntimeGeneratedMappingServiceImpl(classPool);
277         mockSchemaService.registerSchemaServiceListener(mappingServiceImpl);
278     }
279
280     public void updateYangSchema(final String[] files) {
281         mockSchemaService.changeSchema(getContext(files));
282     }
283
284     public static String[] getAllYangFilesOnClasspath() {
285         Predicate<String> predicate = new Predicate<String>() {
286             @Override
287             public boolean apply(final String input) {
288                 return input.endsWith(".yang");
289             }
290         };
291         Reflections reflection = new Reflections("META-INF.yang", new ResourcesScanner());
292         Set<String> result = reflection.getResources(predicate);
293         return result.toArray(new String[result.size()]);
294     }
295
296     private static SchemaContext getContext(final String[] yangFiles) {
297         ClassLoader loader = BindingTestContext.class.getClassLoader();
298         List<InputStream> streams = new ArrayList<>();
299         for (String string : yangFiles) {
300             InputStream stream = loader.getResourceAsStream(string);
301             streams.add(stream);
302         }
303         YangParserImpl parser = new YangParserImpl();
304         Set<Module> modules = parser.parseYangModelsFromStreams(streams);
305         return parser.resolveSchemaContext(modules);
306     }
307
308     public void startLegacy() {
309         startBindingDataBroker();
310         startBindingNotificationBroker();
311         startBindingBroker();
312         startDomDataBroker();
313         startDomDataStore();
314         startDomBroker();
315         startDomMountPoint();
316         startBindingToDomMappingService();
317         startForwarding();
318         if (startWithSchema) {
319             loadYangSchemaFromClasspath();
320         }
321     }
322
323     public void start() {
324         startNewDomDataBroker();
325
326         startDomBroker();
327         startDomMountPoint();
328         startBindingToDomMappingService();
329         startNewDataBroker();
330         startNewBindingDataBroker();
331         startBindingNotificationBroker();
332         startBindingBroker();
333
334         startForwarding();
335         if (startWithSchema) {
336             loadYangSchemaFromClasspath();
337         }
338     }
339
340     public void startNewBindingDataBroker() {
341         ForwardedBackwardsCompatibleDataBroker forwarded = new ForwardedBackwardsCompatibleDataBroker(newDOMDataBroker, mappingServiceImpl,mockSchemaService, executor);
342         baData = forwarded;
343     }
344
345     private void startDomMountPoint() {
346         biMountImpl = new MountPointManagerImpl();
347         biMountImpl.setDataBroker(getDomDataBroker());
348     }
349
350     private void startDomBroker() {
351         checkState(executor != null);
352
353         SchemaAwareRpcBroker router = new SchemaAwareRpcBroker("/", mockSchemaService);
354         ClassToInstanceMap<BrokerService> services = MutableClassToInstanceMap.create();
355         biBrokerImpl = new BrokerImpl(router,services);
356
357     }
358
359     public void startBindingNotificationBroker() {
360         checkState(executor != null);
361         baNotifyImpl = new NotificationBrokerImpl(executor);
362
363     }
364
365     public void loadYangSchemaFromClasspath() {
366         String[] files = getAllYangFilesOnClasspath();
367         updateYangSchema(files);
368     }
369
370     public DataProviderService getBindingDataBroker() {
371         return baData;
372     }
373
374     public org.opendaylight.controller.sal.core.api.data.DataProviderService getDomDataBroker() {
375         return biDataLegacyBroker;
376     }
377
378     public DataStore getDomDataStore() {
379         return dataStore;
380     }
381
382     public BindingIndependentMappingService getBindingToDomMappingService() {
383         return mappingServiceImpl;
384     }
385
386     public void logDataStoreStatistics() {
387         if (dataStoreStats == null) {
388             return;
389         }
390
391         LOG.info("BIDataStore Statistics: Configuration Read Count: {} TotalTime: {} ms AverageTime (ns): {} ms",
392                 dataStoreStats.getConfigurationReadCount(), dataStoreStats.getConfigurationReadTotalTime(),
393                 dataStoreStats.getConfigurationReadAverageTime());
394
395         LOG.info("BIDataStore Statistics: Operational Read Count: {} TotalTime: {} ms AverageTime (ns): {} ms",
396                 dataStoreStats.getOperationalReadCount(), dataStoreStats.getOperationalReadTotalTime(),
397                 dataStoreStats.getOperationalReadAverageTime());
398
399         LOG.info("BIDataStore Statistics: Request Commit Count: {} TotalTime: {} ms AverageTime (ns): {} ms",
400                 dataStoreStats.getRequestCommitCount(), dataStoreStats.getRequestCommitTotalTime(),
401                 dataStoreStats.getRequestCommitAverageTime());
402     }
403
404     public RpcProviderRegistry getBindingRpcRegistry() {
405         return baBrokerImpl.getRoot();
406     }
407
408     public RpcProvisionRegistry getDomRpcRegistry() {
409         if (biBrokerImpl == null) {
410             return null;
411         }
412         return biBrokerImpl.getRouter();
413     }
414
415     public RpcImplementation getDomRpcInvoker() {
416         return biBrokerImpl.getRouter();
417     }
418
419     @Override
420     public void close() throws Exception {
421
422     }
423
424     public MountProviderService getBindingMountProviderService() {
425         return baBrokerImpl.getMountManager();
426     }
427
428     public MountProvisionService getDomMountProviderService() {
429         return biMountImpl;
430     }
431
432     public DataBroker getDataBroker() {
433         return dataBroker;
434     }
435
436
437 }