2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.netconf.it;
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNotNull;
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;
76 public abstract class AbstractNetconfConfigTest extends AbstractConfigTest {
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;
82 static ModuleFactory[] FACTORIES =
83 {new TestImplModuleFactory(), new DepTestImplModuleFactory(), new NetconfTestImplModuleFactory(),
84 new IdentityTestModuleFactory(), new MultipleDependenciesModuleFactory()};
86 protected ConfigSubsystemFacadeFactory configSubsystemFacadeFactory;
87 private EventLoopGroup nettyThreadgroup;
88 private HashedWheelTimer hashedWheelTimer;
90 private NetconfClientDispatcherImpl clientDispatcher;
91 private Channel serverTcpChannel;
93 private NetconfMessage getConfig;
94 private NetconfMessage get;
97 * @Before in subclasses is called after this method.
100 public void setUpAbstractNetconfConfigTest() throws Exception {
101 super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, FACTORIES));
103 nettyThreadgroup = new NioEventLoopGroup();
104 hashedWheelTimer = new HashedWheelTimer();
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)));
121 for (final NetconfOperationServiceFactory netconfOperationServiceFactory : getAdditionalServiceFactories(
122 factoriesListener)) {
123 factoriesListener.onAddNetconfOperationServiceFactory(netconfOperationServiceFactory);
126 serverTcpChannel = startNetconfTcpServer(factoriesListener, netconfMonitoringService);
128 new NetconfClientDispatcherImpl(getNettyThreadgroup(), getNettyThreadgroup(), getHashedWheelTimer());
132 * Called before setUp method is executed, so test classes can set up resources before
133 * setUpAbstractNetconfConfigTest method is called.
135 protected void setUpTestInitial() throws Exception {}
137 private void loadMessages() throws Exception {
138 this.getConfig = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/getConfig.xml");
139 this.get = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/get.xml");
142 public NetconfMessage getGetConfig() {
146 public NetconfMessage getGet() {
150 private Channel startNetconfTcpServer(final AggregatedNetconfOperationServiceFactory listener,
151 final NetconfMonitoringService monitoring) throws Exception {
152 final NetconfServerDispatcherImpl dispatch = createDispatcher(listener, monitoring);
154 final ChannelFuture s;
155 if (getTcpServerAddress() instanceof LocalAddress) {
156 s = dispatch.createLocalServer(((LocalAddress) getTcpServerAddress()));
158 s = dispatch.createServer(((InetSocketAddress) getTcpServerAddress()));
160 s.await(RESOURCE_TIMEOUT_MINUTES, TimeUnit.MINUTES);
164 protected Iterable<NetconfOperationServiceFactory> getAdditionalServiceFactories(
165 final AggregatedNetconfOperationServiceFactory factoriesListener) throws Exception {
166 return Collections.emptySet();
169 protected NetconfMonitoringService getNetconfMonitoringService(
170 final AggregatedNetconfOperationServiceFactory factoriesListener) throws Exception {
171 return new NetconfMonitoringServiceImpl(factoriesListener);
174 protected abstract SocketAddress getTcpServerAddress();
176 public NetconfClientDispatcherImpl getClientDispatcher() {
177 return clientDispatcher;
180 private HardcodedYangStoreService getYangStore() throws IOException {
181 final Collection<InputStream> yangDependencies = getBasicYangs();
182 return new HardcodedYangStoreService(yangDependencies, getBindingRuntimeContext());
185 static Collection<InputStream> getBasicYangs() throws IOException {
187 final List<String> paths = Arrays.asList("/META-INF/yang/config@2013-04-05.yang",
188 "/META-INF/yang/rpc-context@2013-06-17.yang",
189 "/META-INF/yang/config-test.yang", "/META-INF/yang/config-test-impl.yang",
190 "/META-INF/yang/test-types.yang", "/META-INF/yang/test-groups.yang",
191 "/META-INF/yang/ietf-inet-types@2013-07-15.yang");
193 final Collection<InputStream> yangDependencies = new ArrayList<>();
194 final List<String> failedToFind = new ArrayList<>();
195 for (final String path : paths) {
196 final InputStream resourceAsStream = NetconfITTest.class.getResourceAsStream(path);
197 if (resourceAsStream == null) {
198 failedToFind.add(path);
200 yangDependencies.add(resourceAsStream);
203 assertEquals("Some yang files were not found", Collections.<String>emptyList(), failedToFind);
204 return yangDependencies;
207 protected NetconfServerDispatcherImpl createDispatcher(
208 final AggregatedNetconfOperationServiceFactory factoriesListener,
209 final NetconfMonitoringService sessionMonitoringService) {
210 final SessionIdProvider idProvider = new SessionIdProvider();
212 final NetconfServerSessionNegotiatorFactory serverNegotiatorFactory =
213 new NetconfServerSessionNegotiatorFactory(hashedWheelTimer, factoriesListener, idProvider,
214 SERVER_CONNECTION_TIMEOUT_MILLIS, sessionMonitoringService);
216 final NetconfServerDispatcherImpl.ServerChannelInitializer serverChannelInitializer =
217 new NetconfServerDispatcherImpl.ServerChannelInitializer(serverNegotiatorFactory);
218 return new NetconfServerDispatcherImpl(serverChannelInitializer, nettyThreadgroup, nettyThreadgroup);
221 protected HashedWheelTimer getHashedWheelTimer() {
222 return hashedWheelTimer;
225 protected EventLoopGroup getNettyThreadgroup() {
226 return nettyThreadgroup;
230 * @After in subclasses is be called before this.
233 public void cleanUpNetconf() throws Exception {
234 serverTcpChannel.close().await(RESOURCE_TIMEOUT_MINUTES, TimeUnit.MINUTES);
235 hashedWheelTimer.stop();
236 nettyThreadgroup.shutdownGracefully().await(RESOURCE_TIMEOUT_MINUTES, TimeUnit.MINUTES);
239 public NetconfClientConfiguration getClientConfiguration(final InetSocketAddress tcpAddress, final int timeout) {
240 final NetconfClientConfigurationBuilder b = NetconfClientConfigurationBuilder.create();
241 b.withAddress(tcpAddress);
242 b.withSessionListener(new SimpleNetconfClientSessionListener());
243 b.withReconnectStrategy(new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE, timeout));
244 b.withConnectionTimeoutMillis(timeout);
248 public static final class HardcodedYangStoreService extends YangStoreService {
249 public HardcodedYangStoreService(final Collection<? extends InputStream> inputStreams,
250 final BindingRuntimeContext bindingRuntimeContext) throws IOException {
251 super(new SchemaContextProvider() {
253 public SchemaContext getSchemaContext() {
254 return getSchema(inputStreams);
256 }, new SchemaSourceProvider<YangTextSchemaSource>() {
258 public CheckedFuture<? extends YangTextSchemaSource, SchemaSourceException> getSource(
259 SourceIdentifier sourceIdentifier) {
265 refresh(bindingRuntimeContext);
268 private static SchemaContext getSchema(final Collection<? extends InputStream> inputStreams) {
269 final ArrayList<InputStream> byteArrayInputStreams = new ArrayList<>();
270 for (final InputStream inputStream : inputStreams) {
271 assertNotNull(inputStream);
272 final byte[] content;
274 content = ByteStreams.toByteArray(inputStream);
275 } catch (IOException e) {
276 throw new IllegalStateException("Cannot read " + inputStream, e);
278 final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(content);
279 byteArrayInputStreams.add(byteArrayInputStream);
282 for (final InputStream inputStream : byteArrayInputStreams) {
285 } catch (final IOException e) {
286 throw new RuntimeException(e);
291 return YangInferencePipeline.RFC6020_REACTOR.newBuild().buildEffective(byteArrayInputStreams);
292 } catch (SourceException | ReactorException e) {
293 throw Throwables.propagate(e);
298 public EnumResolver getEnumResolver() {
299 return new EnumResolver() {
301 public String fromYang(final String enumType, final String enumYangValue) {
302 return BindingMapping.getClassName(enumYangValue);
306 public String toYang(final String enumType, final String enumJavaValue) {
307 return enumJavaValue.toLowerCase();