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.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.yangtools.sal.binding.generator.impl.GeneratedClassLoadingStrategy;
66 import org.opendaylight.yangtools.yang.binding.DataObject;
67 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
68 import org.opendaylight.yangtools.yang.common.RpcResult;
69 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
70 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
71 import org.opendaylight.yangtools.yang.model.parser.api.YangContextParser;
72 import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
73 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
74 import org.opendaylight.yangtools.yang.parser.repo.URLSchemaContextResolver;
75 import org.osgi.framework.Bundle;
76 import org.osgi.framework.BundleListener;
77 import org.osgi.framework.Filter;
78 import org.osgi.framework.ServiceListener;
79 import org.osgi.framework.ServiceReference;
81 public abstract class AbstractRIBImplModuleTest extends AbstractConfigTest {
83 private static final String INSTANCE_NAME = "rib-impl";
84 private static final String FACTORY_NAME = RIBImplModuleFactory.NAME;
85 private static final String TRANSACTION_NAME = "testTransaction";
87 protected static final RibId RIB_ID = new RibId("test");
88 protected static final Ipv4Address BGP_ID = new Ipv4Address("192.168.1.1");
89 protected static final Ipv4Address CLUSTER_ID = new Ipv4Address("192.168.1.2");
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 final List<ModuleFactory> moduleFactories = getModuleFactories();
116 super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(this.mockedContext, moduleFactories.toArray(new ModuleFactory[moduleFactories.size()])));
118 final Filter mockedFilter = mock(Filter.class);
119 Mockito.doReturn(mockedFilter).when(this.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(this.mockedContext).createFilter(Mockito.anyString());
127 Mockito.doNothing().when(this.mockedContext).addServiceListener(any(ServiceListener.class), Mockito.anyString());
128 Mockito.doNothing().when(this.mockedContext).removeServiceListener(any(ServiceListener.class));
130 Mockito.doNothing().when(this.mockedContext).addBundleListener(any(BundleListener.class));
131 Mockito.doNothing().when(this.mockedContext).removeBundleListener(any(BundleListener.class));
133 Mockito.doReturn(new Bundle[] {}).when(this.mockedContext).getBundles();
135 Mockito.doReturn(new ServiceReference[] {}).when(this.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(this.mockedContext).getServiceReference(any(Class.class));
142 Mockito.doReturn(dataProviderServiceReference).when(this.mockedContext).getServiceReference(DataBroker.class);
143 Mockito.doReturn(classLoadingStrategySR).when(this.mockedContext).getServiceReference(GeneratedClassLoadingStrategy.class);
145 Mockito.doReturn(this.mockedDataProvider).when(this.mockedContext).getService(dataProviderServiceReference);
146 Mockito.doReturn(GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy()).when(this.mockedContext).getService(classLoadingStrategySR);
147 Mockito.doReturn(null).when(this.mockedContext).getService(emptyServiceReference);
149 Mockito.doReturn(this.mockedTransaction).when(this.mockedDataProvider).newReadWriteTransaction();
151 Mockito.doReturn(null).when(this.mockedTransaction).read(Mockito.eq(LogicalDatastoreType.OPERATIONAL), any(InstanceIdentifier.class));
152 Mockito.doNothing().when(this.mockedTransaction).put(Mockito.eq(LogicalDatastoreType.OPERATIONAL), any(InstanceIdentifier.class), any(DataObject.class));
153 Mockito.doNothing().when(this.mockedTransaction).delete(Mockito.eq(LogicalDatastoreType.OPERATIONAL), any(InstanceIdentifier.class));
155 Mockito.doReturn(this.mockedFuture).when(this.mockedTransaction).submit();
156 Mockito.doReturn(TRANSACTION_NAME).when(this.mockedTransaction).getIdentifier();
158 Mockito.doReturn(null).when(this.mockedFuture).get();
160 final GlobalBundleScanningSchemaServiceImpl schemaService = GlobalBundleScanningSchemaServiceImpl.createInstance(this.mockedContext);
161 final YangContextParser parser = new YangParserImpl();
162 final SchemaContext context = parser.parseSources(getFilesAsByteSources(getYangModelsPaths()));
163 final 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 final SchemaContextListener listener = (SchemaContextListener) serviceInstance;
192 final 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 final ConfigTransactionJMXClient transaction = this.configRegistryClient.createTransaction();
216 createRIBImplModuleInstance(transaction);
217 return transaction.commit();
220 protected CommitStatus createRIBImplModuleInstance(final RibId ribId, final Long localAs, final Ipv4Address bgpId, final Ipv4Address clusterId) throws Exception {
221 final ConfigTransactionJMXClient transaction = this.configRegistryClient.createTransaction();
222 createRIBImplModuleInstance(transaction, ribId, localAs, bgpId, clusterId, createAsyncDataBrokerInstance(transaction));
223 return transaction.commit();
226 private ObjectName createRIBImplModuleInstance(final ConfigTransactionJMXClient transaction, final RibId ribId, final Long localAs,
227 final Ipv4Address bgpId, final Ipv4Address clusterId, final ObjectName dataBroker) throws Exception {
228 final ObjectName nameCreated = transaction.createModule(FACTORY_NAME, INSTANCE_NAME);
229 final RIBImplModuleMXBean mxBean = transaction.newMXBeanProxy(nameCreated, RIBImplModuleMXBean.class);
230 final ObjectName reconnectObjectName = TimedReconnectStrategyModuleTest.createInstance(transaction, SESSION_RS_INSTANCE_NAME);
231 mxBean.setSessionReconnectStrategy(reconnectObjectName);
232 mxBean.setDataProvider(dataBroker);
233 mxBean.setDomDataProvider(lookupDomAsyncDataBroker(transaction));
234 mxBean.setCodecTreeFactory(lookupMappingServiceInstance(transaction));
235 final ObjectName reconnectStrategyON = TimedReconnectStrategyModuleTest.createInstance(transaction, TCP_RS_INSTANCE_NAME);
236 mxBean.setTcpReconnectStrategy(reconnectStrategyON);
237 mxBean.setBgpDispatcher(BGPDispatcherImplModuleTest.createInstance(transaction));
238 mxBean.setExtensions(createRibExtensionsInstance(transaction));
239 mxBean.setRibId(ribId);
240 mxBean.setLocalAs(localAs);
241 mxBean.setBgpRibId(bgpId);
242 mxBean.setClusterId(clusterId);
246 protected ObjectName createRIBImplModuleInstance(final ConfigTransactionJMXClient transaction) throws Exception {
247 return createRIBImplModuleInstance(transaction, RIB_ID, 5000L, BGP_ID, CLUSTER_ID,
248 createAsyncDataBrokerInstance(transaction));
251 public ObjectName createRIBImplModuleInstance(final ConfigTransactionJMXClient transaction, final ObjectName dataBroker)
253 return createRIBImplModuleInstance(transaction, RIB_ID, 5000L, BGP_ID, CLUSTER_ID, dataBroker);
256 public ObjectName createAsyncDataBrokerInstance(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException, InstanceNotFoundException {
257 final ObjectName nameCreated = transaction.createModule(BindingAsyncDataBrokerImplModuleFactory.NAME, BINDING_ASYNC_BROKER_INSTANCE_NAME);
258 final BindingAsyncDataBrokerImplModuleMXBean mxBean = transaction.newMXBeanProxy(nameCreated, BindingAsyncDataBrokerImplModuleMXBean.class);
259 mxBean.setBindingMappingService(lookupMappingServiceInstance(transaction));
260 mxBean.setDomAsyncBroker(lookupDomAsyncDataBroker(transaction));
261 mxBean.setSchemaService(lookupSchemaServiceInstance(transaction));
265 public static ObjectName lookupDomAsyncDataBroker(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException {
267 return transaction.lookupConfigBean(DomInmemoryDataBrokerModuleFactory.NAME, DOM_BROKER_INSTANCE_NAME);
268 } catch (final InstanceNotFoundException e) {
270 final ObjectName nameCreated = transaction.createModule(DomInmemoryDataBrokerModuleFactory.NAME, DOM_BROKER_INSTANCE_NAME);
271 final DomInmemoryDataBrokerModuleMXBean mxBean = transaction.newMXBeanProxy(nameCreated, DomInmemoryDataBrokerModuleMXBean.class);
272 mxBean.setSchemaService(lookupSchemaServiceInstance(transaction));
274 } catch (final InstanceAlreadyExistsException e1) {
275 throw new IllegalStateException(e1);
280 private static ObjectName lookupMappingServiceInstance(final ConfigTransactionJMXClient transaction) {
282 return transaction.lookupConfigBean(RuntimeMappingModuleFactory.NAME, RuntimeMappingModuleFactory.SINGLETON_NAME);
283 } catch (final InstanceNotFoundException e) {
285 return transaction.createModule(RuntimeMappingModuleFactory.NAME, RuntimeMappingModuleFactory.SINGLETON_NAME);
286 } catch (final InstanceAlreadyExistsException e1) {
287 throw new IllegalStateException(e1);
292 private static ObjectName lookupSchemaServiceInstance(final ConfigTransactionJMXClient transaction) {
294 return transaction.lookupConfigBean(SchemaServiceImplSingletonModuleFactory.NAME, SchemaServiceImplSingletonModuleFactory.SINGLETON_NAME);
295 } catch (final InstanceNotFoundException e) {
297 return transaction.createModule(SchemaServiceImplSingletonModuleFactory.NAME, SchemaServiceImplSingletonModuleFactory.SINGLETON_NAME);
298 } catch (final InstanceAlreadyExistsException e1) {
299 throw new IllegalStateException(e1);
304 private ObjectName createRibExtensionsInstance(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException {
305 final ObjectName nameCreated = transaction.createModule(RIBExtensionsImplModuleFactory.NAME, RIB_EXTENSIONS_INSTANCE_NAME);
306 transaction.newMXBeanProxy(nameCreated, RIBExtensionsImplModuleMXBean.class);
310 public List<String> getYangModelsPaths() {
311 final List<String> paths = Lists.newArrayList("/META-INF/yang/bgp-rib.yang", "/META-INF/yang/ietf-inet-types.yang",
312 "/META-INF/yang/bgp-message.yang", "/META-INF/yang/bgp-multiprotocol.yang", "/META-INF/yang/bgp-types.yang",
313 "/META-INF/yang/network-concepts.yang", "/META-INF/yang/ieee754.yang");
317 // TODO move back to AbstractConfigTest
318 private static Collection<ByteSource> getFilesAsByteSources(final List<String> paths) {
319 final Collection<ByteSource> resources = new ArrayList<>();
320 final List<String> failedToFind = new ArrayList<>();
321 for (final String path : paths) {
322 final URL url = AbstractRIBImplModuleTest.class.getResource(path);
324 failedToFind.add(path);
326 resources.add(Resources.asByteSource(url));
329 Assert.assertEquals("Some files were not found", Collections.<String> emptyList(), failedToFind);