Extract dom-serializer-api|impl from binding-broker-impl
[controller.git] / opendaylight / md-sal / sal-binding-broker / src / test / java / org / opendaylight / controller / sal / binding / test / util / BindingTestContext.java
1 package org.opendaylight.controller.sal.binding.test.util;
2
3 import java.io.InputStream;
4 import java.util.ArrayList;
5 import java.util.List;
6 import java.util.Set;
7 import java.util.concurrent.Future;
8
9 import javassist.ClassPool;
10
11 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
12 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
13 import org.opendaylight.controller.sal.binding.api.mount.MountProviderService;
14 import org.opendaylight.controller.sal.binding.impl.DataBrokerImpl;
15 import org.opendaylight.controller.sal.binding.impl.NotificationBrokerImpl;
16 import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl;
17 import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingDomConnectorDeployer;
18 import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector;
19 import org.opendaylight.controller.sal.binding.impl.forward.DomForwardedBindingBrokerImpl;
20 import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
21 import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration;
22 import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration;
23 import org.opendaylight.controller.sal.core.api.BrokerService;
24 import org.opendaylight.controller.sal.core.api.RpcImplementation;
25 import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
26 import org.opendaylight.controller.sal.core.api.RpcRegistrationListener;
27 import org.opendaylight.controller.sal.core.api.data.DataStore;
28 import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
29 import org.opendaylight.controller.sal.dom.broker.BrokerImpl;
30 import org.opendaylight.controller.sal.dom.broker.MountPointManagerImpl;
31 import org.opendaylight.controller.sal.dom.broker.impl.DataStoreStatsWrapper;
32 import org.opendaylight.controller.sal.dom.broker.impl.HashMapDataStore;
33 import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareDataStoreAdapter;
34 import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareRpcBroker;
35 import org.opendaylight.controller.sal.dom.broker.impl.SchemaContextProvider;
36 import org.opendaylight.yangtools.concepts.ListenerRegistration;
37 import org.opendaylight.yangtools.sal.binding.generator.impl.RuntimeGeneratedMappingServiceImpl;
38 import org.opendaylight.yangtools.yang.common.QName;
39 import org.opendaylight.yangtools.yang.common.RpcResult;
40 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
41 import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
42 import org.opendaylight.yangtools.yang.model.api.Module;
43 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
44 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
45 import org.reflections.Reflections;
46 import org.reflections.scanners.ResourcesScanner;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49
50 import com.google.common.base.Predicate;
51 import com.google.common.collect.ClassToInstanceMap;
52 import com.google.common.collect.ImmutableClassToInstanceMap;
53 import com.google.common.util.concurrent.ListeningExecutorService;
54
55 import static com.google.common.base.Preconditions.*;
56
57 public class BindingTestContext implements AutoCloseable, SchemaContextProvider {
58
59     public static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier TREE_ROOT = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
60             .builder().toInstance();
61
62     private static final Logger LOG = LoggerFactory.getLogger(BindingTestContext.class);
63
64     private RuntimeGeneratedMappingServiceImpl mappingServiceImpl;
65
66     private DomForwardedBindingBrokerImpl baBrokerImpl;
67     private DataBrokerImpl baDataImpl;
68     private NotificationBrokerImpl baNotifyImpl;
69     private BindingIndependentConnector baConnectImpl;
70
71     private org.opendaylight.controller.sal.dom.broker.DataBrokerImpl biDataImpl;
72     private BrokerImpl biBrokerImpl;
73     private HashMapDataStore rawDataStore;
74     private SchemaAwareDataStoreAdapter schemaAwareDataStore;
75     private DataStoreStatsWrapper dataStoreStats;
76     private DataStore dataStore;
77
78     private boolean dataStoreStatisticsEnabled = false;
79
80     private final ListeningExecutorService executor;
81     private final ClassPool classPool;
82
83     private final boolean startWithSchema;
84
85     private MountPointManagerImpl biMountImpl;
86
87     private SchemaContext schemaContext;
88
89     public SchemaContext getSchemaContext() {
90         return schemaContext;
91     }
92
93     protected BindingTestContext(ListeningExecutorService executor, ClassPool classPool, boolean startWithSchema) {
94         this.executor = executor;
95         this.classPool = classPool;
96         this.startWithSchema = startWithSchema;
97     }
98
99     public void startDomDataStore() {
100         checkState(dataStore == null, "DataStore already started.");
101         checkState(biDataImpl != null, "Dom Data Broker not present");
102         rawDataStore = new HashMapDataStore();
103         schemaAwareDataStore = new SchemaAwareDataStoreAdapter();
104         schemaAwareDataStore.changeDelegate(rawDataStore);
105         if (dataStoreStatisticsEnabled) {
106             dataStoreStats = new DataStoreStatsWrapper(schemaAwareDataStore);
107             dataStore = dataStoreStats;
108         } else {
109             dataStore = schemaAwareDataStore;
110         }
111
112         biDataImpl.registerConfigurationReader(TREE_ROOT, dataStore);
113         biDataImpl.registerOperationalReader(TREE_ROOT, dataStore);
114         biDataImpl.registerCommitHandler(TREE_ROOT, dataStore);
115     }
116
117     public void startDomDataBroker() {
118         checkState(executor != null, "Executor needs to be set");
119         biDataImpl = new org.opendaylight.controller.sal.dom.broker.DataBrokerImpl();
120         biDataImpl.setExecutor(executor);
121     }
122
123     public void startBindingDataBroker() {
124         checkState(executor != null, "Executor needs to be set");
125         baDataImpl = new DataBrokerImpl();
126         baDataImpl.setExecutor(executor);
127     }
128
129     public void startBindingBroker() {
130         checkState(executor != null, "Executor needs to be set");
131         checkState(baDataImpl != null, "Binding Data Broker must be started");
132         checkState(baNotifyImpl != null, "Notification Service must be started");
133         baBrokerImpl = new DomForwardedBindingBrokerImpl("test");
134
135         baBrokerImpl.getMountManager().setDataCommitExecutor(executor);
136         baBrokerImpl.getMountManager().setNotificationExecutor(executor);
137         baBrokerImpl.setRpcBroker(new RpcProviderRegistryImpl("test"));
138         baBrokerImpl.setDataBroker(baDataImpl);
139         baBrokerImpl.setNotificationBroker(baNotifyImpl);
140         baBrokerImpl.start();
141     }
142
143     public void startForwarding() {
144         checkState(baDataImpl != null, "Binding Data Broker needs to be started");
145         checkState(biDataImpl != null, "DOM Data Broker needs to be started.");
146         checkState(mappingServiceImpl != null, "DOM Mapping Service needs to be started.");
147
148         baConnectImpl = BindingDomConnectorDeployer.createConnector(getBindingToDomMappingService());
149         baConnectImpl.setDomRpcRegistry(getDomRpcRegistry());
150         baBrokerImpl.setConnector(baConnectImpl);
151         baBrokerImpl.setDomProviderContext(createMockContext());
152         baBrokerImpl.startForwarding();
153     }
154
155     private ProviderSession createMockContext() {
156         // TODO Auto-generated method stub
157         final ClassToInstanceMap<BrokerService> domBrokerServices = ImmutableClassToInstanceMap
158                 .<BrokerService> builder()
159                 //
160                 .put(org.opendaylight.controller.sal.core.api.data.DataProviderService.class, biDataImpl) //
161                 .put(RpcProvisionRegistry.class, biBrokerImpl.getRouter()) //
162                 .put(MountProvisionService.class, biMountImpl) //
163                 .build();
164
165         return new ProviderSession() {
166
167             @Override
168             public Future<RpcResult<CompositeNode>> rpc(QName rpc, CompositeNode input) {
169                 throw new UnsupportedOperationException();
170             }
171
172             @Override
173             public <T extends BrokerService> T getService(Class<T> service) {
174                 return domBrokerServices.getInstance(service);
175             }
176
177             @Override
178             public boolean isClosed() {
179                 return false;
180             }
181
182             @Override
183             public Set<QName> getSupportedRpcs() {
184                 return null;
185             }
186
187             @Override
188             public void close() {
189             }
190
191             @Override
192             public ListenerRegistration<RpcRegistrationListener> addRpcRegistrationListener(
193                     RpcRegistrationListener listener) {
194                 return null;
195             }
196
197             @Override
198             public RpcRegistration addRpcImplementation(QName rpcType, RpcImplementation implementation)
199                     throws IllegalArgumentException {
200                 return null;
201             }
202
203             @Override
204             public RoutedRpcRegistration addRoutedRpcImplementation(QName rpcType, RpcImplementation implementation) {
205                 return null;
206             }
207
208             @Override
209             public RoutedRpcRegistration addMountedRpcImplementation(QName rpcType, RpcImplementation implementation) {
210                 return null;
211             }
212         };
213     }
214
215     public void startBindingToDomMappingService() {
216         checkState(classPool != null, "ClassPool needs to be present");
217         mappingServiceImpl = new RuntimeGeneratedMappingServiceImpl();
218         mappingServiceImpl.setPool(classPool);
219         mappingServiceImpl.init();
220     }
221
222     public void updateYangSchema(String[] files) {
223         schemaContext = getContext(files);
224         if (schemaAwareDataStore != null) {
225             schemaAwareDataStore.onGlobalContextUpdated(schemaContext);
226         }
227         if (mappingServiceImpl != null) {
228             mappingServiceImpl.onGlobalContextUpdated(schemaContext);
229         }
230     }
231
232     public static String[] getAllYangFilesOnClasspath() {
233         Predicate<String> predicate = new Predicate<String>() {
234             @Override
235             public boolean apply(String input) {
236                 return input.endsWith(".yang");
237             }
238         };
239         Reflections reflection = new Reflections("META-INF.yang", new ResourcesScanner());
240         Set<String> result = reflection.getResources(predicate);
241         return (String[]) result.toArray(new String[result.size()]);
242     }
243
244     private static SchemaContext getContext(String[] yangFiles) {
245         ClassLoader loader = BindingTestContext.class.getClassLoader();
246         List<InputStream> streams = new ArrayList<>();
247         for (String string : yangFiles) {
248             InputStream stream = loader.getResourceAsStream(string);
249             streams.add(stream);
250         }
251         YangParserImpl parser = new YangParserImpl();
252         Set<Module> modules = parser.parseYangModelsFromStreams(streams);
253         return parser.resolveSchemaContext(modules);
254     }
255
256     public void start() {
257         startBindingDataBroker();
258         startBindingNotificationBroker();
259         startBindingBroker();
260         startDomDataBroker();
261         startDomDataStore();
262         startDomBroker();
263         startDomMountPoint();
264         startBindingToDomMappingService();
265         startForwarding();
266         if (startWithSchema) {
267             loadYangSchemaFromClasspath();
268         }
269     }
270
271     private void startDomMountPoint() {
272         biMountImpl = new MountPointManagerImpl();
273         biMountImpl.setDataBroker(getDomDataBroker());
274     }
275
276     private void startDomBroker() {
277         checkState(executor != null);
278         biBrokerImpl = new BrokerImpl();
279         biBrokerImpl.setExecutor(executor);
280         biBrokerImpl.setRouter(new SchemaAwareRpcBroker("/", this));
281     }
282
283     public void startBindingNotificationBroker() {
284         checkState(executor != null);
285         baNotifyImpl = new NotificationBrokerImpl(executor);
286
287     }
288
289     public void loadYangSchemaFromClasspath() {
290         String[] files = getAllYangFilesOnClasspath();
291         updateYangSchema(files);
292     }
293
294     public DataProviderService getBindingDataBroker() {
295         return baDataImpl;
296     }
297
298     public org.opendaylight.controller.sal.core.api.data.DataProviderService getDomDataBroker() {
299         return biDataImpl;
300     }
301
302     public DataStore getDomDataStore() {
303         return dataStore;
304     }
305
306     public BindingIndependentMappingService getBindingToDomMappingService() {
307         return mappingServiceImpl;
308     }
309
310     public void logDataStoreStatistics() {
311         if (dataStoreStats == null) {
312             return;
313         }
314
315         LOG.info("BIDataStore Statistics: Configuration Read Count: {} TotalTime: {} ms AverageTime (ns): {} ms",
316                 dataStoreStats.getConfigurationReadCount(), dataStoreStats.getConfigurationReadTotalTime(),
317                 dataStoreStats.getConfigurationReadAverageTime());
318
319         LOG.info("BIDataStore Statistics: Operational Read Count: {} TotalTime: {} ms AverageTime (ns): {} ms",
320                 dataStoreStats.getOperationalReadCount(), dataStoreStats.getOperationalReadTotalTime(),
321                 dataStoreStats.getOperationalReadAverageTime());
322
323         LOG.info("BIDataStore Statistics: Request Commit Count: {} TotalTime: {} ms AverageTime (ns): {} ms",
324                 dataStoreStats.getRequestCommitCount(), dataStoreStats.getRequestCommitTotalTime(),
325                 dataStoreStats.getRequestCommitAverageTime());
326     }
327
328     public RpcProviderRegistry getBindingRpcRegistry() {
329         return baBrokerImpl.getRoot();
330     }
331
332     public RpcProvisionRegistry getDomRpcRegistry() {
333         if (biBrokerImpl == null) {
334             return null;
335         }
336         return biBrokerImpl.getRouter();
337     }
338
339     public RpcImplementation getDomRpcInvoker() {
340         return biBrokerImpl.getRouter();
341     }
342
343     @Override
344     public void close() throws Exception {
345
346     }
347
348     public MountProviderService getBindingMountProviderService() {
349         return baBrokerImpl.getMountManager();
350     }
351
352     public MountProvisionService getDomMountProviderService() {
353         return biMountImpl;
354     }
355 }