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;
20 import java.lang.reflect.Modifier;
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;
82 public abstract class AbstractRIBImplModuleTest extends AbstractConfigTest {
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";
88 protected static final RibId RIB_ID = new RibId("test");
89 protected static final Ipv4Address BGP_ID = new Ipv4Address("192.168.1.1");
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";
99 private ReadWriteTransaction mockedTransaction;
102 private DataBroker mockedDataProvider;
105 private CheckedFuture<Void, TransactionCommitFailedException> mockedFuture;
108 private RpcResult<TransactionStatus> mockedResult;
110 @SuppressWarnings("unchecked")
112 public void setUp() throws Exception {
113 MockitoAnnotations.initMocks(this);
115 List<ModuleFactory> moduleFactories = getModuleFactories();
116 super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, moduleFactories.toArray(new ModuleFactory[moduleFactories.size()])));
118 Filter mockedFilter = mock(Filter.class);
119 Mockito.doReturn(mockedFilter).when(mockedContext).createFilter(Mockito.anyString());
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");
125 Mockito.doReturn(mockedFilter).when(mockedContext).createFilter(Mockito.anyString());
127 Mockito.doNothing().when(mockedContext).addServiceListener(any(ServiceListener.class), Mockito.anyString());
128 Mockito.doNothing().when(mockedContext).removeServiceListener(any(ServiceListener.class));
130 Mockito.doNothing().when(mockedContext).addBundleListener(any(BundleListener.class));
131 Mockito.doNothing().when(mockedContext).removeBundleListener(any(BundleListener.class));
133 Mockito.doReturn(new Bundle[] {}).when(mockedContext).getBundles();
135 Mockito.doReturn(new ServiceReference[] {}).when(mockedContext).getServiceReferences(Matchers.anyString(), Matchers.anyString());
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();
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);
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);
149 Mockito.doReturn(mockedTransaction).when(mockedDataProvider).newReadWriteTransaction();
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));
155 Mockito.doReturn(mockedFuture).when(mockedTransaction).submit();
156 Mockito.doReturn(TRANSACTION_NAME).when(mockedTransaction).getIdentifier();
158 Mockito.doReturn(null).when(mockedFuture).get();
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();
166 final Field contextResolverField = schemaService.getClass().getDeclaredField("contextResolver");
167 contextResolverField.setAccessible(true);
169 final Field modifiersField = Field.class.getDeclaredField("modifiers");
170 modifiersField.setAccessible(true);
171 modifiersField.setInt(contextResolverField, contextResolverField.getModifiers() & ~Modifier.FINAL);
173 contextResolverField.set(schemaService, mockedContextResolver);
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());
186 protected BundleContextServiceRegistrationHandler getBundleContextServiceRegistrationHandler(final Class<?> serviceType) {
187 if (serviceType.equals(SchemaContextListener.class)) {
188 return new BundleContextServiceRegistrationHandler() {
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;
195 context = parser.parseSources(getFilesAsByteSources(getYangModelsPaths()));
196 } catch (IOException | YangSyntaxErrorException e) {
197 throw new IllegalStateException("Failed to parse models", e);
199 listener.onGlobalContextUpdated(context);
204 return super.getBundleContextServiceRegistrationHandler(serviceType);
208 public void closeAllModules() throws Exception {
209 super.destroyAllConfigBeans();
210 GlobalBundleScanningSchemaServiceImpl.destroyInstance();
214 protected CommitStatus createInstance() throws Exception {
215 ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
216 createRIBImplModuleInstance(transaction);
217 return transaction.commit();
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();
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);
243 protected ObjectName createRIBImplModuleInstance(final ConfigTransactionJMXClient transaction) throws Exception {
244 return createRIBImplModuleInstance(transaction, RIB_ID, 5000L, BGP_ID,
245 createAsyncDataBrokerInstance(transaction));
248 public ObjectName createRIBImplModuleInstance(final ConfigTransactionJMXClient transaction, final ObjectName dataBroker)
250 return createRIBImplModuleInstance(transaction, RIB_ID, 5000L, BGP_ID, dataBroker);
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));
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));
268 private static ObjectName lookupMappingServiceInstance(final ConfigTransactionJMXClient transaction) {
270 return transaction.lookupConfigBean(RuntimeMappingModuleFactory.NAME, RuntimeMappingModuleFactory.SINGLETON_NAME);
271 } catch (InstanceNotFoundException e) {
273 return transaction.createModule(RuntimeMappingModuleFactory.NAME, RuntimeMappingModuleFactory.SINGLETON_NAME);
274 } catch (InstanceAlreadyExistsException e1) {
275 throw new IllegalStateException(e1);
280 private static ObjectName lookupSchemaServiceInstance(final ConfigTransactionJMXClient transaction) {
282 return transaction.lookupConfigBean(SchemaServiceImplSingletonModuleFactory.NAME, SchemaServiceImplSingletonModuleFactory.SINGLETON_NAME);
283 } catch (InstanceNotFoundException e) {
285 return transaction.createModule(SchemaServiceImplSingletonModuleFactory.NAME, SchemaServiceImplSingletonModuleFactory.SINGLETON_NAME);
286 } catch (InstanceAlreadyExistsException e1) {
287 throw new IllegalStateException(e1);
292 public static ObjectName lookupDomBrokerInstance(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException {
294 return transaction.lookupConfigBean(DomBrokerImplModuleFactory.NAME, DOM_BROKER_INSTANCE_NAME);
295 } catch (InstanceNotFoundException e) {
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));
301 } catch (InstanceAlreadyExistsException e1) {
302 throw new IllegalStateException(e1);
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);
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");
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);
326 failedToFind.add(path);
328 resources.add(Resources.asByteSource(url));
331 Assert.assertEquals("Some files were not found", Collections.<String> emptyList(), failedToFind);