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.bgp.rib.impl;
10 import static org.mockito.Matchers.any;
11 import static org.mockito.Mockito.mock;
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;
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;
83 public abstract class AbstractRIBImplModuleTest extends AbstractConfigTest {
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";
89 private static final String RIB_ID = "test";
90 private static final String BGP_ID = "192.168.1.1";
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";
100 private ReadWriteTransaction mockedTransaction;
103 private DataBroker mockedDataProvider;
106 private CheckedFuture<Void, TransactionCommitFailedException> mockedFuture;
109 private RpcResult<TransactionStatus> mockedResult;
111 @SuppressWarnings("unchecked")
113 public void setUp() throws Exception {
114 MockitoAnnotations.initMocks(this);
116 List<ModuleFactory> moduleFactories = getModuleFactories();
117 super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, moduleFactories.toArray(new ModuleFactory[moduleFactories.size()])));
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));
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");
128 Mockito.doReturn(mockedFilter).when(mockedContext).createFilter(Mockito.anyString());
130 Mockito.doNothing().when(mockedContext).addServiceListener(any(ServiceListener.class), Mockito.anyString());
131 Mockito.doNothing().when(mockedContext).removeServiceListener(any(ServiceListener.class));
133 Mockito.doNothing().when(mockedContext).addBundleListener(any(BundleListener.class));
134 Mockito.doNothing().when(mockedContext).removeBundleListener(any(BundleListener.class));
136 Mockito.doReturn(new Bundle[] {}).when(mockedContext).getBundles();
138 Mockito.doReturn(new ServiceReference[] {}).when(mockedContext).getServiceReferences(Matchers.anyString(), Matchers.anyString());
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();
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);
148 Mockito.doReturn(mockedDataProvider).when(mockedContext).getService(dataProviderServiceReference);
149 Mockito.doReturn(mockedClassLoadingStrategy).when(mockedContext).getService(classLoadingStrategySR);
150 Mockito.doReturn(null).when(mockedContext).getService(emptyServiceReference);
152 Mockito.doReturn(mockedTransaction).when(mockedDataProvider).newReadWriteTransaction();
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));
158 Mockito.doReturn(mockedFuture).when(mockedTransaction).submit();
159 Mockito.doReturn(TRANSACTION_NAME).when(mockedTransaction).getIdentifier();
161 Mockito.doReturn(null).when(mockedFuture).get();
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();
169 final Field contextResolverField = schemaService.getClass().getDeclaredField("contextResolver");
170 contextResolverField.setAccessible(true);
171 contextResolverField.set(schemaService, mockedContextResolver);
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());
185 protected BundleContextServiceRegistrationHandler getBundleContextServiceRegistrationHandler(final Class<?> serviceType) {
186 if (serviceType.equals(SchemaContextListener.class)) {
187 return new BundleContextServiceRegistrationHandler() {
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;
194 context = parser.parseSources(getFilesAsByteSources(getYangModelsPaths()));
195 } catch (IOException | YangSyntaxErrorException e) {
196 throw new IllegalStateException("Failed to parse models", e);
198 listener.onGlobalContextUpdated(context);
203 return super.getBundleContextServiceRegistrationHandler(serviceType);
207 public void closeAllModules() throws Exception {
208 super.destroyAllConfigBeans();
209 GlobalBundleScanningSchemaServiceImpl.destroyInstance();
213 protected CommitStatus createInstance() throws Exception {
214 ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
215 createRIBImplModuleInstance(transaction);
216 return transaction.commit();
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();
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);
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));
247 public ObjectName createRIBImplModuleInstance(final ConfigTransactionJMXClient transaction, final ObjectName dataBroker)
249 return createRIBImplModuleInstance(transaction, new RibId(RIB_ID), 5000L, new Ipv4Address(BGP_ID), dataBroker);
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));
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));
267 private static ObjectName lookupMappingServiceInstance(final ConfigTransactionJMXClient transaction) {
269 return transaction.lookupConfigBean(RuntimeMappingModuleFactory.NAME, RuntimeMappingModuleFactory.SINGLETON_NAME);
270 } catch (InstanceNotFoundException e) {
272 return transaction.createModule(RuntimeMappingModuleFactory.NAME, RuntimeMappingModuleFactory.SINGLETON_NAME);
273 } catch (InstanceAlreadyExistsException e1) {
274 throw new IllegalStateException(e1);
279 private static ObjectName lookupSchemaServiceInstance(final ConfigTransactionJMXClient transaction) {
281 return transaction.lookupConfigBean(SchemaServiceImplSingletonModuleFactory.NAME, SchemaServiceImplSingletonModuleFactory.SINGLETON_NAME);
282 } catch (InstanceNotFoundException e) {
284 return transaction.createModule(SchemaServiceImplSingletonModuleFactory.NAME, SchemaServiceImplSingletonModuleFactory.SINGLETON_NAME);
285 } catch (InstanceAlreadyExistsException e1) {
286 throw new IllegalStateException(e1);
291 public static ObjectName lookupDomBrokerInstance(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException {
293 return transaction.lookupConfigBean(DomBrokerImplModuleFactory.NAME, DOM_BROKER_INSTANCE_NAME);
294 } catch (InstanceNotFoundException e) {
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));
300 } catch (InstanceAlreadyExistsException e1) {
301 throw new IllegalStateException(e1);
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);
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");
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);
325 failedToFind.add(path);
327 resources.add(Resources.asByteSource(url));
330 Assert.assertEquals("Some files were not found", Collections.<String> emptyList(), failedToFind);