2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.controller.sal.binding.test.util;
10 import java.io.InputStream;
11 import java.util.ArrayList;
12 import java.util.List;
14 import java.util.concurrent.Future;
16 import javassist.ClassPool;
18 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
19 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
20 import org.opendaylight.controller.sal.binding.api.mount.MountProviderService;
21 import org.opendaylight.controller.sal.binding.impl.DataBrokerImpl;
22 import org.opendaylight.controller.sal.binding.impl.NotificationBrokerImpl;
23 import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl;
24 import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingDomConnectorDeployer;
25 import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector;
26 import org.opendaylight.controller.sal.binding.impl.forward.DomForwardedBindingBrokerImpl;
27 import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
28 import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration;
29 import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration;
30 import org.opendaylight.controller.sal.core.api.BrokerService;
31 import org.opendaylight.controller.sal.core.api.RpcImplementation;
32 import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
33 import org.opendaylight.controller.sal.core.api.RpcRegistrationListener;
34 import org.opendaylight.controller.sal.core.api.data.DataStore;
35 import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
36 import org.opendaylight.controller.sal.dom.broker.BrokerImpl;
37 import org.opendaylight.controller.sal.dom.broker.MountPointManagerImpl;
38 import org.opendaylight.controller.sal.dom.broker.impl.DataStoreStatsWrapper;
39 import org.opendaylight.controller.sal.dom.broker.impl.HashMapDataStore;
40 import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareDataStoreAdapter;
41 import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareRpcBroker;
42 import org.opendaylight.controller.sal.dom.broker.impl.SchemaContextProvider;
43 import org.opendaylight.yangtools.concepts.ListenerRegistration;
44 import org.opendaylight.yangtools.sal.binding.generator.impl.RuntimeGeneratedMappingServiceImpl;
45 import org.opendaylight.yangtools.yang.common.QName;
46 import org.opendaylight.yangtools.yang.common.RpcResult;
47 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
48 import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
49 import org.opendaylight.yangtools.yang.model.api.Module;
50 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
51 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
52 import org.reflections.Reflections;
53 import org.reflections.scanners.ResourcesScanner;
54 import org.slf4j.Logger;
55 import org.slf4j.LoggerFactory;
57 import com.google.common.base.Predicate;
58 import com.google.common.collect.ClassToInstanceMap;
59 import com.google.common.collect.ImmutableClassToInstanceMap;
60 import com.google.common.util.concurrent.ListeningExecutorService;
62 import static com.google.common.base.Preconditions.*;
64 public class BindingTestContext implements AutoCloseable, SchemaContextProvider {
66 public static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier TREE_ROOT = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
67 .builder().toInstance();
69 private static final Logger LOG = LoggerFactory.getLogger(BindingTestContext.class);
71 private RuntimeGeneratedMappingServiceImpl mappingServiceImpl;
73 private DomForwardedBindingBrokerImpl baBrokerImpl;
74 private DataBrokerImpl baDataImpl;
75 private NotificationBrokerImpl baNotifyImpl;
76 private BindingIndependentConnector baConnectImpl;
78 private org.opendaylight.controller.sal.dom.broker.DataBrokerImpl biDataImpl;
79 private BrokerImpl biBrokerImpl;
80 private HashMapDataStore rawDataStore;
81 private SchemaAwareDataStoreAdapter schemaAwareDataStore;
82 private DataStoreStatsWrapper dataStoreStats;
83 private DataStore dataStore;
85 private boolean dataStoreStatisticsEnabled = false;
87 private final ListeningExecutorService executor;
88 private final ClassPool classPool;
90 private final boolean startWithSchema;
92 private MountPointManagerImpl biMountImpl;
94 private SchemaContext schemaContext;
96 public SchemaContext getSchemaContext() {
100 protected BindingTestContext(ListeningExecutorService executor, ClassPool classPool, boolean startWithSchema) {
101 this.executor = executor;
102 this.classPool = classPool;
103 this.startWithSchema = startWithSchema;
106 public void startDomDataStore() {
107 checkState(dataStore == null, "DataStore already started.");
108 checkState(biDataImpl != null, "Dom Data Broker not present");
109 rawDataStore = new HashMapDataStore();
110 schemaAwareDataStore = new SchemaAwareDataStoreAdapter();
111 schemaAwareDataStore.changeDelegate(rawDataStore);
112 if (dataStoreStatisticsEnabled) {
113 dataStoreStats = new DataStoreStatsWrapper(schemaAwareDataStore);
114 dataStore = dataStoreStats;
116 dataStore = schemaAwareDataStore;
119 biDataImpl.registerConfigurationReader(TREE_ROOT, dataStore);
120 biDataImpl.registerOperationalReader(TREE_ROOT, dataStore);
121 biDataImpl.registerCommitHandler(TREE_ROOT, dataStore);
124 public void startDomDataBroker() {
125 checkState(executor != null, "Executor needs to be set");
126 biDataImpl = new org.opendaylight.controller.sal.dom.broker.DataBrokerImpl();
127 biDataImpl.setExecutor(executor);
130 public void startBindingDataBroker() {
131 checkState(executor != null, "Executor needs to be set");
132 baDataImpl = new DataBrokerImpl();
133 baDataImpl.setExecutor(executor);
136 public void startBindingBroker() {
137 checkState(executor != null, "Executor needs to be set");
138 checkState(baDataImpl != null, "Binding Data Broker must be started");
139 checkState(baNotifyImpl != null, "Notification Service must be started");
140 baBrokerImpl = new DomForwardedBindingBrokerImpl("test");
142 baBrokerImpl.getMountManager().setDataCommitExecutor(executor);
143 baBrokerImpl.getMountManager().setNotificationExecutor(executor);
144 baBrokerImpl.setRpcBroker(new RpcProviderRegistryImpl("test"));
145 baBrokerImpl.setDataBroker(baDataImpl);
146 baBrokerImpl.setNotificationBroker(baNotifyImpl);
147 baBrokerImpl.start();
150 public void startForwarding() {
151 checkState(baDataImpl != null, "Binding Data Broker needs to be started");
152 checkState(biDataImpl != null, "DOM Data Broker needs to be started.");
153 checkState(mappingServiceImpl != null, "DOM Mapping Service needs to be started.");
155 baConnectImpl = BindingDomConnectorDeployer.createConnector(getBindingToDomMappingService());
156 baConnectImpl.setDomRpcRegistry(getDomRpcRegistry());
157 baBrokerImpl.setConnector(baConnectImpl);
158 baBrokerImpl.setDomProviderContext(createMockContext());
159 baBrokerImpl.startForwarding();
162 private ProviderSession createMockContext() {
163 // TODO Auto-generated method stub
164 final ClassToInstanceMap<BrokerService> domBrokerServices = ImmutableClassToInstanceMap
165 .<BrokerService> builder()
167 .put(org.opendaylight.controller.sal.core.api.data.DataProviderService.class, biDataImpl) //
168 .put(RpcProvisionRegistry.class, biBrokerImpl.getRouter()) //
169 .put(MountProvisionService.class, biMountImpl) //
172 return new ProviderSession() {
175 public Future<RpcResult<CompositeNode>> rpc(QName rpc, CompositeNode input) {
176 throw new UnsupportedOperationException();
180 public <T extends BrokerService> T getService(Class<T> service) {
181 return domBrokerServices.getInstance(service);
185 public boolean isClosed() {
190 public Set<QName> getSupportedRpcs() {
195 public void close() {
199 public ListenerRegistration<RpcRegistrationListener> addRpcRegistrationListener(
200 RpcRegistrationListener listener) {
205 public RpcRegistration addRpcImplementation(QName rpcType, RpcImplementation implementation)
206 throws IllegalArgumentException {
211 public RoutedRpcRegistration addRoutedRpcImplementation(QName rpcType, RpcImplementation implementation) {
216 public RoutedRpcRegistration addMountedRpcImplementation(QName rpcType, RpcImplementation implementation) {
222 public void startBindingToDomMappingService() {
223 checkState(classPool != null, "ClassPool needs to be present");
224 mappingServiceImpl = new RuntimeGeneratedMappingServiceImpl();
225 mappingServiceImpl.setPool(classPool);
226 mappingServiceImpl.init();
229 public void updateYangSchema(String[] files) {
230 schemaContext = getContext(files);
231 if (schemaAwareDataStore != null) {
232 schemaAwareDataStore.onGlobalContextUpdated(schemaContext);
234 if (mappingServiceImpl != null) {
235 mappingServiceImpl.onGlobalContextUpdated(schemaContext);
239 public static String[] getAllYangFilesOnClasspath() {
240 Predicate<String> predicate = new Predicate<String>() {
242 public boolean apply(String input) {
243 return input.endsWith(".yang");
246 Reflections reflection = new Reflections("META-INF.yang", new ResourcesScanner());
247 Set<String> result = reflection.getResources(predicate);
248 return (String[]) result.toArray(new String[result.size()]);
251 private static SchemaContext getContext(String[] yangFiles) {
252 ClassLoader loader = BindingTestContext.class.getClassLoader();
253 List<InputStream> streams = new ArrayList<>();
254 for (String string : yangFiles) {
255 InputStream stream = loader.getResourceAsStream(string);
258 YangParserImpl parser = new YangParserImpl();
259 Set<Module> modules = parser.parseYangModelsFromStreams(streams);
260 return parser.resolveSchemaContext(modules);
263 public void start() {
264 startBindingDataBroker();
265 startBindingNotificationBroker();
266 startBindingBroker();
267 startDomDataBroker();
270 startDomMountPoint();
271 startBindingToDomMappingService();
273 if (startWithSchema) {
274 loadYangSchemaFromClasspath();
278 private void startDomMountPoint() {
279 biMountImpl = new MountPointManagerImpl();
280 biMountImpl.setDataBroker(getDomDataBroker());
283 private void startDomBroker() {
284 checkState(executor != null);
285 biBrokerImpl = new BrokerImpl();
286 biBrokerImpl.setExecutor(executor);
287 biBrokerImpl.setRouter(new SchemaAwareRpcBroker("/", this));
290 public void startBindingNotificationBroker() {
291 checkState(executor != null);
292 baNotifyImpl = new NotificationBrokerImpl(executor);
296 public void loadYangSchemaFromClasspath() {
297 String[] files = getAllYangFilesOnClasspath();
298 updateYangSchema(files);
301 public DataProviderService getBindingDataBroker() {
305 public org.opendaylight.controller.sal.core.api.data.DataProviderService getDomDataBroker() {
309 public DataStore getDomDataStore() {
313 public BindingIndependentMappingService getBindingToDomMappingService() {
314 return mappingServiceImpl;
317 public void logDataStoreStatistics() {
318 if (dataStoreStats == null) {
322 LOG.info("BIDataStore Statistics: Configuration Read Count: {} TotalTime: {} ms AverageTime (ns): {} ms",
323 dataStoreStats.getConfigurationReadCount(), dataStoreStats.getConfigurationReadTotalTime(),
324 dataStoreStats.getConfigurationReadAverageTime());
326 LOG.info("BIDataStore Statistics: Operational Read Count: {} TotalTime: {} ms AverageTime (ns): {} ms",
327 dataStoreStats.getOperationalReadCount(), dataStoreStats.getOperationalReadTotalTime(),
328 dataStoreStats.getOperationalReadAverageTime());
330 LOG.info("BIDataStore Statistics: Request Commit Count: {} TotalTime: {} ms AverageTime (ns): {} ms",
331 dataStoreStats.getRequestCommitCount(), dataStoreStats.getRequestCommitTotalTime(),
332 dataStoreStats.getRequestCommitAverageTime());
335 public RpcProviderRegistry getBindingRpcRegistry() {
336 return baBrokerImpl.getRoot();
339 public RpcProvisionRegistry getDomRpcRegistry() {
340 if (biBrokerImpl == null) {
343 return biBrokerImpl.getRouter();
346 public RpcImplementation getDomRpcInvoker() {
347 return biBrokerImpl.getRouter();
351 public void close() throws Exception {
355 public MountProviderService getBindingMountProviderService() {
356 return baBrokerImpl.getMountManager();
359 public MountProvisionService getDomMountProviderService() {