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