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.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");
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);
199 yangDependencies.add(resourceAsStream);
202 assertEquals("Some yang files were not found", Collections.<String>emptyList(), failedToFind);
203 return yangDependencies;
206 protected NetconfServerDispatcherImpl createDispatcher(
207 final AggregatedNetconfOperationServiceFactory factoriesListener,
208 final NetconfMonitoringService sessionMonitoringService) {
209 final SessionIdProvider idProvider = new SessionIdProvider();
211 final NetconfServerSessionNegotiatorFactory serverNegotiatorFactory =
212 new NetconfServerSessionNegotiatorFactory(hashedWheelTimer, factoriesListener, idProvider,
213 SERVER_CONNECTION_TIMEOUT_MILLIS, sessionMonitoringService);
215 final NetconfServerDispatcherImpl.ServerChannelInitializer serverChannelInitializer =
216 new NetconfServerDispatcherImpl.ServerChannelInitializer(serverNegotiatorFactory);
217 return new NetconfServerDispatcherImpl(serverChannelInitializer, nettyThreadgroup, nettyThreadgroup);
220 protected HashedWheelTimer getHashedWheelTimer() {
221 return hashedWheelTimer;
224 protected EventLoopGroup getNettyThreadgroup() {
225 return nettyThreadgroup;
229 * @After in subclasses is be called before this.
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);
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);
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() {
252 public SchemaContext getSchemaContext() {
253 return getSchema(inputStreams);
255 }, new SchemaSourceProvider<YangTextSchemaSource>() {
257 public CheckedFuture<? extends YangTextSchemaSource, SchemaSourceException> getSource(
258 SourceIdentifier sourceIdentifier) {
264 refresh(bindingRuntimeContext);
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;
273 content = ByteStreams.toByteArray(inputStream);
274 } catch (IOException e) {
275 throw new IllegalStateException("Cannot read " + inputStream, e);
277 final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(content);
278 byteArrayInputStreams.add(byteArrayInputStream);
281 for (final InputStream inputStream : byteArrayInputStreams) {
284 } catch (final IOException e) {
285 throw new RuntimeException(e);
290 return YangInferencePipeline.RFC6020_REACTOR.newBuild().buildEffective(byteArrayInputStreams);
291 } catch (SourceException | ReactorException e) {
292 throw Throwables.propagate(e);
297 public EnumResolver getEnumResolver() {
298 return new EnumResolver() {
300 public String fromYang(final String enumType, final String enumYangValue) {
301 return BindingMapping.getClassName(enumYangValue);
305 public String toYang(final String enumType, final String enumJavaValue) {
306 return enumJavaValue.toLowerCase();