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