Fix netconf-connector-config groupId
[netconf.git] / opendaylight / netconf / netconf-it / src / test / java / org / opendaylight / netconf / it / AbstractNetconfConfigTest.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the terms of the Eclipse
5  * Public License v1.0 which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.netconf.it;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNotNull;
12
13 import com.google.common.base.Throwables;
14 import com.google.common.io.ByteStreams;
15 import com.google.common.util.concurrent.CheckedFuture;
16 import io.netty.channel.Channel;
17 import io.netty.channel.ChannelFuture;
18 import io.netty.channel.EventLoopGroup;
19 import io.netty.channel.local.LocalAddress;
20 import io.netty.channel.nio.NioEventLoopGroup;
21 import io.netty.util.HashedWheelTimer;
22 import io.netty.util.concurrent.GlobalEventExecutor;
23 import java.io.ByteArrayInputStream;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.net.InetSocketAddress;
27 import java.net.SocketAddress;
28 import java.util.ArrayList;
29 import java.util.Arrays;
30 import java.util.Collection;
31 import java.util.Collections;
32 import java.util.List;
33 import java.util.concurrent.TimeUnit;
34 import org.junit.After;
35 import org.junit.Before;
36 import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacadeFactory;
37 import org.opendaylight.controller.config.facade.xml.osgi.EnumResolver;
38 import org.opendaylight.controller.config.facade.xml.osgi.YangStoreService;
39 import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
40 import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
41 import org.opendaylight.controller.config.spi.ModuleFactory;
42 import org.opendaylight.controller.config.yang.test.impl.DepTestImplModuleFactory;
43 import org.opendaylight.controller.config.yang.test.impl.IdentityTestModuleFactory;
44 import org.opendaylight.controller.config.yang.test.impl.MultipleDependenciesModuleFactory;
45 import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleFactory;
46 import org.opendaylight.controller.config.yang.test.impl.TestImplModuleFactory;
47 import org.opendaylight.netconf.api.NetconfMessage;
48 import org.opendaylight.netconf.api.monitoring.NetconfMonitoringService;
49 import org.opendaylight.netconf.client.NetconfClientDispatcherImpl;
50 import org.opendaylight.netconf.client.SimpleNetconfClientSessionListener;
51 import org.opendaylight.netconf.client.conf.NetconfClientConfiguration;
52 import org.opendaylight.netconf.client.conf.NetconfClientConfigurationBuilder;
53 import org.opendaylight.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl;
54 import org.opendaylight.netconf.impl.NetconfServerDispatcherImpl;
55 import org.opendaylight.netconf.impl.NetconfServerSessionNegotiatorFactory;
56 import org.opendaylight.netconf.impl.SessionIdProvider;
57 import org.opendaylight.netconf.impl.osgi.AggregatedNetconfOperationServiceFactory;
58 import org.opendaylight.netconf.impl.osgi.NetconfMonitoringServiceImpl;
59 import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactory;
60 import org.opendaylight.netconf.monitoring.osgi.NetconfMonitoringActivator;
61 import org.opendaylight.netconf.monitoring.osgi.NetconfMonitoringOperationService;
62 import org.opendaylight.netconf.util.test.XmlFileLoader;
63 import org.opendaylight.protocol.framework.NeverReconnectStrategy;
64 import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
65 import org.opendaylight.yangtools.yang.binding.BindingMapping;
66 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
67 import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
68 import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceException;
69 import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
70 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
71 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider;
72 import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
73 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
74 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline;
75
76 public abstract class AbstractNetconfConfigTest extends AbstractConfigTest {
77
78     public static final String LOOPBACK_ADDRESS = "127.0.0.1";
79     public static final int SERVER_CONNECTION_TIMEOUT_MILLIS = 5000;
80     private static final int RESOURCE_TIMEOUT_MINUTES = 2;
81
82     static ModuleFactory[] FACTORIES =
83             {new TestImplModuleFactory(), new DepTestImplModuleFactory(), new NetconfTestImplModuleFactory(),
84                     new IdentityTestModuleFactory(), new MultipleDependenciesModuleFactory()};
85
86     protected ConfigSubsystemFacadeFactory configSubsystemFacadeFactory;
87     private EventLoopGroup nettyThreadgroup;
88     private HashedWheelTimer hashedWheelTimer;
89
90     private NetconfClientDispatcherImpl clientDispatcher;
91     private Channel serverTcpChannel;
92
93     private NetconfMessage getConfig;
94     private NetconfMessage get;
95
96     /**
97      * @Before in subclasses is called after this method.
98      */
99     @Before
100     public void setUpAbstractNetconfConfigTest() throws Exception {
101         super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, FACTORIES));
102
103         nettyThreadgroup = new NioEventLoopGroup();
104         hashedWheelTimer = new HashedWheelTimer();
105
106         loadMessages();
107
108         setUpTestInitial();
109
110         final AggregatedNetconfOperationServiceFactory factoriesListener =
111                 new AggregatedNetconfOperationServiceFactory();
112         final NetconfMonitoringService netconfMonitoringService = getNetconfMonitoringService(factoriesListener);
113         configSubsystemFacadeFactory =
114                 new ConfigSubsystemFacadeFactory(configRegistryClient, configRegistryClient, getYangStore());
115         factoriesListener.onAddNetconfOperationServiceFactory(
116                 new NetconfOperationServiceFactoryImpl(configSubsystemFacadeFactory));
117         factoriesListener.onAddNetconfOperationServiceFactory(
118                 new NetconfMonitoringActivator.NetconfMonitoringOperationServiceFactory(
119                         new NetconfMonitoringOperationService(netconfMonitoringService)));
120
121         for (final NetconfOperationServiceFactory netconfOperationServiceFactory : getAdditionalServiceFactories(
122                 factoriesListener)) {
123             factoriesListener.onAddNetconfOperationServiceFactory(netconfOperationServiceFactory);
124         }
125
126         serverTcpChannel = startNetconfTcpServer(factoriesListener, netconfMonitoringService);
127         clientDispatcher =
128                 new NetconfClientDispatcherImpl(getNettyThreadgroup(), getNettyThreadgroup(), getHashedWheelTimer());
129     }
130
131     /**
132      * Called before setUp method is executed, so test classes can set up resources before
133      * setUpAbstractNetconfConfigTest method is called.
134      */
135     protected void setUpTestInitial() throws Exception {}
136
137     private void loadMessages() throws Exception {
138         this.getConfig = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/getConfig.xml");
139         this.get = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/get.xml");
140     }
141
142     public NetconfMessage getGetConfig() {
143         return getConfig;
144     }
145
146     public NetconfMessage getGet() {
147         return get;
148     }
149
150     private Channel startNetconfTcpServer(final AggregatedNetconfOperationServiceFactory listener,
151             final NetconfMonitoringService monitoring) throws Exception {
152         final NetconfServerDispatcherImpl dispatch = createDispatcher(listener, monitoring);
153
154         final ChannelFuture s;
155         if (getTcpServerAddress() instanceof LocalAddress) {
156             s = dispatch.createLocalServer(((LocalAddress) getTcpServerAddress()));
157         } else {
158             s = dispatch.createServer(((InetSocketAddress) getTcpServerAddress()));
159         }
160         s.await(RESOURCE_TIMEOUT_MINUTES, TimeUnit.MINUTES);
161         return s.channel();
162     }
163
164     protected Iterable<NetconfOperationServiceFactory> getAdditionalServiceFactories(
165             final AggregatedNetconfOperationServiceFactory factoriesListener) throws Exception {
166         return Collections.emptySet();
167     }
168
169     protected NetconfMonitoringService getNetconfMonitoringService(
170             final AggregatedNetconfOperationServiceFactory factoriesListener) throws Exception {
171         return new NetconfMonitoringServiceImpl(factoriesListener);
172     }
173
174     protected abstract SocketAddress getTcpServerAddress();
175
176     public NetconfClientDispatcherImpl getClientDispatcher() {
177         return clientDispatcher;
178     }
179
180     private HardcodedYangStoreService getYangStore() throws IOException {
181         final Collection<InputStream> yangDependencies = getBasicYangs();
182         return new HardcodedYangStoreService(yangDependencies, getBindingRuntimeContext());
183     }
184
185     static Collection<InputStream> getBasicYangs() throws IOException {
186
187         final List<String> paths = Arrays.asList("/META-INF/yang/config.yang", "/META-INF/yang/rpc-context.yang",
188                 "/META-INF/yang/config-test.yang", "/META-INF/yang/config-test-impl.yang",
189                 "/META-INF/yang/test-types.yang", "/META-INF/yang/test-groups.yang",
190                 "/META-INF/yang/ietf-inet-types.yang");
191
192         final Collection<InputStream> yangDependencies = new ArrayList<>();
193         final List<String> failedToFind = new ArrayList<>();
194         for (final String path : paths) {
195             final InputStream resourceAsStream = NetconfITTest.class.getResourceAsStream(path);
196             if (resourceAsStream == null) {
197                 failedToFind.add(path);
198             } else {
199                 yangDependencies.add(resourceAsStream);
200             }
201         }
202         assertEquals("Some yang files were not found", Collections.<String>emptyList(), failedToFind);
203         return yangDependencies;
204     }
205
206     protected NetconfServerDispatcherImpl createDispatcher(
207             final AggregatedNetconfOperationServiceFactory factoriesListener,
208             final NetconfMonitoringService sessionMonitoringService) {
209         final SessionIdProvider idProvider = new SessionIdProvider();
210
211         final NetconfServerSessionNegotiatorFactory serverNegotiatorFactory =
212                 new NetconfServerSessionNegotiatorFactory(hashedWheelTimer, factoriesListener, idProvider,
213                         SERVER_CONNECTION_TIMEOUT_MILLIS, sessionMonitoringService);
214
215         final NetconfServerDispatcherImpl.ServerChannelInitializer serverChannelInitializer =
216                 new NetconfServerDispatcherImpl.ServerChannelInitializer(serverNegotiatorFactory);
217         return new NetconfServerDispatcherImpl(serverChannelInitializer, nettyThreadgroup, nettyThreadgroup);
218     }
219
220     protected HashedWheelTimer getHashedWheelTimer() {
221         return hashedWheelTimer;
222     }
223
224     protected EventLoopGroup getNettyThreadgroup() {
225         return nettyThreadgroup;
226     }
227
228     /**
229      * @After in subclasses is be called before this.
230      */
231     @After
232     public void cleanUpNetconf() throws Exception {
233         serverTcpChannel.close().await(RESOURCE_TIMEOUT_MINUTES, TimeUnit.MINUTES);
234         hashedWheelTimer.stop();
235         nettyThreadgroup.shutdownGracefully().await(RESOURCE_TIMEOUT_MINUTES, TimeUnit.MINUTES);
236     }
237
238     public NetconfClientConfiguration getClientConfiguration(final InetSocketAddress tcpAddress, final int timeout) {
239         final NetconfClientConfigurationBuilder b = NetconfClientConfigurationBuilder.create();
240         b.withAddress(tcpAddress);
241         b.withSessionListener(new SimpleNetconfClientSessionListener());
242         b.withReconnectStrategy(new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE, timeout));
243         b.withConnectionTimeoutMillis(timeout);
244         return b.build();
245     }
246
247     public static final class HardcodedYangStoreService extends YangStoreService {
248         public HardcodedYangStoreService(final Collection<? extends InputStream> inputStreams,
249                 final BindingRuntimeContext bindingRuntimeContext) throws IOException {
250             super(new SchemaContextProvider() {
251                 @Override
252                 public SchemaContext getSchemaContext() {
253                     return getSchema(inputStreams);
254                 }
255             }, new SchemaSourceProvider<YangTextSchemaSource>() {
256                 @Override
257                 public CheckedFuture<? extends YangTextSchemaSource, SchemaSourceException> getSource(
258                         SourceIdentifier sourceIdentifier) {
259
260                     return null;
261                 }
262             });
263
264             refresh(bindingRuntimeContext);
265         }
266
267         private static SchemaContext getSchema(final Collection<? extends InputStream> inputStreams) {
268             final ArrayList<InputStream> byteArrayInputStreams = new ArrayList<>();
269             for (final InputStream inputStream : inputStreams) {
270                 assertNotNull(inputStream);
271                 final byte[] content;
272                 try {
273                     content = ByteStreams.toByteArray(inputStream);
274                 } catch (IOException e) {
275                     throw new IllegalStateException("Cannot read " + inputStream, e);
276                 }
277                 final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(content);
278                 byteArrayInputStreams.add(byteArrayInputStream);
279             }
280
281             for (final InputStream inputStream : byteArrayInputStreams) {
282                 try {
283                     inputStream.reset();
284                 } catch (final IOException e) {
285                     throw new RuntimeException(e);
286                 }
287             }
288
289             try {
290                 return YangInferencePipeline.RFC6020_REACTOR.newBuild().buildEffective(byteArrayInputStreams);
291             } catch (SourceException | ReactorException e) {
292                 throw Throwables.propagate(e);
293             }
294         }
295
296         @Override
297         public EnumResolver getEnumResolver() {
298             return new EnumResolver() {
299                 @Override
300                 public String fromYang(final String enumType, final String enumYangValue) {
301                     return BindingMapping.getClassName(enumYangValue);
302                 }
303
304                 @Override
305                 public String toYang(final String enumType, final String enumJavaValue) {
306                     return enumJavaValue.toLowerCase();
307                 }
308             };
309         }
310     }
311 }