Remove usage of RpcBrokerImplModule from the config test
[bgpcep.git] / programming / impl / src / test / java / org / opendaylight / controller / config / yang / programming / impl / AbstractInstructionSchedulerTest.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.config.yang.programming.impl;
9
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;
16
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;
27 import java.net.URL;
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;
33 import java.util.Set;
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;
88
89 public abstract class AbstractInstructionSchedulerTest extends AbstractConfigTest {
90
91     private static final String FACTORY_NAME = InstructionSchedulerImplModuleFactory.NAME;
92     private static final String INSTANCE_NAME = "instruction-scheduler-impl";
93
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";
101
102     @Mock
103     private RpcResult<TransactionStatus> mockedResult;
104
105     @SuppressWarnings("unchecked")
106     @Before
107     public void setUp() throws Exception {
108         MockitoAnnotations.initMocks(this);
109
110         final List<ModuleFactory> moduleFactories = getModuleFactories();
111         super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, moduleFactories.toArray(new ModuleFactory[moduleFactories.size()])));
112
113         doAnswer(new Answer<Filter>() {
114             @Override
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();
119                 return mockFilter;
120             }
121         }).when(mockedContext).createFilter(anyString());
122
123         Mockito.doReturn(new ServiceReference[] {}).when(mockedContext).getServiceReferences(Matchers.anyString(), Matchers.anyString());
124
125         final ServiceReference<?> classLoadingStrategySR = mock(ServiceReference.class, "ClassLoadingStrategy");
126         final ServiceReference<?> emptyServiceReference = mock(ServiceReference.class, "Empty");
127
128         Mockito.doNothing().when(mockedContext).addServiceListener(any(ServiceListener.class), Mockito.anyString());
129         Mockito.doNothing().when(mockedContext).removeServiceListener(any(ServiceListener.class));
130
131         Mockito.doNothing().when(mockedContext).addBundleListener(any(BundleListener.class));
132         Mockito.doNothing().when(mockedContext).removeBundleListener(any(BundleListener.class));
133
134         Mockito.doReturn(new Bundle[] {}).when(mockedContext).getBundles();
135
136         Mockito.doReturn(new ServiceReference[] {}).when(mockedContext).getServiceReferences(Matchers.anyString(), Matchers.anyString());
137
138         Mockito.doReturn("Class loading stategy reference").when(classLoadingStrategySR).toString();
139         Mockito.doReturn("Empty reference").when(emptyServiceReference).toString();
140
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);
144
145         Mockito.doReturn(GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy()).when(mockedContext).getService(classLoadingStrategySR);
146         Mockito.doReturn(null).when(mockedContext).getService(emptyServiceReference);
147
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();
152
153         final Field contextResolverField = schemaService.getClass().getDeclaredField("contextResolver");
154         contextResolverField.setAccessible(true);
155
156         final Field modifiersField = Field.class.getDeclaredField("modifiers");
157         modifiersField.setAccessible(true);
158         modifiersField.setInt(contextResolverField, contextResolverField.getModifiers() & ~Modifier.FINAL);
159
160         contextResolverField.set(schemaService, mockedContextResolver);
161
162         BindingToNormalizedNodeCodecFactory.getOrCreateInstance(
163                 GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy(), schemaService);
164
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));
171
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);
176     }
177
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);
185     }
186
187     @After
188     public void tearDownGlobalBundleScanningSchemaServiceImpl() throws Exception{
189         GlobalBundleScanningSchemaServiceImpl.destroyInstance();
190     }
191
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));
201         return objectName;
202     }
203
204     private ObjectName createTimerInstance(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException {
205         final ObjectName nameCreated = transaction.createModule(HashedWheelTimerModuleFactory.NAME, TIMER_INSTANCE_NAME);
206         return nameCreated;
207
208     }
209
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));
218         return objectName;
219     }
220
221     public ObjectName createNotificationBrokerInstance(final ConfigTransactionJMXClient transaction) throws Exception {
222         final ObjectName objectName = transaction.createModule(NotificationBrokerImplModuleFactory.NAME, NOTIFICATION_BROKER_INSTANCE_NAME);
223         return objectName;
224     }
225
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));
231         return nameCreated;
232     }
233
234     private static ObjectName lookupDataBrokerInstance(final ConfigTransactionJMXClient transaction) {
235         try {
236             return transaction.lookupConfigBean(BindingAsyncDataBrokerImplModuleFactory.NAME, BINDING_ASYNC_BROKER_INSTANCE_NAME);
237         } catch (final InstanceNotFoundException e) {
238             try {
239                 return transaction.createModule(RuntimeMappingModuleFactory.NAME, RuntimeMappingModuleFactory.SINGLETON_NAME);
240             } catch (final InstanceAlreadyExistsException e1) {
241                 throw new IllegalStateException(e1);
242             }
243         }
244     }
245
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));
252         return nameCreated;
253     }
254
255     private static ObjectName lookupMappingServiceInstance(final ConfigTransactionJMXClient transaction) {
256         try {
257             return transaction.lookupConfigBean(RuntimeMappingModuleFactory.NAME, RuntimeMappingModuleFactory.SINGLETON_NAME);
258         } catch (final InstanceNotFoundException e) {
259             try {
260                 return transaction.createModule(RuntimeMappingModuleFactory.NAME, RuntimeMappingModuleFactory.SINGLETON_NAME);
261             } catch (final InstanceAlreadyExistsException e1) {
262                 throw new IllegalStateException(e1);
263             }
264         }
265     }
266
267     private static ObjectName lookupSchemaServiceInstance(final ConfigTransactionJMXClient transaction) {
268         try {
269             return transaction.lookupConfigBean(SchemaServiceImplSingletonModuleFactory.NAME, SchemaServiceImplSingletonModuleFactory.SINGLETON_NAME);
270         } catch (final InstanceNotFoundException e) {
271             try {
272                 return transaction.createModule(SchemaServiceImplSingletonModuleFactory.NAME, SchemaServiceImplSingletonModuleFactory.SINGLETON_NAME);
273             } catch (final InstanceAlreadyExistsException e1) {
274                 throw new IllegalStateException(e1);
275             }
276         }
277     }
278
279     public static ObjectName lookupDomBrokerInstance(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException {
280         try {
281             return transaction.lookupConfigBean(DomBrokerImplModuleFactory.NAME, DOM_BROKER_INSTANCE_NAME);
282         } catch (final InstanceNotFoundException e) {
283             try {
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));
287                 return nameCreated;
288             } catch (final InstanceAlreadyExistsException e1) {
289                 throw new IllegalStateException(e1);
290             }
291         }
292     }
293
294     private static ObjectName lookupDomAsyncDataBroker(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException {
295         try {
296             return transaction.lookupConfigBean(DomInmemoryDataBrokerModuleFactory.NAME, DOM_ASYNC_DATA_BROKER_INSTANCE);
297         } catch (final InstanceNotFoundException e) {
298             try {
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));
302                 return nameCreated;
303             } catch (final InstanceAlreadyExistsException e1) {
304                 throw new IllegalStateException(e1);
305             }
306         }
307     }
308
309     @Override
310     protected BundleContextServiceRegistrationHandler getBundleContextServiceRegistrationHandler(final Class<?> serviceType) {
311         if (serviceType.equals(SchemaContextListener.class)) {
312             return new BundleContextServiceRegistrationHandler() {
313                 @Override
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);
319                 }
320             };
321         }
322         return super.getBundleContextServiceRegistrationHandler(serviceType);
323     }
324
325     public List<String> getYangModelsPaths() {
326         final List<String> paths = Lists.newArrayList("/META-INF/yang/ietf-inet-types.yang", "/META-INF/yang/programming.yang");
327         return paths;
328     }
329
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());
336     }
337
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);
344             if (url == null) {
345                 failedToFind.add(path);
346             } else {
347                 resources.add(Resources.asByteSource(url));
348             }
349         }
350         Assert.assertEquals("Some files were not found", Collections.<String> emptyList(), failedToFind);
351
352         return resources;
353     }
354
355     private static SchemaContext parseYangStreams(final Collection<ByteSource> streams) {
356         final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR
357                 .newBuild();
358         try {
359             return reactor.buildEffective(streams);
360         } catch (final ReactorException | IOException e) {
361             throw new RuntimeException("Unable to build schema context from " + streams, e);
362         }
363     }
364
365 }