package org.opendaylight.controller.config.yang.bgp.rib.impl;
import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.contains;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import com.google.common.base.Optional;
import com.google.common.collect.Lists;
import com.google.common.io.ByteSource;
import com.google.common.io.Resources;
import com.google.common.util.concurrent.CheckedFuture;
+import io.netty.channel.EventLoopGroup;
+import io.netty.util.concurrent.EventExecutor;
+import io.netty.util.concurrent.ImmediateEventExecutor;
+import io.netty.util.concurrent.SucceededFuture;
import java.io.IOException;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
+import java.net.InetSocketAddress;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
import org.opendaylight.controller.config.api.jmx.CommitStatus;
import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
import org.opendaylight.controller.config.yang.md.sal.dom.impl.DomInmemoryDataBrokerModuleFactory;
import org.opendaylight.controller.config.yang.md.sal.dom.impl.DomInmemoryDataBrokerModuleMXBean;
import org.opendaylight.controller.config.yang.md.sal.dom.impl.SchemaServiceImplSingletonModuleFactory;
+import org.opendaylight.controller.config.yang.netty.eventexecutor.AutoCloseableEventExecutor;
import org.opendaylight.controller.config.yang.netty.eventexecutor.GlobalEventExecutorModuleFactory;
import org.opendaylight.controller.config.yang.netty.threadgroup.NettyThreadgroupModuleFactory;
+import org.opendaylight.controller.config.yang.netty.threadgroup.NioEventLoopGroupCloseable;
import org.opendaylight.controller.config.yang.netty.timer.HashedWheelTimerModuleFactory;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodecFactory;
import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.controller.sal.dom.broker.GlobalBundleScanningSchemaServiceImpl;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
+import org.opendaylight.controller.md.sal.dom.api.DOMNotificationPublishService;
+import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcProviderService;
+import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.opendaylight.controller.sal.core.api.model.YangTextSourceProvider;
+import org.opendaylight.protocol.bgp.parser.spi.BGPExtensionProviderContext;
+import org.opendaylight.protocol.bgp.parser.spi.MessageRegistry;
+import org.opendaylight.protocol.bgp.rib.impl.spi.BGPDispatcher;
+import org.opendaylight.protocol.bgp.rib.impl.spi.BGPPeerRegistry;
+import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionProviderContext;
+import org.opendaylight.protocol.bgp.rib.spi.SimpleRIBExtensionProviderContext;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.RibId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.BgpId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.ClusterIdentifier;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.sal.binding.generator.api.ClassLoadingStrategy;
import org.opendaylight.yangtools.sal.binding.generator.impl.GeneratedClassLoadingStrategy;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
-import org.opendaylight.yangtools.yang.model.parser.api.YangContextParser;
-import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
-import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
-import org.opendaylight.yangtools.yang.parser.repo.URLSchemaContextResolver;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
+import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleListener;
import org.osgi.framework.Filter;
@Mock
private RpcResult<TransactionStatus> mockedResult;
+ @Mock
+ protected BGPDispatcher mockedBGPDispatcher;
+
@SuppressWarnings("unchecked")
@Before
public void setUp() throws Exception {
final List<ModuleFactory> moduleFactories = getModuleFactories();
super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(this.mockedContext, moduleFactories.toArray(new ModuleFactory[moduleFactories.size()])));
- final Filter mockedFilter = mock(Filter.class);
- Mockito.doReturn(mockedFilter).when(this.mockedContext).createFilter(Mockito.anyString());
+ doAnswer(new Answer<Filter>() {
+ @Override
+ public Filter answer(final InvocationOnMock invocation) {
+ final String str = invocation.getArgumentAt(0, String.class);
+ final Filter mockFilter = mock(Filter.class);
+ doReturn(str).when(mockFilter).toString();
+ return mockFilter;
+ }
+ }).when(mockedContext).createFilter(anyString());
final ServiceReference<?> emptyServiceReference = mock(ServiceReference.class, "Empty");
final ServiceReference<?> classLoadingStrategySR = mock(ServiceReference.class, "ClassLoadingStrategy");
final ServiceReference<?> dataProviderServiceReference = mock(ServiceReference.class, "Data Provider");
- Mockito.doReturn(mockedFilter).when(this.mockedContext).createFilter(Mockito.anyString());
-
Mockito.doNothing().when(this.mockedContext).addServiceListener(any(ServiceListener.class), Mockito.anyString());
Mockito.doNothing().when(this.mockedContext).removeServiceListener(any(ServiceListener.class));
Mockito.doReturn(emptyServiceReference).when(this.mockedContext).getServiceReference(any(Class.class));
Mockito.doReturn(dataProviderServiceReference).when(this.mockedContext).getServiceReference(DataBroker.class);
Mockito.doReturn(classLoadingStrategySR).when(this.mockedContext).getServiceReference(GeneratedClassLoadingStrategy.class);
+ Mockito.doReturn(classLoadingStrategySR).when(this.mockedContext).getServiceReference(ClassLoadingStrategy.class);
Mockito.doReturn(this.mockedDataProvider).when(this.mockedContext).getService(dataProviderServiceReference);
Mockito.doReturn(GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy()).when(this.mockedContext).getService(classLoadingStrategySR);
Mockito.doReturn(null).when(this.mockedFuture).get();
- final GlobalBundleScanningSchemaServiceImpl schemaService = GlobalBundleScanningSchemaServiceImpl.createInstance(this.mockedContext);
- final YangContextParser parser = new YangParserImpl();
- final SchemaContext context = parser.parseSources(getFilesAsByteSources(getYangModelsPaths()));
- final URLSchemaContextResolver mockedContextResolver = Mockito.mock(URLSchemaContextResolver.class);
- Mockito.doReturn(Optional.of(context)).when(mockedContextResolver).getSchemaContext();
+ final SchemaContext context = parseYangStreams(getFilesAsByteSources(getYangModelsPaths()));
+ final SchemaService mockedSchemaService = mock(SchemaService.class);
+ doReturn(context).when(mockedSchemaService).getGlobalContext();
+ doAnswer(new Answer<ListenerRegistration<SchemaContextListener>>() {
+ @Override
+ public ListenerRegistration<SchemaContextListener> answer(InvocationOnMock invocation) {
+ invocation.getArgumentAt(0, SchemaContextListener.class).onGlobalContextUpdated(context);
+ ListenerRegistration<SchemaContextListener> reg = mock(ListenerRegistration.class);
+ doNothing().when(reg).close();
+ return reg;
+ }
+ }).when(mockedSchemaService).registerSchemaContextListener(any(SchemaContextListener.class));
+
+ setupMockService(SchemaService.class, mockedSchemaService);
+ setupMockService(YangTextSourceProvider.class, mock(YangTextSourceProvider.class));
+
+ BindingToNormalizedNodeCodecFactory.getOrCreateInstance(
+ GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy(), mockedSchemaService);
+
+ BGPExtensionProviderContext mockContext = mock(BGPExtensionProviderContext.class);
+ doReturn(mock(MessageRegistry.class)).when(mockContext).getMessageRegistry();
+ setupMockService(BGPExtensionProviderContext.class, mockContext);
+
+ setupMockService(EventLoopGroup.class, NioEventLoopGroupCloseable.newInstance(0));
+ setupMockService(EventExecutor.class, AutoCloseableEventExecutor.CloseableEventExecutorMixin.globalEventExecutor());
- final Field contextResolverField = schemaService.getClass().getDeclaredField("contextResolver");
- contextResolverField.setAccessible(true);
+ setupMockService(DOMNotificationService.class, mock(DOMNotificationService.class));
+ setupMockService(DOMNotificationPublishService.class, mock(DOMNotificationPublishService.class));
+ setupMockService(DOMRpcService.class, mock(DOMRpcService.class));
+ setupMockService(DOMRpcProviderService.class, mock(DOMRpcProviderService.class));
+ setupMockService(DOMMountPointService.class, mock(DOMMountPointService.class));
- final Field modifiersField = Field.class.getDeclaredField("modifiers");
- modifiersField.setAccessible(true);
- modifiersField.setInt(contextResolverField, contextResolverField.getModifiers() & ~Modifier.FINAL);
+ setupMockService(BGPDispatcher.class, mockedBGPDispatcher);
+ doReturn(new SucceededFuture<>(ImmediateEventExecutor.INSTANCE, null)).when(mockedBGPDispatcher).createReconnectingClient(
+ any(InetSocketAddress.class), any(BGPPeerRegistry.class), anyInt(), any(Optional.class));
- contextResolverField.set(schemaService, mockedContextResolver);
+ setupMockService(RIBExtensionProviderContext.class, new SimpleRIBExtensionProviderContext());
+ }
+
+ protected void setupMockService(final Class<?> serviceInterface, final Object instance) throws Exception {
+ final ServiceReference<?> mockServiceRef = mock(ServiceReference.class);
+ doReturn(new ServiceReference[]{mockServiceRef}).when(mockedContext).
+ getServiceReferences(anyString(), contains(serviceInterface.getName()));
+ doReturn(new ServiceReference[]{mockServiceRef}).when(mockedContext).
+ getServiceReferences(serviceInterface.getName(), null);
+ doReturn(instance).when(mockedContext).getService(mockServiceRef);
+ }
+
+ private static SchemaContext parseYangStreams(final Collection<ByteSource> streams) {
+ final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR
+ .newBuild();
+ try {
+ return reactor.buildEffective(streams);
+ } catch (final ReactorException | IOException e) {
+ throw new RuntimeException("Unable to build schema context from " + streams, e);
+ }
}
protected List<ModuleFactory> getModuleFactories() {
@Override
public void handleServiceRegistration(final Class<?> clazz, final Object serviceInstance, final Dictionary<String, ?> props) {
final SchemaContextListener listener = (SchemaContextListener) serviceInstance;
- final YangContextParser parser = new YangParserImpl();
- final SchemaContext context;
- try {
- context = parser.parseSources(getFilesAsByteSources(getYangModelsPaths()));
- } catch (IOException | YangSyntaxErrorException e) {
- throw new IllegalStateException("Failed to parse models", e);
- }
+ final SchemaContext context = parseYangStreams(getFilesAsByteSources(getYangModelsPaths()));
listener.onGlobalContextUpdated(context);
}
};
@After
public void closeAllModules() throws Exception {
super.destroyAllConfigBeans();
- GlobalBundleScanningSchemaServiceImpl.destroyInstance();
}
mxBean.setDataProvider(dataBroker);
mxBean.setDomDataProvider(lookupDomAsyncDataBroker(transaction));
mxBean.setCodecTreeFactory(lookupMappingServiceInstance(transaction));
- mxBean.setBgpDispatcher(BGPDispatcherImplModuleTest.createInstance(transaction));
+ mxBean.setBgpDispatcher(createBGPDispatcherImplInstance(transaction));
mxBean.setExtensions(createRibExtensionsInstance(transaction));
mxBean.setRibId(ribId);
mxBean.setLocalAs(localAs);
- mxBean.setBgpRibId(bgpId);
- mxBean.setClusterId(clusterId);
+ mxBean.setBgpRibId(bgpId != null ? new BgpId(bgpId) : null);
+ mxBean.setClusterId(clusterId != null ? new ClusterIdentifier(clusterId) : null);
+ return nameCreated;
+ }
+
+ public static ObjectName createBGPDispatcherImplInstance(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException {
+ final ObjectName nameCreated = transaction.createModule(BGPDispatcherImplModuleFactory.NAME, "bgp-message-fct");
+ final BGPDispatcherImplModuleMXBean mxBean = transaction.newMXBeanProxy(nameCreated, BGPDispatcherImplModuleMXBean.class);
return nameCreated;
}
}
public List<String> getYangModelsPaths() {
- final List<String> paths = Lists.newArrayList("/META-INF/yang/bgp-rib.yang", "/META-INF/yang/ietf-inet-types.yang",
+ final List<String> paths = Lists.newArrayList("/META-INF/yang/bgp-rib.yang", "/META-INF/yang/ietf-inet-types@2013-07-15.yang",
"/META-INF/yang/bgp-message.yang", "/META-INF/yang/bgp-multiprotocol.yang", "/META-INF/yang/bgp-types.yang",
"/META-INF/yang/network-concepts.yang", "/META-INF/yang/ieee754.yang", "/META-INF/yang/yang-ext.yang");
return paths;