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.config.yang.programming.impl;
10 import static org.mockito.Matchers.any;
11 import static org.mockito.Matchers.anyString;
12 import static org.mockito.Matchers.contains;
13 import static org.mockito.Mockito.doAnswer;
14 import static org.mockito.Mockito.doReturn;
15 import static org.mockito.Mockito.mock;
17 import com.google.common.base.Optional;
18 import com.google.common.collect.Lists;
19 import com.google.common.io.ByteSource;
20 import com.google.common.io.Resources;
21 import io.netty.channel.EventLoopGroup;
22 import io.netty.channel.nio.NioEventLoopGroup;
23 import io.netty.util.Timer;
24 import java.io.IOException;
25 import java.lang.reflect.Field;
26 import java.lang.reflect.Modifier;
28 import java.util.ArrayList;
29 import java.util.Collection;
30 import java.util.Collections;
31 import java.util.Dictionary;
32 import java.util.List;
34 import javax.management.InstanceAlreadyExistsException;
35 import javax.management.InstanceNotFoundException;
36 import javax.management.ObjectName;
37 import org.junit.After;
38 import org.junit.Assert;
39 import org.junit.Before;
40 import org.mockito.Matchers;
41 import org.mockito.Mock;
42 import org.mockito.Mockito;
43 import org.mockito.MockitoAnnotations;
44 import org.mockito.invocation.InvocationOnMock;
45 import org.mockito.stubbing.Answer;
46 import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
47 import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
48 import org.opendaylight.controller.config.spi.ModuleFactory;
49 import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
50 import org.opendaylight.controller.config.yang.md.sal.binding.impl.BindingAsyncDataBrokerImplModuleFactory;
51 import org.opendaylight.controller.config.yang.md.sal.binding.impl.BindingAsyncDataBrokerImplModuleMXBean;
52 import org.opendaylight.controller.config.yang.md.sal.binding.impl.BindingBrokerImplModuleFactory;
53 import org.opendaylight.controller.config.yang.md.sal.binding.impl.BindingBrokerImplModuleMXBean;
54 import org.opendaylight.controller.config.yang.md.sal.binding.impl.ForwardedCompatibleDataBrokerImplModuleFactory;
55 import org.opendaylight.controller.config.yang.md.sal.binding.impl.ForwardedCompatibleDataBrokerImplModuleMXBean;
56 import org.opendaylight.controller.config.yang.md.sal.binding.impl.NotificationBrokerImplModuleFactory;
57 import org.opendaylight.controller.config.yang.md.sal.binding.impl.RuntimeMappingModuleFactory;
58 import org.opendaylight.controller.config.yang.md.sal.dom.impl.DomBrokerImplModuleFactory;
59 import org.opendaylight.controller.config.yang.md.sal.dom.impl.DomBrokerImplModuleMXBean;
60 import org.opendaylight.controller.config.yang.md.sal.dom.impl.DomInmemoryDataBrokerModuleFactory;
61 import org.opendaylight.controller.config.yang.md.sal.dom.impl.DomInmemoryDataBrokerModuleMXBean;
62 import org.opendaylight.controller.config.yang.md.sal.dom.impl.SchemaServiceImplSingletonModuleFactory;
63 import org.opendaylight.controller.config.yang.netty.timer.HashedWheelTimerModuleFactory;
64 import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodecFactory;
65 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
66 import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
67 import org.opendaylight.controller.md.sal.dom.api.DOMNotificationPublishService;
68 import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService;
69 import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementation;
70 import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementationRegistration;
71 import org.opendaylight.controller.md.sal.dom.api.DOMRpcProviderService;
72 import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
73 import org.opendaylight.controller.sal.dom.broker.GlobalBundleScanningSchemaServiceImpl;
74 import org.opendaylight.yangtools.sal.binding.generator.api.ClassLoadingStrategy;
75 import org.opendaylight.yangtools.sal.binding.generator.impl.GeneratedClassLoadingStrategy;
76 import org.opendaylight.yangtools.yang.common.RpcResult;
77 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
78 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
79 import org.opendaylight.yangtools.yang.parser.repo.URLSchemaContextResolver;
80 import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
81 import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor;
82 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline;
83 import org.osgi.framework.Bundle;
84 import org.osgi.framework.BundleListener;
85 import org.osgi.framework.Filter;
86 import org.osgi.framework.ServiceListener;
87 import org.osgi.framework.ServiceReference;
89 public abstract class AbstractInstructionSchedulerTest extends AbstractConfigTest {
91 private static final String FACTORY_NAME = InstructionSchedulerImplModuleFactory.NAME;
92 private static final String INSTANCE_NAME = "instruction-scheduler-impl";
94 private static final String BINDING_BROKER_INSTANCE_NAME = "binding-broker-impl";
95 private static final String NOTIFICATION_BROKER_INSTANCE_NAME = "notification-broker-impl";
96 private static final String COMPATIBLE_DATA_BROKER_INSTANCE_NAME = "binding-data-compatible-broker-instance";
97 private static final String DOM_BROKER_INSTANCE_NAME = "dom-broker-impl";
98 private static final String TIMER_INSTANCE_NAME = "timer-impl";
99 private static final String BINDING_ASYNC_BROKER_INSTANCE_NAME = "binding-async-broker-instance";
100 private static final String DOM_ASYNC_DATA_BROKER_INSTANCE = "dom-inmemory-data-broker";
103 private RpcResult<TransactionStatus> mockedResult;
105 @SuppressWarnings("unchecked")
107 public void setUp() throws Exception {
108 MockitoAnnotations.initMocks(this);
110 final List<ModuleFactory> moduleFactories = getModuleFactories();
111 super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, moduleFactories.toArray(new ModuleFactory[moduleFactories.size()])));
113 doAnswer(new Answer<Filter>() {
115 public Filter answer(final InvocationOnMock invocation) {
116 final String str = invocation.getArgumentAt(0, String.class);
117 final Filter mockFilter = mock(Filter.class);
118 doReturn(str).when(mockFilter).toString();
121 }).when(mockedContext).createFilter(anyString());
123 Mockito.doReturn(new ServiceReference[] {}).when(mockedContext).getServiceReferences(Matchers.anyString(), Matchers.anyString());
125 final ServiceReference<?> classLoadingStrategySR = mock(ServiceReference.class, "ClassLoadingStrategy");
126 final ServiceReference<?> emptyServiceReference = mock(ServiceReference.class, "Empty");
128 Mockito.doNothing().when(mockedContext).addServiceListener(any(ServiceListener.class), Mockito.anyString());
129 Mockito.doNothing().when(mockedContext).removeServiceListener(any(ServiceListener.class));
131 Mockito.doNothing().when(mockedContext).addBundleListener(any(BundleListener.class));
132 Mockito.doNothing().when(mockedContext).removeBundleListener(any(BundleListener.class));
134 Mockito.doReturn(new Bundle[] {}).when(mockedContext).getBundles();
136 Mockito.doReturn(new ServiceReference[] {}).when(mockedContext).getServiceReferences(Matchers.anyString(), Matchers.anyString());
138 Mockito.doReturn("Class loading stategy reference").when(classLoadingStrategySR).toString();
139 Mockito.doReturn("Empty reference").when(emptyServiceReference).toString();
141 Mockito.doReturn(emptyServiceReference).when(mockedContext).getServiceReference(any(Class.class));
142 Mockito.doReturn(classLoadingStrategySR).when(mockedContext).getServiceReference(GeneratedClassLoadingStrategy.class);
143 Mockito.doReturn(classLoadingStrategySR).when(this.mockedContext).getServiceReference(ClassLoadingStrategy.class);
145 Mockito.doReturn(GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy()).when(mockedContext).getService(classLoadingStrategySR);
146 Mockito.doReturn(null).when(mockedContext).getService(emptyServiceReference);
148 final GlobalBundleScanningSchemaServiceImpl schemaService = GlobalBundleScanningSchemaServiceImpl.createInstance(this.mockedContext);
149 final SchemaContext context = parseYangStreams(getFilesAsByteSources(getYangModelsPaths()));
150 final URLSchemaContextResolver mockedContextResolver = Mockito.mock(URLSchemaContextResolver.class);
151 Mockito.doReturn(Optional.of(context)).when(mockedContextResolver).getSchemaContext();
153 final Field contextResolverField = schemaService.getClass().getDeclaredField("contextResolver");
154 contextResolverField.setAccessible(true);
156 final Field modifiersField = Field.class.getDeclaredField("modifiers");
157 modifiersField.setAccessible(true);
158 modifiersField.setInt(contextResolverField, contextResolverField.getModifiers() & ~Modifier.FINAL);
160 contextResolverField.set(schemaService, mockedContextResolver);
162 BindingToNormalizedNodeCodecFactory.getOrCreateInstance(
163 GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy(), schemaService);
165 setupMockService(Timer.class, mock(Timer.class));
166 setupMockService(EventLoopGroup.class, new NioEventLoopGroup());
167 setupMockService(DOMNotificationService.class, mock(DOMNotificationService.class));
168 setupMockService(DOMNotificationPublishService.class, mock(DOMNotificationPublishService.class));
169 setupMockService(DOMRpcService.class, mock(DOMRpcService.class));
170 setupMockService(DOMMountPointService.class, mock(DOMMountPointService.class));
172 final DOMRpcProviderService mockRpcProvider = mock(DOMRpcProviderService.class);
173 doReturn(mock(DOMRpcImplementationRegistration.class)).when(mockRpcProvider).registerRpcImplementation(
174 any(DOMRpcImplementation.class), any(Set.class));
175 setupMockService(DOMRpcProviderService.class, mockRpcProvider);
178 private void setupMockService(final Class<?> serviceInterface, final Object instance) throws Exception {
179 final ServiceReference<?> mockServiceRef = mock(ServiceReference.class);
180 doReturn(new ServiceReference[]{mockServiceRef}).when(mockedContext).
181 getServiceReferences(anyString(), contains(serviceInterface.getName()));
182 doReturn(new ServiceReference[]{mockServiceRef}).when(mockedContext).
183 getServiceReferences(serviceInterface.getName(), null);
184 doReturn(instance).when(mockedContext).getService(mockServiceRef);
188 public void tearDownGlobalBundleScanningSchemaServiceImpl() throws Exception{
189 GlobalBundleScanningSchemaServiceImpl.destroyInstance();
192 public ObjectName createInstructionSchedulerModuleInstance(final ConfigTransactionJMXClient transaction, final ObjectName dataBrokerON,
193 final ObjectName rpcRegistyON, final ObjectName notificationBrokerON) throws Exception {
194 final ObjectName objectName = transaction.createModule(FACTORY_NAME, INSTANCE_NAME);
195 final InstructionSchedulerImplModuleMXBean mxBean = transaction.newMXBeanProxy(objectName,
196 InstructionSchedulerImplModuleMXBean.class);
197 mxBean.setDataProvider(dataBrokerON);
198 mxBean.setRpcRegistry(rpcRegistyON);
199 mxBean.setNotificationService(notificationBrokerON);
200 mxBean.setTimer(createTimerInstance(transaction));
204 private ObjectName createTimerInstance(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException {
205 final ObjectName nameCreated = transaction.createModule(HashedWheelTimerModuleFactory.NAME, TIMER_INSTANCE_NAME);
210 public ObjectName createBindingBrokerImpl(final ConfigTransactionJMXClient transaction, final ObjectName dataBrokerON,
211 final ObjectName notificationBrokerON) throws Exception {
212 final ObjectName objectName = transaction.createModule(BindingBrokerImplModuleFactory.NAME, BINDING_BROKER_INSTANCE_NAME);
213 final BindingBrokerImplModuleMXBean mxBean = transaction.newMXBeanProxy(objectName, BindingBrokerImplModuleMXBean.class);
214 mxBean.setDataBroker(dataBrokerON);
215 mxBean.setNotificationService(notificationBrokerON);
216 mxBean.setBindingMappingService(lookupMappingServiceInstance(transaction));
217 mxBean.setDomAsyncBroker(lookupDomBrokerInstance(transaction));
221 public ObjectName createNotificationBrokerInstance(final ConfigTransactionJMXClient transaction) throws Exception {
222 final ObjectName objectName = transaction.createModule(NotificationBrokerImplModuleFactory.NAME, NOTIFICATION_BROKER_INSTANCE_NAME);
226 public ObjectName createCompatibleDataBrokerInstance(final ConfigTransactionJMXClient transaction)
227 throws InstanceAlreadyExistsException, InstanceNotFoundException {
228 final ObjectName nameCreated = transaction.createModule(ForwardedCompatibleDataBrokerImplModuleFactory.NAME, COMPATIBLE_DATA_BROKER_INSTANCE_NAME);
229 final ForwardedCompatibleDataBrokerImplModuleMXBean mxBean = transaction.newMXBeanProxy(nameCreated, ForwardedCompatibleDataBrokerImplModuleMXBean.class);
230 mxBean.setDataBroker(lookupDataBrokerInstance(transaction));
234 private static ObjectName lookupDataBrokerInstance(final ConfigTransactionJMXClient transaction) {
236 return transaction.lookupConfigBean(BindingAsyncDataBrokerImplModuleFactory.NAME, BINDING_ASYNC_BROKER_INSTANCE_NAME);
237 } catch (final InstanceNotFoundException e) {
239 return transaction.createModule(RuntimeMappingModuleFactory.NAME, RuntimeMappingModuleFactory.SINGLETON_NAME);
240 } catch (final InstanceAlreadyExistsException e1) {
241 throw new IllegalStateException(e1);
246 public ObjectName createAsyncDataBrokerInstance(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException, InstanceNotFoundException {
247 final ObjectName nameCreated = transaction.createModule(BindingAsyncDataBrokerImplModuleFactory.NAME, BINDING_ASYNC_BROKER_INSTANCE_NAME);
248 final BindingAsyncDataBrokerImplModuleMXBean mxBean = transaction.newMXBeanProxy(nameCreated, BindingAsyncDataBrokerImplModuleMXBean.class);
249 mxBean.setBindingMappingService(lookupMappingServiceInstance(transaction));
250 mxBean.setDomAsyncBroker(lookupDomAsyncDataBroker(transaction));
251 mxBean.setSchemaService(lookupSchemaServiceInstance(transaction));
255 private static ObjectName lookupMappingServiceInstance(final ConfigTransactionJMXClient transaction) {
257 return transaction.lookupConfigBean(RuntimeMappingModuleFactory.NAME, RuntimeMappingModuleFactory.SINGLETON_NAME);
258 } catch (final InstanceNotFoundException e) {
260 return transaction.createModule(RuntimeMappingModuleFactory.NAME, RuntimeMappingModuleFactory.SINGLETON_NAME);
261 } catch (final InstanceAlreadyExistsException e1) {
262 throw new IllegalStateException(e1);
267 private static ObjectName lookupSchemaServiceInstance(final ConfigTransactionJMXClient transaction) {
269 return transaction.lookupConfigBean(SchemaServiceImplSingletonModuleFactory.NAME, SchemaServiceImplSingletonModuleFactory.SINGLETON_NAME);
270 } catch (final InstanceNotFoundException e) {
272 return transaction.createModule(SchemaServiceImplSingletonModuleFactory.NAME, SchemaServiceImplSingletonModuleFactory.SINGLETON_NAME);
273 } catch (final InstanceAlreadyExistsException e1) {
274 throw new IllegalStateException(e1);
279 public static ObjectName lookupDomBrokerInstance(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException {
281 return transaction.lookupConfigBean(DomBrokerImplModuleFactory.NAME, DOM_BROKER_INSTANCE_NAME);
282 } catch (final InstanceNotFoundException e) {
284 final ObjectName nameCreated = transaction.createModule(DomBrokerImplModuleFactory.NAME, DOM_BROKER_INSTANCE_NAME);
285 final DomBrokerImplModuleMXBean mxBean = transaction.newMXBeanProxy(nameCreated, DomBrokerImplModuleMXBean.class);
286 mxBean.setAsyncDataBroker(lookupDomAsyncDataBroker(transaction));
288 } catch (final InstanceAlreadyExistsException e1) {
289 throw new IllegalStateException(e1);
294 private static ObjectName lookupDomAsyncDataBroker(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException {
296 return transaction.lookupConfigBean(DomInmemoryDataBrokerModuleFactory.NAME, DOM_ASYNC_DATA_BROKER_INSTANCE);
297 } catch (final InstanceNotFoundException e) {
299 final ObjectName nameCreated = transaction.createModule(DomInmemoryDataBrokerModuleFactory.NAME, DOM_ASYNC_DATA_BROKER_INSTANCE);
300 final DomInmemoryDataBrokerModuleMXBean mxBean = transaction.newMXBeanProxy(nameCreated, DomInmemoryDataBrokerModuleMXBean.class);
301 mxBean.setSchemaService(lookupSchemaServiceInstance(transaction));
303 } catch (final InstanceAlreadyExistsException e1) {
304 throw new IllegalStateException(e1);
310 protected BundleContextServiceRegistrationHandler getBundleContextServiceRegistrationHandler(final Class<?> serviceType) {
311 if (serviceType.equals(SchemaContextListener.class)) {
312 return new BundleContextServiceRegistrationHandler() {
314 public void handleServiceRegistration(final Class<?> clazz, final Object serviceInstance, final Dictionary<String, ?> props) {
315 final SchemaContextListener listener = (SchemaContextListener) serviceInstance;
316 final SchemaContext context = parseYangStreams(getFilesAsByteSources(getYangModelsPaths()));
317 listener.onGlobalContextUpdated(context);
318 listener.onGlobalContextUpdated(context);
322 return super.getBundleContextServiceRegistrationHandler(serviceType);
325 public List<String> getYangModelsPaths() {
326 final List<String> paths = Lists.newArrayList("/META-INF/yang/ietf-inet-types.yang", "/META-INF/yang/programming.yang");
330 public List<ModuleFactory> getModuleFactories() {
331 return Lists.newArrayList(new InstructionSchedulerImplModuleFactory(), new HashedWheelTimerModuleFactory(),
332 new NotificationBrokerImplModuleFactory(), new DomBrokerImplModuleFactory(),
333 new RuntimeMappingModuleFactory(), new BindingBrokerImplModuleFactory(), new BindingAsyncDataBrokerImplModuleFactory(),
334 new DomInmemoryDataBrokerModuleFactory(), new SchemaServiceImplSingletonModuleFactory(),
335 new ForwardedCompatibleDataBrokerImplModuleFactory());
338 // TODO move back to AbstractConfigTest
339 private static Collection<ByteSource> getFilesAsByteSources(final List<String> paths) {
340 final Collection<ByteSource> resources = new ArrayList<>();
341 final List<String> failedToFind = new ArrayList<>();
342 for (final String path : paths) {
343 final URL url = AbstractInstructionSchedulerTest.class.getResource(path);
345 failedToFind.add(path);
347 resources.add(Resources.asByteSource(url));
350 Assert.assertEquals("Some files were not found", Collections.<String> emptyList(), failedToFind);
355 private static SchemaContext parseYangStreams(final Collection<ByteSource> streams) {
356 final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR
359 return reactor.buildEffective(streams);
360 } catch (final ReactorException | IOException e) {
361 throw new RuntimeException("Unable to build schema context from " + streams, e);