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.doNothing;
15 import static org.mockito.Mockito.doReturn;
16 import static org.mockito.Mockito.mock;
18 import com.google.common.base.Throwables;
19 import com.google.common.collect.Lists;
20 import io.netty.channel.EventLoopGroup;
21 import io.netty.channel.nio.NioEventLoopGroup;
22 import io.netty.util.Timer;
23 import java.io.IOException;
24 import java.io.InputStream;
26 import java.util.ArrayList;
27 import java.util.Collections;
28 import java.util.Dictionary;
29 import java.util.List;
31 import javax.management.InstanceAlreadyExistsException;
32 import javax.management.InstanceNotFoundException;
33 import javax.management.ObjectName;
34 import org.junit.After;
35 import org.junit.Assert;
36 import org.junit.Before;
37 import org.mockito.Matchers;
38 import org.mockito.Mock;
39 import org.mockito.Mockito;
40 import org.mockito.MockitoAnnotations;
41 import org.mockito.invocation.InvocationOnMock;
42 import org.mockito.stubbing.Answer;
43 import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
44 import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
45 import org.opendaylight.controller.config.spi.ModuleFactory;
46 import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
47 import org.opendaylight.controller.config.yang.md.sal.binding.impl.BindingAsyncDataBrokerImplModuleFactory;
48 import org.opendaylight.controller.config.yang.md.sal.binding.impl.BindingAsyncDataBrokerImplModuleMXBean;
49 import org.opendaylight.controller.config.yang.md.sal.binding.impl.BindingBrokerImplModuleFactory;
50 import org.opendaylight.controller.config.yang.md.sal.binding.impl.BindingBrokerImplModuleMXBean;
51 import org.opendaylight.controller.config.yang.md.sal.binding.impl.ForwardedCompatibleDataBrokerImplModuleFactory;
52 import org.opendaylight.controller.config.yang.md.sal.binding.impl.ForwardedCompatibleDataBrokerImplModuleMXBean;
53 import org.opendaylight.controller.config.yang.md.sal.binding.impl.NotificationBrokerImplModuleFactory;
54 import org.opendaylight.controller.config.yang.md.sal.binding.impl.RuntimeMappingModuleFactory;
55 import org.opendaylight.controller.config.yang.md.sal.dom.impl.DomBrokerImplModuleFactory;
56 import org.opendaylight.controller.config.yang.md.sal.dom.impl.DomBrokerImplModuleMXBean;
57 import org.opendaylight.controller.config.yang.md.sal.dom.impl.DomInmemoryDataBrokerModuleFactory;
58 import org.opendaylight.controller.config.yang.md.sal.dom.impl.DomInmemoryDataBrokerModuleMXBean;
59 import org.opendaylight.controller.config.yang.md.sal.dom.impl.SchemaServiceImplSingletonModuleFactory;
60 import org.opendaylight.controller.config.yang.netty.timer.HashedWheelTimerModuleFactory;
61 import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
62 import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodecFactory;
63 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
64 import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
65 import org.opendaylight.controller.md.sal.dom.api.DOMNotificationPublishService;
66 import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService;
67 import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementation;
68 import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementationRegistration;
69 import org.opendaylight.controller.md.sal.dom.api.DOMRpcProviderService;
70 import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
71 import org.opendaylight.controller.sal.core.api.model.SchemaService;
72 import org.opendaylight.controller.sal.core.api.model.YangTextSourceProvider;
73 import org.opendaylight.mdsal.binding.generator.api.ClassLoadingStrategy;
74 import org.opendaylight.mdsal.binding.generator.impl.GeneratedClassLoadingStrategy;
75 import org.opendaylight.yangtools.concepts.ListenerRegistration;
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.model.parser.api.YangSyntaxErrorException;
80 import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceException;
81 import org.opendaylight.yangtools.yang.parser.repo.YangTextSchemaContextResolver;
82 import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
83 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
84 import org.osgi.framework.Bundle;
85 import org.osgi.framework.BundleListener;
86 import org.osgi.framework.Filter;
87 import org.osgi.framework.ServiceListener;
88 import org.osgi.framework.ServiceReference;
90 public abstract class AbstractInstructionSchedulerTest extends AbstractConfigTest {
92 private static final String FACTORY_NAME = InstructionSchedulerImplModuleFactory.NAME;
93 private static final String INSTANCE_NAME = "instruction-scheduler-impl";
95 private static final String BINDING_BROKER_INSTANCE_NAME = "binding-broker-impl";
96 private static final String NOTIFICATION_BROKER_INSTANCE_NAME = "notification-broker-impl";
97 private static final String COMPATIBLE_DATA_BROKER_INSTANCE_NAME = "binding-data-compatible-broker-instance";
98 private static final String DOM_BROKER_INSTANCE_NAME = "dom-broker-impl";
99 private static final String TIMER_INSTANCE_NAME = "timer-impl";
100 private static final String BINDING_ASYNC_BROKER_INSTANCE_NAME = "binding-async-broker-instance";
101 private static final String DOM_ASYNC_DATA_BROKER_INSTANCE = "dom-inmemory-data-broker";
104 private RpcResult<TransactionStatus> mockedResult;
106 @SuppressWarnings("unchecked")
108 public void setUp() throws Exception {
109 MockitoAnnotations.initMocks(this);
111 final List<ModuleFactory> moduleFactories = getModuleFactories();
112 super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(this.mockedContext, moduleFactories.toArray(new ModuleFactory[moduleFactories.size()])));
114 doAnswer(new Answer<Filter>() {
116 public Filter answer(final InvocationOnMock invocation) {
117 final String str = invocation.getArgumentAt(0, String.class);
118 final Filter mockFilter = mock(Filter.class);
119 doReturn(str).when(mockFilter).toString();
122 }).when(this.mockedContext).createFilter(anyString());
124 Mockito.doReturn(new ServiceReference[] {}).when(this.mockedContext).getServiceReferences(Matchers.anyString(), Matchers.anyString());
126 final ServiceReference<?> classLoadingStrategySR = mock(ServiceReference.class, "ClassLoadingStrategy");
127 final ServiceReference<?> emptyServiceReference = mock(ServiceReference.class, "Empty");
129 Mockito.doNothing().when(this.mockedContext).addServiceListener(any(ServiceListener.class), Mockito.anyString());
130 Mockito.doNothing().when(this.mockedContext).removeServiceListener(any(ServiceListener.class));
132 Mockito.doNothing().when(this.mockedContext).addBundleListener(any(BundleListener.class));
133 Mockito.doNothing().when(this.mockedContext).removeBundleListener(any(BundleListener.class));
135 Mockito.doReturn(new Bundle[] {}).when(this.mockedContext).getBundles();
137 Mockito.doReturn(new ServiceReference[] {}).when(this.mockedContext).getServiceReferences(Matchers.anyString(), Matchers.anyString());
139 Mockito.doReturn("Class loading stategy reference").when(classLoadingStrategySR).toString();
140 Mockito.doReturn("Empty reference").when(emptyServiceReference).toString();
142 Mockito.doReturn(emptyServiceReference).when(this.mockedContext).getServiceReference(any(Class.class));
143 Mockito.doReturn(classLoadingStrategySR).when(this.mockedContext).getServiceReference(GeneratedClassLoadingStrategy.class);
144 Mockito.doReturn(classLoadingStrategySR).when(this.mockedContext).getServiceReference(ClassLoadingStrategy.class);
146 Mockito.doReturn(GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy()).when(this.mockedContext).getService(classLoadingStrategySR);
147 Mockito.doReturn(null).when(this.mockedContext).getService(emptyServiceReference);
149 final SchemaContext context = parseYangStreams(getFilesAsStreams(getYangModelsPaths()));
150 final SchemaService mockedSchemaService = mock(SchemaService.class);
151 doReturn(context).when(mockedSchemaService).getGlobalContext();
152 doAnswer(new Answer<ListenerRegistration<SchemaContextListener>>() {
154 public ListenerRegistration<SchemaContextListener> answer(final InvocationOnMock invocation) {
155 invocation.getArgumentAt(0, SchemaContextListener.class).onGlobalContextUpdated(context);
156 final ListenerRegistration<SchemaContextListener> reg = mock(ListenerRegistration.class);
157 doNothing().when(reg).close();
160 }).when(mockedSchemaService).registerSchemaContextListener(any(SchemaContextListener.class));
162 setupMockService(SchemaService.class, mockedSchemaService);
163 setupMockService(YangTextSourceProvider.class, mock(YangTextSourceProvider.class));
165 final BindingToNormalizedNodeCodec bindingCodec = BindingToNormalizedNodeCodecFactory.newInstance(
166 GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy());
167 BindingToNormalizedNodeCodecFactory.registerInstance(bindingCodec, mockedSchemaService);
168 setupMockService(BindingToNormalizedNodeCodec.class, bindingCodec);
170 setupMockService(Timer.class, mock(Timer.class));
171 setupMockService(EventLoopGroup.class, new NioEventLoopGroup());
172 setupMockService(DOMNotificationService.class, mock(DOMNotificationService.class));
173 setupMockService(DOMNotificationPublishService.class, mock(DOMNotificationPublishService.class));
174 setupMockService(DOMRpcService.class, mock(DOMRpcService.class));
175 setupMockService(DOMMountPointService.class, mock(DOMMountPointService.class));
177 final DOMRpcProviderService mockRpcProvider = mock(DOMRpcProviderService.class);
178 doReturn(mock(DOMRpcImplementationRegistration.class)).when(mockRpcProvider).registerRpcImplementation(
179 any(DOMRpcImplementation.class), any(Set.class));
180 setupMockService(DOMRpcProviderService.class, mockRpcProvider);
183 protected void setupMockService(final Class<?> serviceInterface, final Object instance) throws Exception {
184 final ServiceReference<?> mockServiceRef = mock(ServiceReference.class);
185 doReturn(new ServiceReference[]{mockServiceRef}).when(this.mockedContext).
186 getServiceReferences(anyString(), contains(serviceInterface.getName()));
187 doReturn(new ServiceReference[]{mockServiceRef}).when(this.mockedContext).
188 getServiceReferences(serviceInterface.getName(), null);
189 doReturn(instance).when(this.mockedContext).getService(mockServiceRef);
193 public void tearDownGlobalBundleScanningSchemaServiceImpl() throws Exception{
196 public ObjectName createInstructionSchedulerModuleInstance(final ConfigTransactionJMXClient transaction, final ObjectName dataBrokerON,
197 final ObjectName rpcRegistyON, final ObjectName notificationBrokerON) throws Exception {
198 final ObjectName objectName = transaction.createModule(FACTORY_NAME, INSTANCE_NAME);
199 final InstructionSchedulerImplModuleMXBean mxBean = transaction.newMXBeanProxy(objectName,
200 InstructionSchedulerImplModuleMXBean.class);
201 mxBean.setDataProvider(dataBrokerON);
202 mxBean.setRpcRegistry(rpcRegistyON);
203 mxBean.setNotificationService(notificationBrokerON);
204 mxBean.setTimer(createTimerInstance(transaction));
208 private ObjectName createTimerInstance(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException {
209 final ObjectName nameCreated = transaction.createModule(HashedWheelTimerModuleFactory.NAME, TIMER_INSTANCE_NAME);
214 public ObjectName createBindingBrokerImpl(final ConfigTransactionJMXClient transaction, final ObjectName dataBrokerON,
215 final ObjectName notificationBrokerON) throws Exception {
216 final ObjectName objectName = transaction.createModule(BindingBrokerImplModuleFactory.NAME, BINDING_BROKER_INSTANCE_NAME);
217 final BindingBrokerImplModuleMXBean mxBean = transaction.newMXBeanProxy(objectName, BindingBrokerImplModuleMXBean.class);
218 mxBean.setDataBroker(dataBrokerON);
219 mxBean.setNotificationService(notificationBrokerON);
220 mxBean.setBindingMappingService(lookupMappingServiceInstance(transaction));
221 mxBean.setDomAsyncBroker(lookupDomBrokerInstance(transaction));
225 public ObjectName createNotificationBrokerInstance(final ConfigTransactionJMXClient transaction) throws Exception {
226 final ObjectName objectName = transaction.createModule(NotificationBrokerImplModuleFactory.NAME, NOTIFICATION_BROKER_INSTANCE_NAME);
230 public ObjectName createCompatibleDataBrokerInstance(final ConfigTransactionJMXClient transaction)
231 throws InstanceAlreadyExistsException, InstanceNotFoundException {
232 final ObjectName nameCreated = transaction.createModule(ForwardedCompatibleDataBrokerImplModuleFactory.NAME, COMPATIBLE_DATA_BROKER_INSTANCE_NAME);
233 final ForwardedCompatibleDataBrokerImplModuleMXBean mxBean = transaction.newMXBeanProxy(nameCreated, ForwardedCompatibleDataBrokerImplModuleMXBean.class);
234 mxBean.setDataBroker(lookupDataBrokerInstance(transaction));
238 private static ObjectName lookupDataBrokerInstance(final ConfigTransactionJMXClient transaction) {
240 return transaction.lookupConfigBean(BindingAsyncDataBrokerImplModuleFactory.NAME, BINDING_ASYNC_BROKER_INSTANCE_NAME);
241 } catch (final InstanceNotFoundException e) {
243 return transaction.createModule(RuntimeMappingModuleFactory.NAME, RuntimeMappingModuleFactory.SINGLETON_NAME);
244 } catch (final InstanceAlreadyExistsException e1) {
245 throw new IllegalStateException(e1);
250 public ObjectName createAsyncDataBrokerInstance(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException, InstanceNotFoundException {
251 final ObjectName nameCreated = transaction.createModule(BindingAsyncDataBrokerImplModuleFactory.NAME, BINDING_ASYNC_BROKER_INSTANCE_NAME);
252 final BindingAsyncDataBrokerImplModuleMXBean mxBean = transaction.newMXBeanProxy(nameCreated, BindingAsyncDataBrokerImplModuleMXBean.class);
253 mxBean.setBindingMappingService(lookupMappingServiceInstance(transaction));
254 mxBean.setDomAsyncBroker(lookupDomAsyncDataBroker(transaction));
255 mxBean.setSchemaService(lookupSchemaServiceInstance(transaction));
259 private static ObjectName lookupMappingServiceInstance(final ConfigTransactionJMXClient transaction) {
261 return transaction.lookupConfigBean(RuntimeMappingModuleFactory.NAME, RuntimeMappingModuleFactory.SINGLETON_NAME);
262 } catch (final InstanceNotFoundException e) {
264 return transaction.createModule(RuntimeMappingModuleFactory.NAME, RuntimeMappingModuleFactory.SINGLETON_NAME);
265 } catch (final InstanceAlreadyExistsException e1) {
266 throw new IllegalStateException(e1);
271 private static ObjectName lookupSchemaServiceInstance(final ConfigTransactionJMXClient transaction) {
273 return transaction.lookupConfigBean(SchemaServiceImplSingletonModuleFactory.NAME, SchemaServiceImplSingletonModuleFactory.SINGLETON_NAME);
274 } catch (final InstanceNotFoundException e) {
276 return transaction.createModule(SchemaServiceImplSingletonModuleFactory.NAME, SchemaServiceImplSingletonModuleFactory.SINGLETON_NAME);
277 } catch (final InstanceAlreadyExistsException e1) {
278 throw new IllegalStateException(e1);
283 public static ObjectName lookupDomBrokerInstance(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException {
285 return transaction.lookupConfigBean(DomBrokerImplModuleFactory.NAME, DOM_BROKER_INSTANCE_NAME);
286 } catch (final InstanceNotFoundException e) {
288 final ObjectName nameCreated = transaction.createModule(DomBrokerImplModuleFactory.NAME, DOM_BROKER_INSTANCE_NAME);
289 final DomBrokerImplModuleMXBean mxBean = transaction.newMXBeanProxy(nameCreated, DomBrokerImplModuleMXBean.class);
290 mxBean.setAsyncDataBroker(lookupDomAsyncDataBroker(transaction));
292 } catch (final InstanceAlreadyExistsException e1) {
293 throw new IllegalStateException(e1);
298 private static ObjectName lookupDomAsyncDataBroker(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException {
300 return transaction.lookupConfigBean(DomInmemoryDataBrokerModuleFactory.NAME, DOM_ASYNC_DATA_BROKER_INSTANCE);
301 } catch (final InstanceNotFoundException e) {
303 final ObjectName nameCreated = transaction.createModule(DomInmemoryDataBrokerModuleFactory.NAME, DOM_ASYNC_DATA_BROKER_INSTANCE);
304 final DomInmemoryDataBrokerModuleMXBean mxBean = transaction.newMXBeanProxy(nameCreated, DomInmemoryDataBrokerModuleMXBean.class);
305 mxBean.setSchemaService(lookupSchemaServiceInstance(transaction));
307 } catch (final InstanceAlreadyExistsException e1) {
308 throw new IllegalStateException(e1);
314 protected BundleContextServiceRegistrationHandler getBundleContextServiceRegistrationHandler(final Class<?> serviceType) {
315 if (serviceType.equals(SchemaContextListener.class)) {
316 return new BundleContextServiceRegistrationHandler() {
318 public void handleServiceRegistration(final Class<?> clazz, final Object serviceInstance, final Dictionary<String, ?> props) {
319 final SchemaContextListener listener = (SchemaContextListener) serviceInstance;
320 final SchemaContext context = parseYangStreams(getFilesAsStreams(getYangModelsPaths()));
321 listener.onGlobalContextUpdated(context);
322 listener.onGlobalContextUpdated(context);
326 return super.getBundleContextServiceRegistrationHandler(serviceType);
329 public List<String> getYangModelsPaths() {
330 return Lists.newArrayList("/META-INF/yang/ietf-inet-types@2013-07-15.yang", "/META-INF/yang/programming.yang");
333 public List<ModuleFactory> getModuleFactories() {
334 return Lists.newArrayList(new InstructionSchedulerImplModuleFactory(), new HashedWheelTimerModuleFactory(),
335 new NotificationBrokerImplModuleFactory(), new DomBrokerImplModuleFactory(),
336 new RuntimeMappingModuleFactory(), new BindingBrokerImplModuleFactory(), new BindingAsyncDataBrokerImplModuleFactory(),
337 new DomInmemoryDataBrokerModuleFactory(), new SchemaServiceImplSingletonModuleFactory(),
338 new ForwardedCompatibleDataBrokerImplModuleFactory());
341 // TODO move back to AbstractConfigTest
342 private static List<InputStream> getFilesAsStreams(final List<String> paths) {
343 final List<InputStream> resources = new ArrayList<>();
344 final List<String> failedToFind = new ArrayList<>();
345 for (final String path : paths) {
346 final InputStream is = AbstractInstructionSchedulerTest.class.getResourceAsStream(path);
348 failedToFind.add(path);
353 Assert.assertEquals("Some files were not found", Collections.emptyList(), failedToFind);
358 private static YangTextSchemaContextResolver newSchemaContextResolver(final List<String> paths) {
359 final YangTextSchemaContextResolver resolver = YangTextSchemaContextResolver.create("test");
360 final List<String> failedToFind = new ArrayList<>();
361 for (final String path : paths) {
362 final URL url = AbstractInstructionSchedulerTest.class.getResource(path);
364 failedToFind.add(path);
367 resolver.registerSource(url);
368 } catch (SchemaSourceException | IOException | YangSyntaxErrorException e) {
369 Throwables.propagate(e);
373 Assert.assertEquals("Some files were not found", Collections.<String> emptyList(), failedToFind);
377 private static SchemaContext parseYangStreams(final List<InputStream> streams) {
379 return YangParserTestUtils.parseYangStreams(streams);
380 } catch (final ReactorException e) {
381 throw new RuntimeException("Unable to build schema context from " + streams, e);