BUG-868: migrate SchemaServiceListener users
[bgpcep.git] / bgp / rib-impl / src / test / java / org / opendaylight / controller / config / yang / bgp / rib / impl / AbstractRIBImplModuleTest.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.bgp.rib.impl;
9
10 import static org.mockito.Matchers.any;
11 import static org.mockito.Mockito.mock;
12
13 import com.google.common.base.Optional;
14 import com.google.common.collect.Lists;
15 import com.google.common.io.ByteSource;
16 import com.google.common.io.Resources;
17 import com.google.common.util.concurrent.CheckedFuture;
18
19 import java.io.IOException;
20 import java.lang.reflect.Field;
21 import java.net.URL;
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.Dictionary;
26 import java.util.List;
27
28 import javax.management.InstanceAlreadyExistsException;
29 import javax.management.InstanceNotFoundException;
30 import javax.management.ObjectName;
31
32 import org.junit.After;
33 import org.junit.Assert;
34 import org.junit.Before;
35 import org.mockito.Matchers;
36 import org.mockito.Mock;
37 import org.mockito.Mockito;
38 import org.mockito.MockitoAnnotations;
39 import org.opendaylight.controller.config.api.jmx.CommitStatus;
40 import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
41 import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
42 import org.opendaylight.controller.config.spi.ModuleFactory;
43 import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
44 import org.opendaylight.controller.config.yang.bgp.parser.spi.SimpleBGPExtensionProviderContextModuleFactory;
45 import org.opendaylight.controller.config.yang.bgp.rib.spi.RIBExtensionsImplModuleFactory;
46 import org.opendaylight.controller.config.yang.bgp.rib.spi.RIBExtensionsImplModuleMXBean;
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.DataBrokerImplModuleFactory;
50 import org.opendaylight.controller.config.yang.md.sal.binding.impl.DataBrokerImplModuleMXBean;
51 import org.opendaylight.controller.config.yang.md.sal.binding.impl.RuntimeMappingModuleFactory;
52 import org.opendaylight.controller.config.yang.md.sal.dom.impl.DomBrokerImplModuleFactory;
53 import org.opendaylight.controller.config.yang.md.sal.dom.impl.DomBrokerImplModuleMXBean;
54 import org.opendaylight.controller.config.yang.md.sal.dom.impl.DomInmemoryDataBrokerModuleFactory;
55 import org.opendaylight.controller.config.yang.md.sal.dom.impl.DomInmemoryDataBrokerModuleMXBean;
56 import org.opendaylight.controller.config.yang.md.sal.dom.impl.SchemaServiceImplSingletonModuleFactory;
57 import org.opendaylight.controller.config.yang.netty.eventexecutor.GlobalEventExecutorModuleFactory;
58 import org.opendaylight.controller.config.yang.netty.threadgroup.NettyThreadgroupModuleFactory;
59 import org.opendaylight.controller.config.yang.netty.timer.HashedWheelTimerModuleFactory;
60 import org.opendaylight.controller.config.yang.protocol.framework.TimedReconnectStrategyFactoryModuleFactory;
61 import org.opendaylight.controller.config.yang.protocol.framework.TimedReconnectStrategyModuleTest;
62 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
63 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
64 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
65 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
66 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
67 import org.opendaylight.controller.sal.dom.broker.GlobalBundleScanningSchemaServiceImpl;
68 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.RibId;
70 import org.opendaylight.yangtools.yang.binding.DataObject;
71 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
72 import org.opendaylight.yangtools.yang.common.RpcResult;
73 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
74 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
75 import org.opendaylight.yangtools.yang.model.parser.api.YangContextParser;
76 import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
77 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
78 import org.opendaylight.yangtools.yang.parser.impl.util.URLSchemaContextResolver;
79 import org.osgi.framework.Bundle;
80 import org.osgi.framework.BundleListener;
81 import org.osgi.framework.Filter;
82 import org.osgi.framework.ServiceListener;
83 import org.osgi.framework.ServiceReference;
84
85 public abstract class AbstractRIBImplModuleTest extends AbstractConfigTest {
86
87     private static final String INSTANCE_NAME = "rib-impl";
88     private static final String FACTORY_NAME = RIBImplModuleFactory.NAME;
89     private static final String TRANSACTION_NAME = "testTransaction";
90
91     private static final String RIB_ID = "test";
92     private static final String BGP_ID = "192.168.1.1";
93
94     private static final String SESSION_RS_INSTANCE_NAME = "session-reconnect-strategy-factory";
95     private static final String TCP_RS_INSTANCE_NAME = "tcp-reconnect-strategy-factory";
96     private static final String RIB_EXTENSIONS_INSTANCE_NAME = "rib-extensions-impl";
97     private static final String DOM_BROKER_INSTANCE_NAME = "dom-broker-impl";
98     private static final String BINDING_ASYNC_BROKER_INSTANCE_NAME = "binding-async-broker-instance";
99     private static final String DOM_ASYNC_DATA_BROKER_INSTANCE = "dom-inmemory-data-broker";
100     private static final String DATA_BROKER_INSTANCE_NAME = "data-broker-instance";
101
102     @Mock
103     private ReadWriteTransaction mockedTransaction;
104
105     @Mock
106     private DataBroker mockedDataProvider;
107
108     @Mock
109     private CheckedFuture<Void, TransactionCommitFailedException> mockedFuture;
110
111     @Mock
112     private RpcResult<TransactionStatus> mockedResult;
113
114     @SuppressWarnings("unchecked")
115     @Before
116     public void setUp() throws Exception {
117         MockitoAnnotations.initMocks(this);
118
119         List<ModuleFactory> moduleFactories = getModuleFactories();
120         super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, moduleFactories.toArray(new ModuleFactory[moduleFactories.size()])));
121
122         Filter mockedFilter = mock(Filter.class);
123         Mockito.doReturn(mockedFilter).when(mockedContext).createFilter(Mockito.anyString());
124
125         ServiceReference<?> emptyServiceReference = mock(ServiceReference.class, "Empty");
126
127         ServiceReference<?> dataProviderServiceReference = mock(ServiceReference.class, "Data Provider");
128
129         Mockito.doReturn(mockedFilter).when(mockedContext).createFilter(Mockito.anyString());
130
131         Mockito.doNothing().when(mockedContext).addServiceListener(any(ServiceListener.class), Mockito.anyString());
132         Mockito.doNothing().when(mockedContext).removeServiceListener(any(ServiceListener.class));
133
134         Mockito.doNothing().when(mockedContext).addBundleListener(any(BundleListener.class));
135         Mockito.doNothing().when(mockedContext).removeBundleListener(any(BundleListener.class));
136
137         Mockito.doReturn(new Bundle[] {}).when(mockedContext).getBundles();
138
139         Mockito.doReturn(new ServiceReference[] {}).when(mockedContext).getServiceReferences(Matchers.anyString(), Matchers.anyString());
140
141         Mockito.doReturn("Empty reference").when(emptyServiceReference).toString();
142         Mockito.doReturn("Data Provider Service Reference").when(dataProviderServiceReference).toString();
143
144         Mockito.doReturn(emptyServiceReference).when(mockedContext).getServiceReference(any(Class.class));
145         Mockito.doReturn(dataProviderServiceReference).when(mockedContext).getServiceReference(DataBroker.class);
146
147         Mockito.doReturn(mockedDataProvider).when(mockedContext).getService(dataProviderServiceReference);
148
149         Mockito.doReturn(null).when(mockedContext).getService(emptyServiceReference);
150
151         Mockito.doReturn(mockedTransaction).when(mockedDataProvider).newReadWriteTransaction();
152
153         Mockito.doReturn(null).when(mockedTransaction).read(Mockito.eq(LogicalDatastoreType.OPERATIONAL), any(InstanceIdentifier.class));
154         Mockito.doNothing().when(mockedTransaction).put(Mockito.eq(LogicalDatastoreType.OPERATIONAL), any(InstanceIdentifier.class), any(DataObject.class));
155         Mockito.doNothing().when(mockedTransaction).delete(Mockito.eq(LogicalDatastoreType.OPERATIONAL), any(InstanceIdentifier.class));
156
157         Mockito.doReturn(mockedFuture).when(mockedTransaction).submit();
158         Mockito.doReturn(TRANSACTION_NAME).when(mockedTransaction).getIdentifier();
159
160         Mockito.doReturn(null).when(mockedFuture).get();
161
162         GlobalBundleScanningSchemaServiceImpl schemaService = GlobalBundleScanningSchemaServiceImpl.createInstance(this.mockedContext);
163         YangContextParser parser = new YangParserImpl();
164         SchemaContext context = parser.parseSources(getFilesAsByteSources(getYangModelsPaths()));
165         URLSchemaContextResolver mockedContextResolver = Mockito.mock(URLSchemaContextResolver.class);
166         Mockito.doReturn(Optional.of(context)).when(mockedContextResolver).getSchemaContext();
167
168         final Field contextResolverField = schemaService.getClass().getDeclaredField("contextResolver");
169         contextResolverField.setAccessible(true);
170         contextResolverField.set(schemaService, mockedContextResolver);
171
172     }
173
174     protected List<ModuleFactory> getModuleFactories() {
175         return Lists.newArrayList(new RIBImplModuleFactory(), new DataBrokerImplModuleFactory(), new GlobalEventExecutorModuleFactory(),
176                 new BGPDispatcherImplModuleFactory(), new NettyThreadgroupModuleFactory(),
177                 new TimedReconnectStrategyFactoryModuleFactory(), new SimpleBGPExtensionProviderContextModuleFactory(),
178                 new RIBExtensionsImplModuleFactory(), new DomBrokerImplModuleFactory(), new RuntimeMappingModuleFactory(),
179                 new HashedWheelTimerModuleFactory(), new BindingAsyncDataBrokerImplModuleFactory(),
180                 new DomInmemoryDataBrokerModuleFactory(), new SchemaServiceImplSingletonModuleFactory());
181     }
182
183     @Override
184     protected BundleContextServiceRegistrationHandler getBundleContextServiceRegistrationHandler(final Class<?> serviceType) {
185         if (serviceType.equals(SchemaContextListener.class)) {
186             return new BundleContextServiceRegistrationHandler() {
187                 @Override
188                 public void handleServiceRegistration(final Class<?> clazz, final Object serviceInstance, final Dictionary<String, ?> props) {
189                     SchemaContextListener listener = (SchemaContextListener) serviceInstance;
190                     YangContextParser parser = new YangParserImpl();
191                     final SchemaContext context;
192                     try {
193                         context = parser.parseSources(getFilesAsByteSources(getYangModelsPaths()));
194                     } catch (IOException | YangSyntaxErrorException e) {
195                         throw new IllegalStateException("Failed to parse models", e);
196                     }
197                     listener.onGlobalContextUpdated(context);
198                 }
199             };
200         }
201
202         return super.getBundleContextServiceRegistrationHandler(serviceType);
203     }
204
205     @After
206     public void closeAllModules() throws Exception {
207         super.destroyAllConfigBeans();
208         GlobalBundleScanningSchemaServiceImpl.destroyInstance();
209
210     }
211
212     protected CommitStatus createInstance() throws Exception {
213         ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
214         createRIBImplModuleInstance(transaction);
215         return transaction.commit();
216     }
217
218     protected CommitStatus createRIBImplModuleInstance(final RibId ribId, final Long localAs, final Ipv4Address bgpId) throws Exception {
219         ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
220         createRIBImplModuleInstance(transaction, ribId, localAs, bgpId, createAsyncDataBrokerInstance(transaction));
221         return transaction.commit();
222     }
223
224     private ObjectName createRIBImplModuleInstance(final ConfigTransactionJMXClient transaction, final RibId ribId, final Long localAs,
225             final Ipv4Address bgpId, final ObjectName dataBroker) throws Exception {
226         ObjectName nameCreated = transaction.createModule(FACTORY_NAME, INSTANCE_NAME);
227         RIBImplModuleMXBean mxBean = transaction.newMXBeanProxy(nameCreated, RIBImplModuleMXBean.class);
228         ObjectName reconnectObjectName = TimedReconnectStrategyModuleTest.createInstance(transaction, SESSION_RS_INSTANCE_NAME);
229         mxBean.setSessionReconnectStrategy(reconnectObjectName);
230         mxBean.setDataProvider(dataBroker);
231         ObjectName reconnectStrategyON = TimedReconnectStrategyModuleTest.createInstance(transaction, TCP_RS_INSTANCE_NAME);
232         mxBean.setTcpReconnectStrategy(reconnectStrategyON);
233         mxBean.setBgpDispatcher(BGPDispatcherImplModuleTest.createInstance(transaction));
234         mxBean.setExtensions(createRibExtensionsInstance(transaction));
235         mxBean.setRibId(ribId);
236         mxBean.setLocalAs(localAs);
237         mxBean.setBgpId(bgpId);
238         return nameCreated;
239     }
240
241     protected ObjectName createRIBImplModuleInstance(final ConfigTransactionJMXClient transaction) throws Exception {
242         return createRIBImplModuleInstance(transaction, new RibId(RIB_ID), 5000L, new Ipv4Address(BGP_ID),
243                 createAsyncDataBrokerInstance(transaction));
244     }
245
246     public ObjectName createRIBImplModuleInstance(final ConfigTransactionJMXClient transaction, final ObjectName dataBroker)
247             throws Exception {
248         return createRIBImplModuleInstance(transaction, new RibId(RIB_ID), 5000L, new Ipv4Address(BGP_ID), dataBroker);
249     }
250
251     public ObjectName createDataBrokerInstance(final ConfigTransactionJMXClient transaction)
252             throws InstanceAlreadyExistsException, InstanceNotFoundException {
253         ObjectName nameCreated = transaction.createModule(DataBrokerImplModuleFactory.NAME, DATA_BROKER_INSTANCE_NAME);
254         DataBrokerImplModuleMXBean mxBean = transaction.newMXBeanProxy(nameCreated, DataBrokerImplModuleMXBean.class);
255         mxBean.setDomBroker(lookupDomBrokerInstance(transaction));
256         mxBean.setMappingService(lookupMappingServiceInstance(transaction));
257         return nameCreated;
258     }
259
260     public ObjectName createAsyncDataBrokerInstance(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException, InstanceNotFoundException {
261         final ObjectName nameCreated = transaction.createModule(BindingAsyncDataBrokerImplModuleFactory.NAME, BINDING_ASYNC_BROKER_INSTANCE_NAME);
262         final BindingAsyncDataBrokerImplModuleMXBean mxBean = transaction.newMXBeanProxy(nameCreated, BindingAsyncDataBrokerImplModuleMXBean.class);
263         mxBean.setBindingMappingService(lookupMappingServiceInstance(transaction));
264         mxBean.setDomAsyncBroker(lookupDomBrokerInstance(transaction));
265         return nameCreated;
266     }
267
268     private static ObjectName createDomAsyncDataBroker(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException {
269         final ObjectName nameCreated = transaction.createModule(DomInmemoryDataBrokerModuleFactory.NAME, DOM_ASYNC_DATA_BROKER_INSTANCE);
270         final DomInmemoryDataBrokerModuleMXBean mxBean = transaction.newMXBeanProxy(nameCreated, DomInmemoryDataBrokerModuleMXBean.class);
271         mxBean.setSchemaService(lookupSchemaServiceInstance(transaction));
272         return nameCreated;
273     }
274
275     private static ObjectName lookupMappingServiceInstance(final ConfigTransactionJMXClient transaction) {
276         try {
277             return transaction.lookupConfigBean(RuntimeMappingModuleFactory.NAME, RuntimeMappingModuleFactory.SINGLETON_NAME);
278         } catch (InstanceNotFoundException e) {
279             try {
280                 return transaction.createModule(RuntimeMappingModuleFactory.NAME, RuntimeMappingModuleFactory.SINGLETON_NAME);
281             } catch (InstanceAlreadyExistsException e1) {
282                 throw new IllegalStateException(e1);
283             }
284         }
285     }
286
287     private static ObjectName lookupSchemaServiceInstance(final ConfigTransactionJMXClient transaction) {
288         try {
289             return transaction.lookupConfigBean(SchemaServiceImplSingletonModuleFactory.NAME, SchemaServiceImplSingletonModuleFactory.SINGLETON_NAME);
290         } catch (InstanceNotFoundException e) {
291             try {
292                 return transaction.createModule(SchemaServiceImplSingletonModuleFactory.NAME, SchemaServiceImplSingletonModuleFactory.SINGLETON_NAME);
293             } catch (InstanceAlreadyExistsException e1) {
294                 throw new IllegalStateException(e1);
295             }
296         }
297     }
298
299     public static ObjectName lookupDomBrokerInstance(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException {
300         try {
301             return transaction.lookupConfigBean(DomBrokerImplModuleFactory.NAME, DOM_BROKER_INSTANCE_NAME);
302         } catch (InstanceNotFoundException e) {
303             try {
304                 final ObjectName nameCreated = transaction.createModule(DomBrokerImplModuleFactory.NAME, DOM_BROKER_INSTANCE_NAME);
305                 final DomBrokerImplModuleMXBean mxBean = transaction.newMXBeanProxy(nameCreated, DomBrokerImplModuleMXBean.class);
306                 mxBean.setAsyncDataBroker(createDomAsyncDataBroker(transaction));
307                 return nameCreated;
308             } catch (InstanceAlreadyExistsException e1) {
309                 throw new IllegalStateException(e1);
310             }
311         }
312     }
313
314     private ObjectName createRibExtensionsInstance(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException {
315         ObjectName nameCreated = transaction.createModule(RIBExtensionsImplModuleFactory.NAME, RIB_EXTENSIONS_INSTANCE_NAME);
316         transaction.newMXBeanProxy(nameCreated, RIBExtensionsImplModuleMXBean.class);
317         return nameCreated;
318     }
319
320     public List<String> getYangModelsPaths() {
321         List<String> paths = Lists.newArrayList("/META-INF/yang/bgp-rib.yang", "/META-INF/yang/ietf-inet-types.yang",
322                 "/META-INF/yang/bgp-message.yang", "/META-INF/yang/bgp-multiprotocol.yang", "/META-INF/yang/bgp-types.yang");
323         return paths;
324     }
325
326     // TODO move back to AbstractConfigTest
327     private static Collection<ByteSource> getFilesAsByteSources(final List<String> paths) {
328         final Collection<ByteSource> resources = new ArrayList<>();
329         List<String> failedToFind = new ArrayList<>();
330         for (String path : paths) {
331             URL url = AbstractRIBImplModuleTest.class.getResource(path);
332             if (url == null) {
333                 failedToFind.add(path);
334             } else {
335                 resources.add(Resources.asByteSource(url));
336             }
337         }
338         Assert.assertEquals("Some files were not found", Collections.<String> emptyList(), failedToFind);
339
340         return resources;
341     }
342 }