BUG-4672: BMP client reconnection not working
[bgpcep.git] / bgp / bmp-impl / src / test / java / org / opendaylight / controller / config / yang / bmp / impl / BmpMonitorImplModuleTest.java
1 /*
2  * Copyright (c) 2015 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.bmp.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.lang.reflect.Field;
19 import java.lang.reflect.Modifier;
20 import java.net.URL;
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.List;
25 import javax.management.InstanceAlreadyExistsException;
26 import javax.management.ObjectName;
27 import org.junit.After;
28 import org.junit.Assert;
29 import org.junit.Before;
30 import org.junit.Test;
31 import org.mockito.Matchers;
32 import org.mockito.Mock;
33 import org.mockito.Mockito;
34 import org.mockito.MockitoAnnotations;
35 import org.opendaylight.controller.config.api.jmx.CommitStatus;
36 import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
37 import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
38 import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
39 import org.opendaylight.controller.config.yang.bgp.rib.spi.RIBExtensionsImplModuleFactory;
40 import org.opendaylight.controller.config.yang.bgp.rib.spi.RIBExtensionsImplModuleMXBean;
41 import org.opendaylight.controller.config.yang.bmp.spi.SimpleBmpExtensionProviderContextModuleFactory;
42 import org.opendaylight.controller.config.yang.md.sal.binding.impl.RuntimeMappingModuleFactory;
43 import org.opendaylight.controller.config.yang.md.sal.binding.impl.RuntimeMappingModuleMXBean;
44 import org.opendaylight.controller.config.yang.md.sal.dom.impl.DomInmemoryDataBrokerModuleFactory;
45 import org.opendaylight.controller.config.yang.md.sal.dom.impl.DomInmemoryDataBrokerModuleMXBean;
46 import org.opendaylight.controller.config.yang.md.sal.dom.impl.SchemaServiceImplSingletonModuleFactory;
47 import org.opendaylight.controller.config.yang.md.sal.dom.impl.SchemaServiceImplSingletonModuleMXBean;
48 import org.opendaylight.controller.config.yang.netty.eventexecutor.GlobalEventExecutorModuleFactory;
49 import org.opendaylight.controller.config.yang.netty.threadgroup.NettyThreadgroupModuleFactory;
50 import org.opendaylight.controller.config.yang.protocol.framework.TimedReconnectStrategyFactoryModuleFactory;
51 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
52 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
53 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
54 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
55 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
56 import org.opendaylight.controller.sal.core.api.model.SchemaService;
57 import org.opendaylight.controller.sal.dom.broker.GlobalBundleScanningSchemaServiceImpl;
58 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
59 import org.opendaylight.yangtools.sal.binding.generator.impl.GeneratedClassLoadingStrategy;
60 import org.opendaylight.yangtools.yang.binding.DataObject;
61 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
62 import org.opendaylight.yangtools.yang.common.RpcResult;
63 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
64 import org.opendaylight.yangtools.yang.model.parser.api.YangContextParser;
65 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
66 import org.opendaylight.yangtools.yang.parser.repo.URLSchemaContextResolver;
67 import org.osgi.framework.Bundle;
68 import org.osgi.framework.BundleListener;
69 import org.osgi.framework.Filter;
70 import org.osgi.framework.ServiceListener;
71 import org.osgi.framework.ServiceReference;
72
73 public class BmpMonitorImplModuleTest extends AbstractConfigTest {
74
75     private static final String FACTORY_NAME = BmpMonitorImplModuleFactory.NAME;
76     private static final String INSTANCE_NAME = "bmp-monitor-impl-instance";
77     private static final String RIB_EXT_INSTANCE_NAME = "rib-ext-instance";
78     private static final String CODEC_INSTANCE_NAME = "runtime-mapping-singleton";
79     private static final String DOM_INSTANCE_NAME = "dom-data-instance";
80     private static final String TRANSACTION_NAME = "testTransaction";
81
82     @Mock private ReadWriteTransaction mockedTransaction;
83     @Mock private DataBroker mockedDataProvider;
84     @Mock private CheckedFuture<Void, TransactionCommitFailedException> mockedFuture;
85     @Mock private RpcResult<TransactionStatus> mockedResult;
86
87     @SuppressWarnings("unchecked")
88     @Before
89     public void setUp() throws Exception {
90         MockitoAnnotations.initMocks(this);
91
92         super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(this.mockedContext,
93             new BmpMonitorImplModuleFactory(),
94             new RIBExtensionsImplModuleFactory(),
95             new RuntimeMappingModuleFactory(),
96             new DomInmemoryDataBrokerModuleFactory(),
97             new BmpDispatcherImplModuleFactory(),
98             new NettyThreadgroupModuleFactory(),
99             new SimpleBmpExtensionProviderContextModuleFactory(),
100             new TimedReconnectStrategyFactoryModuleFactory(),
101             new GlobalEventExecutorModuleFactory(),
102             new SchemaServiceImplSingletonModuleFactory()));
103
104         final Filter mockedFilter = mock(Filter.class);
105         Mockito.doReturn(mockedFilter).when(this.mockedContext).createFilter(Mockito.anyString());
106
107         final ServiceReference<?> emptyServiceReference = mock(ServiceReference.class, "Empty");
108         final ServiceReference<?> classLoadingStrategySR = mock(ServiceReference.class, "ClassLoadingStrategy");
109         final ServiceReference<?> dataProviderServiceReference = mock(ServiceReference.class, "Data Provider");
110         final ServiceReference<?> schemaServiceReference = mock(ServiceReference.class, "schemaServiceReference");
111
112         Mockito.doReturn(mockedFilter).when(this.mockedContext).createFilter(Mockito.anyString());
113
114         Mockito.doNothing().when(this.mockedContext).addServiceListener(any(ServiceListener.class), Mockito.anyString());
115         Mockito.doNothing().when(this.mockedContext).removeServiceListener(any(ServiceListener.class));
116
117         Mockito.doNothing().when(this.mockedContext).addBundleListener(any(BundleListener.class));
118         Mockito.doNothing().when(this.mockedContext).removeBundleListener(any(BundleListener.class));
119
120         Mockito.doReturn(new Bundle[] {}).when(this.mockedContext).getBundles();
121
122         Mockito.doReturn(new ServiceReference[] {}).when(this.mockedContext).getServiceReferences(Matchers.anyString(), Matchers.anyString());
123
124         Mockito.doReturn("Empty reference").when(emptyServiceReference).toString();
125         Mockito.doReturn("Data Provider Service Reference").when(dataProviderServiceReference).toString();
126         Mockito.doReturn("Class loading stategy reference").when(classLoadingStrategySR).toString();
127         Mockito.doReturn("Schema Service reference").when(schemaServiceReference).toString();
128
129         Mockito.doReturn(emptyServiceReference).when(this.mockedContext).getServiceReference(any(Class.class));
130         Mockito.doReturn(dataProviderServiceReference).when(this.mockedContext).getServiceReference(DataBroker.class);
131         Mockito.doReturn(classLoadingStrategySR).when(this.mockedContext).getServiceReference(GeneratedClassLoadingStrategy.class);
132         Mockito.doReturn(schemaServiceReference).when(this.mockedContext).getServiceReference(SchemaService.class);
133
134         Mockito.doReturn(this.mockedDataProvider).when(this.mockedContext).getService(dataProviderServiceReference);
135         Mockito.doReturn(GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy()).when(this.mockedContext).getService(classLoadingStrategySR);
136         Mockito.doReturn(null).when(this.mockedContext).getService(emptyServiceReference);
137         final GlobalBundleScanningSchemaServiceImpl schemaService = GlobalBundleScanningSchemaServiceImpl.createInstance(this.mockedContext);
138         Mockito.doReturn(schemaService).when(this.mockedContext).getService(schemaServiceReference);
139
140         Mockito.doReturn(this.mockedTransaction).when(this.mockedDataProvider).newReadWriteTransaction();
141
142         Mockito.doReturn(null).when(this.mockedTransaction).read(Mockito.eq(LogicalDatastoreType.OPERATIONAL), any(InstanceIdentifier.class));
143         Mockito.doNothing().when(this.mockedTransaction).put(Mockito.eq(LogicalDatastoreType.OPERATIONAL), any(InstanceIdentifier.class), any(DataObject.class));
144         Mockito.doNothing().when(this.mockedTransaction).delete(Mockito.eq(LogicalDatastoreType.OPERATIONAL), any(InstanceIdentifier.class));
145
146         Mockito.doReturn(this.mockedFuture).when(this.mockedTransaction).submit();
147         Mockito.doReturn(TRANSACTION_NAME).when(this.mockedTransaction).getIdentifier();
148
149         Mockito.doReturn(null).when(this.mockedFuture).get();
150
151         final YangContextParser parser = new YangParserImpl();
152         final SchemaContext context = parser.parseSources(getFilesAsByteSources(getYangModelsPaths()));
153         final URLSchemaContextResolver mockedContextResolver = Mockito.mock(URLSchemaContextResolver.class);
154         Mockito.doReturn(Optional.of(context)).when(mockedContextResolver).getSchemaContext();
155
156         final Field contextResolverField = schemaService.getClass().getDeclaredField("contextResolver");
157         contextResolverField.setAccessible(true);
158
159         final Field modifiersField = Field.class.getDeclaredField("modifiers");
160         modifiersField.setAccessible(true);
161         modifiersField.setInt(contextResolverField, contextResolverField.getModifiers() & ~Modifier.FINAL);
162
163         contextResolverField.set(schemaService, mockedContextResolver);
164     }
165
166     private List<String> getYangModelsPaths() {
167         final List<String> paths = Lists.newArrayList("/META-INF/yang/bgp-rib.yang", "/META-INF/yang/ietf-inet-types.yang",
168                 "/META-INF/yang/bgp-message.yang", "/META-INF/yang/bgp-multiprotocol.yang", "/META-INF/yang/bgp-types.yang",
169                 "/META-INF/yang/network-concepts.yang", "/META-INF/yang/ieee754.yang", "/META-INF/yang/yang-ext.yang",
170                 "/META-INF/yang/bmp-monitor.yang", "/META-INF/yang/bmp-message.yang", "/META-INF/yang/ietf-yang-types.yang");
171         return paths;
172     }
173
174     private Collection<ByteSource> getFilesAsByteSources(final List<String> paths) {
175         final Collection<ByteSource> resources = new ArrayList<>();
176         final List<String> failedToFind = new ArrayList<>();
177         for (final String path : paths) {
178             final URL url = BmpMonitorImplModuleTest.class.getResource(path);
179             if (url == null) {
180                 failedToFind.add(path);
181             } else {
182                 resources.add(Resources.asByteSource(url));
183             }
184         }
185         Assert.assertEquals("Some files were not found", Collections.<String> emptyList(), failedToFind);
186         return resources;
187     }
188
189     @After
190     public void closeAllModules() throws Exception {
191         super.destroyAllConfigBeans();
192         GlobalBundleScanningSchemaServiceImpl.destroyInstance();
193     }
194
195     @Test
196     public void testCreateBean() throws Exception {
197         final CommitStatus status = createInstance();
198         assertBeanCount(1, FACTORY_NAME);
199         assertStatus(status, 9, 0, 0);
200     }
201
202     @Test
203     public void testReusingOldInstance() throws Exception {
204         createInstance();
205         final ConfigTransactionJMXClient transaction = this.configRegistryClient.createTransaction();
206         assertBeanCount(1, FACTORY_NAME);
207         final CommitStatus status = transaction.commit();
208         assertBeanCount(1, FACTORY_NAME);
209         assertStatus(status, 0, 0, 9);
210     }
211
212     private CommitStatus createInstance() throws Exception {
213         final ConfigTransactionJMXClient transaction = this.configRegistryClient.createTransaction();
214         final ObjectName nameCreated = transaction.createModule(FACTORY_NAME, INSTANCE_NAME);
215         final BmpMonitorImplModuleMXBean mxBean = transaction.newMXBeanProxy(nameCreated, BmpMonitorImplModuleMXBean.class);
216         mxBean.setExtensions(createExtensions(transaction));
217         mxBean.setCodecTreeFactory(createRuntimeMapping(transaction));
218         mxBean.setDomDataProvider(createDomData(transaction));
219         mxBean.setBmpDispatcher(createDispatcher(transaction));
220         mxBean.setBindingPort(new PortNumber(9999));
221         return transaction.commit();
222     }
223
224     private static ObjectName createExtensions(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException {
225         final ObjectName nameCreated = transaction.createModule(RIBExtensionsImplModuleFactory.NAME, RIB_EXT_INSTANCE_NAME);
226         transaction.newMXBeanProxy(nameCreated, RIBExtensionsImplModuleMXBean.class);
227         return nameCreated;
228     }
229
230     private static ObjectName createRuntimeMapping(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException {
231         final ObjectName nameCreated = transaction.createModule(RuntimeMappingModuleFactory.NAME, CODEC_INSTANCE_NAME);
232         transaction.newMXBeanProxy(nameCreated, RuntimeMappingModuleMXBean.class);
233         return nameCreated;
234     }
235
236     private static ObjectName createDomData(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException {
237         final ObjectName nameCreated = transaction.createModule(DomInmemoryDataBrokerModuleFactory.NAME, DOM_INSTANCE_NAME);
238         final DomInmemoryDataBrokerModuleMXBean bean = transaction.newMXBeanProxy(nameCreated, DomInmemoryDataBrokerModuleMXBean.class);
239         bean.setSchemaService(createSchemaService(transaction));
240         return nameCreated;
241     }
242
243     private static ObjectName createSchemaService(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException {
244         final ObjectName nameCreated = transaction.createModule(SchemaServiceImplSingletonModuleFactory.NAME, SchemaServiceImplSingletonModuleFactory.SINGLETON_NAME);
245         transaction.newMXBeanProxy(nameCreated, SchemaServiceImplSingletonModuleMXBean.class);
246         return nameCreated;
247     }
248
249     private static ObjectName createDispatcher(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException {
250         return BmpDispatcherImplModuleTest.createInstance(transaction);
251     }
252 }