2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
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
9 package org.opendaylight.controller.netconf.netty;
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertFalse;
13 import static org.junit.Assert.assertTrue;
15 import com.google.common.base.Stopwatch;
16 import io.netty.bootstrap.Bootstrap;
17 import io.netty.channel.ChannelInitializer;
18 import io.netty.channel.EventLoopGroup;
19 import io.netty.channel.nio.NioEventLoopGroup;
20 import io.netty.channel.socket.nio.NioSocketChannel;
21 import io.netty.util.HashedWheelTimer;
23 import java.net.InetSocketAddress;
24 import java.nio.file.Files;
25 import java.util.concurrent.ExecutorService;
26 import java.util.concurrent.Executors;
27 import java.util.concurrent.ScheduledExecutorService;
28 import java.util.concurrent.TimeUnit;
29 import org.apache.sshd.server.PasswordAuthenticator;
30 import org.apache.sshd.server.keyprovider.PEMGeneratorHostKeyProvider;
31 import org.apache.sshd.server.session.ServerSession;
32 import org.junit.AfterClass;
33 import org.junit.BeforeClass;
34 import org.junit.Test;
35 import org.opendaylight.controller.netconf.netty.EchoClientHandler.State;
36 import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.LoginPassword;
37 import org.opendaylight.controller.netconf.nettyutil.handler.ssh.client.AsyncSshHandler;
38 import org.opendaylight.controller.netconf.ssh.SshProxyServer;
39 import org.opendaylight.controller.netconf.ssh.SshProxyServerConfigurationBuilder;
40 import org.opendaylight.controller.netconf.util.osgi.NetconfConfigUtil;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
44 public class SSHTest {
45 private static final Logger LOG = LoggerFactory.getLogger(SSHTest.class);
46 public static final String AHOJ = "ahoj\n";
48 private static EventLoopGroup nettyGroup;
49 private static HashedWheelTimer hashedWheelTimer;
50 private static ExecutorService nioExec;
51 private static ScheduledExecutorService minaTimerEx;
54 public static void setUp() throws Exception {
55 hashedWheelTimer = new HashedWheelTimer();
56 nettyGroup = new NioEventLoopGroup();
57 nioExec = Executors.newFixedThreadPool(1);
58 minaTimerEx = Executors.newScheduledThreadPool(1);
62 public static void tearDown() throws Exception {
63 hashedWheelTimer.stop();
64 nettyGroup.shutdownGracefully().await();
65 minaTimerEx.shutdownNow();
66 nioExec.shutdownNow();
70 public void test() throws Exception {
71 File sshKeyPair = Files.createTempFile("sshKeyPair", ".pem").toFile();
72 sshKeyPair.deleteOnExit();
73 new Thread(new EchoServer(), "EchoServer").start();
75 final InetSocketAddress addr = new InetSocketAddress("127.0.0.1", 10831);
76 final SshProxyServer sshProxyServer = new SshProxyServer(minaTimerEx, nettyGroup, nioExec);
78 new SshProxyServerConfigurationBuilder().setBindingAddress(addr).setLocalAddress(NetconfConfigUtil.getNetconfLocalAddress()).setAuthenticator(new PasswordAuthenticator() {
80 public boolean authenticate(final String username, final String password, final ServerSession session) {
83 }).setKeyPairProvider(new PEMGeneratorHostKeyProvider(sshKeyPair.toPath().toAbsolutePath().toString())).setIdleTimeout(Integer.MAX_VALUE).createSshProxyServerConfiguration());
85 final EchoClientHandler echoClientHandler = connectClient(addr);
87 Stopwatch stopwatch = Stopwatch.createStarted();
88 while(echoClientHandler.isConnected() == false && stopwatch.elapsed(TimeUnit.SECONDS) < 30) {
91 assertTrue(echoClientHandler.isConnected());
92 LOG.info("connected, writing to client");
93 echoClientHandler.write(AHOJ);
95 // check that server sent back the same string
96 stopwatch = stopwatch.reset().start();
97 while (echoClientHandler.read().endsWith(AHOJ) == false && stopwatch.elapsed(TimeUnit.SECONDS) < 30) {
102 final String read = echoClientHandler.read();
103 assertTrue(read + " should end with " + AHOJ, read.endsWith(AHOJ));
105 LOG.info("Closing socket");
106 sshProxyServer.close();
110 public EchoClientHandler connectClient(final InetSocketAddress address) {
111 final EchoClientHandler echoClientHandler = new EchoClientHandler();
112 final ChannelInitializer<NioSocketChannel> channelInitializer = new ChannelInitializer<NioSocketChannel>() {
114 public void initChannel(final NioSocketChannel ch) throws Exception {
115 ch.pipeline().addFirst(AsyncSshHandler.createForNetconfSubsystem(new LoginPassword("a", "a")));
116 ch.pipeline().addLast(echoClientHandler);
119 final Bootstrap b = new Bootstrap();
122 .channel(NioSocketChannel.class)
123 .handler(channelInitializer);
126 b.connect(address).addListener(echoClientHandler);
127 return echoClientHandler;
131 public void testClientWithoutServer() throws Exception {
132 final InetSocketAddress address = new InetSocketAddress(12345);
133 final EchoClientHandler echoClientHandler = connectClient(address);
134 final Stopwatch stopwatch = Stopwatch.createStarted();
135 while(echoClientHandler.getState() == State.CONNECTING && stopwatch.elapsed(TimeUnit.SECONDS) < 5) {
138 assertFalse(echoClientHandler.isConnected());
139 assertEquals(State.FAILED_TO_CONNECT, echoClientHandler.getState());