b043f708081a41f1fce86d9c6526654174b81b77
[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.doAnswer;
12 import static org.mockito.Mockito.doNothing;
13 import static org.mockito.Mockito.doReturn;
14 import static org.mockito.Mockito.mock;
15
16 import com.google.common.collect.Lists;
17 import com.google.common.util.concurrent.CheckedFuture;
18 import io.netty.channel.nio.NioEventLoopGroup;
19 import java.io.InputStream;
20 import java.util.ArrayList;
21 import java.util.Collections;
22 import java.util.List;
23 import javax.management.InstanceAlreadyExistsException;
24 import javax.management.ObjectName;
25 import org.junit.After;
26 import org.junit.Assert;
27 import org.junit.Before;
28 import org.junit.Test;
29 import org.mockito.Mock;
30 import org.mockito.Mockito;
31 import org.mockito.MockitoAnnotations;
32 import org.mockito.invocation.InvocationOnMock;
33 import org.mockito.stubbing.Answer;
34 import org.opendaylight.controller.config.api.jmx.CommitStatus;
35 import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
36 import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
37 import org.opendaylight.controller.config.yang.bgp.rib.spi.RIBExtensionsImplModuleFactory;
38 import org.opendaylight.controller.config.yang.bgp.rib.spi.RIBExtensionsImplModuleMXBean;
39 import org.opendaylight.controller.config.yang.md.sal.binding.impl.RuntimeMappingModuleFactory;
40 import org.opendaylight.controller.config.yang.md.sal.binding.impl.RuntimeMappingModuleMXBean;
41 import org.opendaylight.controller.config.yang.md.sal.dom.impl.DomInmemoryDataBrokerModuleFactory;
42 import org.opendaylight.controller.config.yang.md.sal.dom.impl.DomInmemoryDataBrokerModuleMXBean;
43 import org.opendaylight.controller.config.yang.md.sal.dom.impl.SchemaServiceImplSingletonModuleFactory;
44 import org.opendaylight.controller.config.yang.md.sal.dom.impl.SchemaServiceImplSingletonModuleMXBean;
45 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
46 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
47 import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
48 import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodecFactory;
49 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
50 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
51 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
52 import org.opendaylight.controller.sal.core.api.model.SchemaService;
53 import org.opendaylight.controller.sal.core.api.model.YangTextSourceProvider;
54 import org.opendaylight.mdsal.binding.generator.api.ClassLoadingStrategy;
55 import org.opendaylight.mdsal.binding.generator.impl.GeneratedClassLoadingStrategy;
56 import org.opendaylight.protocol.bmp.api.BmpDispatcher;
57 import org.opendaylight.protocol.bmp.impl.BmpDispatcherImpl;
58 import org.opendaylight.protocol.bmp.impl.session.DefaultBmpSessionFactory;
59 import org.opendaylight.protocol.bmp.spi.registry.SimpleBmpMessageRegistry;
60 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
61 import org.opendaylight.yangtools.concepts.ListenerRegistration;
62 import org.opendaylight.yangtools.yang.binding.DataObject;
63 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
64 import org.opendaylight.yangtools.yang.common.RpcResult;
65 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
66 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
67 import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
68 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
69 import org.osgi.framework.Bundle;
70 import org.osgi.framework.BundleListener;
71 import org.osgi.framework.ServiceReference;
72
73 public class BmpMonitorImplModuleTest extends AbstractBmpModuleTest {
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     @Override
88     @SuppressWarnings("unchecked")
89     @Before
90     public void setUp() throws Exception {
91         MockitoAnnotations.initMocks(this);
92
93         super.setUp();
94         super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(this.mockedContext,
95             new BmpMonitorImplModuleFactory(),
96             new RIBExtensionsImplModuleFactory(),
97             new RuntimeMappingModuleFactory(),
98             new DomInmemoryDataBrokerModuleFactory(),
99             new BmpDispatcherImplModuleFactory(),
100             new SchemaServiceImplSingletonModuleFactory()));
101
102         final ServiceReference<?> emptyServiceReference = mock(ServiceReference.class, "Empty");
103         final ServiceReference<?> classLoadingStrategySR = mock(ServiceReference.class, "ClassLoadingStrategy");
104         final ServiceReference<?> dataProviderServiceReference = mock(ServiceReference.class, "Data Provider");
105         final ServiceReference<?> schemaServiceReference = mock(ServiceReference.class, "schemaServiceReference");
106
107         Mockito.doNothing().when(this.mockedContext).addBundleListener(any(BundleListener.class));
108         Mockito.doNothing().when(this.mockedContext).removeBundleListener(any(BundleListener.class));
109
110         Mockito.doReturn(new Bundle[] {}).when(this.mockedContext).getBundles();
111
112         Mockito.doReturn("Empty reference").when(emptyServiceReference).toString();
113         Mockito.doReturn("Data Provider Service Reference").when(dataProviderServiceReference).toString();
114         Mockito.doReturn("Class loading stategy reference").when(classLoadingStrategySR).toString();
115         Mockito.doReturn("Schema Service reference").when(schemaServiceReference).toString();
116
117         Mockito.doReturn(emptyServiceReference).when(this.mockedContext).getServiceReference(any(Class.class));
118         Mockito.doReturn(dataProviderServiceReference).when(this.mockedContext).getServiceReference(DataBroker.class);
119         Mockito.doReturn(classLoadingStrategySR).when(this.mockedContext).getServiceReference(GeneratedClassLoadingStrategy.class);
120         Mockito.doReturn(schemaServiceReference).when(this.mockedContext).getServiceReference(SchemaService.class);
121         Mockito.doReturn(classLoadingStrategySR).when(this.mockedContext).getServiceReference(ClassLoadingStrategy.class);
122
123         Mockito.doReturn(this.mockedDataProvider).when(this.mockedContext).getService(dataProviderServiceReference);
124         Mockito.doReturn(GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy()).when(this.mockedContext).getService(classLoadingStrategySR);
125         Mockito.doReturn(null).when(this.mockedContext).getService(emptyServiceReference);
126
127         Mockito.doReturn(this.mockedTransaction).when(this.mockedDataProvider).newReadWriteTransaction();
128
129         Mockito.doReturn(null).when(this.mockedTransaction).read(Mockito.eq(LogicalDatastoreType.OPERATIONAL), any(InstanceIdentifier.class));
130         Mockito.doNothing().when(this.mockedTransaction).put(Mockito.eq(LogicalDatastoreType.OPERATIONAL), any(InstanceIdentifier.class), any(DataObject.class));
131         Mockito.doNothing().when(this.mockedTransaction).delete(Mockito.eq(LogicalDatastoreType.OPERATIONAL), any(InstanceIdentifier.class));
132
133         Mockito.doReturn(this.mockedFuture).when(this.mockedTransaction).submit();
134         Mockito.doReturn(TRANSACTION_NAME).when(this.mockedTransaction).getIdentifier();
135
136         Mockito.doReturn(null).when(this.mockedFuture).get();
137
138         final SchemaContext context = parseYangStreams(getFilesAsStreams(getYangModelsPaths()));
139         final SchemaService mockedSchemaService = mock(SchemaService.class);
140         doReturn(context).when(mockedSchemaService).getGlobalContext();
141         doAnswer(invocation -> {
142             invocation.getArgumentAt(0, SchemaContextListener.class).onGlobalContextUpdated(context);
143             final ListenerRegistration<SchemaContextListener> reg = mock(ListenerRegistration.class);
144             doNothing().when(reg).close();
145             return reg;
146         }).when(mockedSchemaService).registerSchemaContextListener(any(SchemaContextListener.class));
147
148         setupMockService(SchemaService.class, mockedSchemaService);
149         setupMockService(YangTextSourceProvider.class, mock(YangTextSourceProvider.class));
150         Mockito.doReturn(mockedSchemaService).when(this.mockedContext).getService(schemaServiceReference);
151
152         final BindingToNormalizedNodeCodec bindingCodec = BindingToNormalizedNodeCodecFactory.newInstance(
153                 GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy());
154         BindingToNormalizedNodeCodecFactory.registerInstance(bindingCodec, mockedSchemaService);
155         setupMockService(BindingToNormalizedNodeCodec.class, bindingCodec);
156
157         final BmpDispatcher bmpDispatcher = new BmpDispatcherImpl(new NioEventLoopGroup(), new NioEventLoopGroup(),
158                 new SimpleBmpMessageRegistry(), new DefaultBmpSessionFactory());
159         setupMockService(BmpDispatcher.class, bmpDispatcher);
160     }
161
162     private static SchemaContext parseYangStreams(final List<InputStream> streams) {
163         try {
164             return YangParserTestUtils.parseYangStreams(streams);
165         } catch (final ReactorException e) {
166             throw new RuntimeException("Unable to build schema context from " + streams, e);
167         }
168     }
169
170     private List<String> getYangModelsPaths() {
171         final List<String> paths = Lists.newArrayList("/META-INF/yang/bgp-rib.yang", "/META-INF/yang/ietf-inet-types@2013-07-15.yang",
172                 "/META-INF/yang/bgp-message.yang", "/META-INF/yang/bgp-multiprotocol.yang", "/META-INF/yang/bgp-types.yang",
173                 "/META-INF/yang/network-concepts.yang", "/META-INF/yang/ieee754.yang", "/META-INF/yang/yang-ext.yang",
174                 "/META-INF/yang/bmp-monitor.yang", "/META-INF/yang/bmp-message.yang", "/META-INF/yang/ietf-yang-types@2013-07-15.yang");
175         return paths;
176     }
177
178     private List<InputStream> getFilesAsStreams(final List<String> paths) {
179         final List<InputStream> resources = new ArrayList<>();
180         final List<String> failedToFind = new ArrayList<>();
181         for (final String path : paths) {
182             final InputStream is = BmpMonitorImplModuleTest.class.getResourceAsStream(path);
183             if (is == null) {
184                 failedToFind.add(path);
185             } else {
186                 resources.add(is);
187             }
188         }
189         Assert.assertEquals("Some files were not found", Collections.emptyList(), failedToFind);
190         return resources;
191     }
192
193     @After
194     public void closeAllModules() throws Exception {
195         super.destroyAllConfigBeans();
196     }
197
198     @Test
199     public void testCreateBean() throws Exception {
200         final CommitStatus status = createInstance();
201         assertBeanCount(1, FACTORY_NAME);
202         assertStatus(status, 6, 0, 0);
203     }
204
205     @Test
206     public void testReusingOldInstance() throws Exception {
207         createInstance();
208         final ConfigTransactionJMXClient transaction = this.configRegistryClient.createTransaction();
209         assertBeanCount(1, FACTORY_NAME);
210         final CommitStatus status = transaction.commit();
211         assertBeanCount(1, FACTORY_NAME);
212         assertStatus(status, 0, 0, 6);
213     }
214
215     private CommitStatus createInstance() throws Exception {
216         final ConfigTransactionJMXClient transaction = this.configRegistryClient.createTransaction();
217         final ObjectName nameCreated = transaction.createModule(FACTORY_NAME, INSTANCE_NAME);
218         final BmpMonitorImplModuleMXBean mxBean = transaction.newMXBeanProxy(nameCreated, BmpMonitorImplModuleMXBean.class);
219         mxBean.setExtensions(createExtensions(transaction));
220         mxBean.setCodecTreeFactory(createRuntimeMapping(transaction));
221         mxBean.setDomDataProvider(createDomData(transaction));
222         mxBean.setBmpDispatcher(createDispatcher(transaction));
223         mxBean.setBindingPort(new PortNumber(9999));
224         return transaction.commit();
225     }
226
227     private static ObjectName createExtensions(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException {
228         final ObjectName nameCreated = transaction.createModule(RIBExtensionsImplModuleFactory.NAME, RIB_EXT_INSTANCE_NAME);
229         transaction.newMXBeanProxy(nameCreated, RIBExtensionsImplModuleMXBean.class);
230         return nameCreated;
231     }
232
233     private static ObjectName createRuntimeMapping(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException {
234         final ObjectName nameCreated = transaction.createModule(RuntimeMappingModuleFactory.NAME, CODEC_INSTANCE_NAME);
235         transaction.newMXBeanProxy(nameCreated, RuntimeMappingModuleMXBean.class);
236         return nameCreated;
237     }
238
239     private static ObjectName createDomData(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException {
240         final ObjectName nameCreated = transaction.createModule(DomInmemoryDataBrokerModuleFactory.NAME, DOM_INSTANCE_NAME);
241         final DomInmemoryDataBrokerModuleMXBean bean = transaction.newMXBeanProxy(nameCreated, DomInmemoryDataBrokerModuleMXBean.class);
242         bean.setSchemaService(createSchemaService(transaction));
243         return nameCreated;
244     }
245
246     private static ObjectName createSchemaService(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException {
247         final ObjectName nameCreated = transaction.createModule(SchemaServiceImplSingletonModuleFactory.NAME, SchemaServiceImplSingletonModuleFactory.SINGLETON_NAME);
248         transaction.newMXBeanProxy(nameCreated, SchemaServiceImplSingletonModuleMXBean.class);
249         return nameCreated;
250     }
251
252     private static ObjectName createDispatcher(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException {
253         final ObjectName nameCreated = transaction.createModule(BmpDispatcherImplModuleFactory.NAME, "bmp-message-fct");
254         transaction.newMXBeanProxy(nameCreated, BmpDispatcherImplModuleMXBean.class);
255         return nameCreated;
256     }
257 }