import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
import com.google.common.base.Stopwatch;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.util.HashedWheelTimer;
+import java.io.File;
import java.net.InetSocketAddress;
+import java.nio.file.Files;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
-import org.junit.After;
-import org.junit.Before;
+import org.apache.sshd.server.PasswordAuthenticator;
+import org.apache.sshd.server.keyprovider.PEMGeneratorHostKeyProvider;
+import org.apache.sshd.server.session.ServerSession;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
import org.junit.Test;
-import org.opendaylight.controller.netconf.auth.AuthProvider;
import org.opendaylight.controller.netconf.netty.EchoClientHandler.State;
import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.LoginPassword;
import org.opendaylight.controller.netconf.nettyutil.handler.ssh.client.AsyncSshHandler;
-import org.opendaylight.controller.netconf.ssh.NetconfSSHServer;
-import org.opendaylight.controller.netconf.ssh.authentication.PEMGenerator;
+import org.opendaylight.controller.netconf.ssh.SshProxyServer;
+import org.opendaylight.controller.netconf.ssh.SshProxyServerConfigurationBuilder;
import org.opendaylight.controller.netconf.util.osgi.NetconfConfigUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SSHTest {
- public static final Logger logger = LoggerFactory.getLogger(SSHTest.class);
+ private static final Logger LOG = LoggerFactory.getLogger(SSHTest.class);
public static final String AHOJ = "ahoj\n";
- private EventLoopGroup nettyGroup;
- HashedWheelTimer hashedWheelTimer;
- @Before
- public void setUp() throws Exception {
+ private static EventLoopGroup nettyGroup;
+ private static HashedWheelTimer hashedWheelTimer;
+ private static ExecutorService nioExec;
+ private static ScheduledExecutorService minaTimerEx;
+
+ @BeforeClass
+ public static void setUp() throws Exception {
hashedWheelTimer = new HashedWheelTimer();
nettyGroup = new NioEventLoopGroup();
+ nioExec = Executors.newFixedThreadPool(1);
+ minaTimerEx = Executors.newScheduledThreadPool(1);
}
- @After
- public void tearDown() throws Exception {
+ @AfterClass
+ public static void tearDown() throws Exception {
hashedWheelTimer.stop();
- nettyGroup.shutdownGracefully();
+ nettyGroup.shutdownGracefully().await();
+ minaTimerEx.shutdownNow();
+ nioExec.shutdownNow();
}
@Test
public void test() throws Exception {
+ File sshKeyPair = Files.createTempFile("sshKeyPair", ".pem").toFile();
+ sshKeyPair.deleteOnExit();
new Thread(new EchoServer(), "EchoServer").start();
- AuthProvider authProvider = mock(AuthProvider.class);
- doReturn(true).when(authProvider).authenticated(anyString(), anyString());
- doReturn("auth").when(authProvider).toString();
-
- NetconfSSHServer netconfSSHServer = NetconfSSHServer.start(10831, NetconfConfigUtil.getNetconfLocalAddress(),
- new NioEventLoopGroup(), PEMGenerator.generate().toCharArray());
- netconfSSHServer.setAuthProvider(authProvider);
- InetSocketAddress address = netconfSSHServer.getLocalSocketAddress();
+ final InetSocketAddress addr = new InetSocketAddress("127.0.0.1", 10831);
+ final SshProxyServer sshProxyServer = new SshProxyServer(minaTimerEx, nettyGroup, nioExec);
+ sshProxyServer.bind(
+ new SshProxyServerConfigurationBuilder().setBindingAddress(addr).setLocalAddress(NetconfConfigUtil.getNetconfLocalAddress()).setAuthenticator(new PasswordAuthenticator() {
+ @Override
+ public boolean authenticate(final String username, final String password, final ServerSession session) {
+ return true;
+ }
+ }).setKeyPairProvider(new PEMGeneratorHostKeyProvider(sshKeyPair.toPath().toAbsolutePath().toString())).setIdleTimeout(Integer.MAX_VALUE).createSshProxyServerConfiguration());
- final EchoClientHandler echoClientHandler = connectClient(new InetSocketAddress("localhost", address.getPort()));
+ final EchoClientHandler echoClientHandler = connectClient(addr);
Stopwatch stopwatch = new Stopwatch().start();
- while(echoClientHandler.isConnected() == false && stopwatch.elapsed(TimeUnit.SECONDS) < 5) {
- Thread.sleep(100);
+ while(echoClientHandler.isConnected() == false && stopwatch.elapsed(TimeUnit.SECONDS) < 30) {
+ Thread.sleep(500);
}
assertTrue(echoClientHandler.isConnected());
- logger.info("connected, writing to client");
+ LOG.info("connected, writing to client");
echoClientHandler.write(AHOJ);
+
// check that server sent back the same string
stopwatch = stopwatch.reset().start();
- while (echoClientHandler.read().endsWith(AHOJ) == false && stopwatch.elapsed(TimeUnit.SECONDS) < 5) {
- Thread.sleep(100);
+ while (echoClientHandler.read().endsWith(AHOJ) == false && stopwatch.elapsed(TimeUnit.SECONDS) < 30) {
+ Thread.sleep(500);
}
+
try {
- String read = echoClientHandler.read();
+ final String read = echoClientHandler.read();
assertTrue(read + " should end with " + AHOJ, read.endsWith(AHOJ));
} finally {
- logger.info("Closing socket");
- netconfSSHServer.close();
- netconfSSHServer.join();
+ LOG.info("Closing socket");
+ sshProxyServer.close();
}
}
- public EchoClientHandler connectClient(InetSocketAddress address) {
+ public EchoClientHandler connectClient(final InetSocketAddress address) {
final EchoClientHandler echoClientHandler = new EchoClientHandler();
- ChannelInitializer<NioSocketChannel> channelInitializer = new ChannelInitializer<NioSocketChannel>() {
+ final ChannelInitializer<NioSocketChannel> channelInitializer = new ChannelInitializer<NioSocketChannel>() {
@Override
- public void initChannel(NioSocketChannel ch) throws Exception {
+ public void initChannel(final NioSocketChannel ch) throws Exception {
ch.pipeline().addFirst(AsyncSshHandler.createForNetconfSubsystem(new LoginPassword("a", "a")));
ch.pipeline().addLast(echoClientHandler);
}
};
- Bootstrap b = new Bootstrap();
+ final Bootstrap b = new Bootstrap();
b.group(nettyGroup)
.channel(NioSocketChannel.class)
@Test
public void testClientWithoutServer() throws Exception {
- InetSocketAddress address = new InetSocketAddress(12345);
+ final InetSocketAddress address = new InetSocketAddress(12345);
final EchoClientHandler echoClientHandler = connectClient(address);
- Stopwatch stopwatch = new Stopwatch().start();
+ final Stopwatch stopwatch = new Stopwatch().start();
while(echoClientHandler.getState() == State.CONNECTING && stopwatch.elapsed(TimeUnit.SECONDS) < 5) {
Thread.sleep(100);
}
assertFalse(echoClientHandler.isConnected());
- assertEquals(State.CONNECTION_CLOSED, echoClientHandler.getState());
+ assertEquals(State.FAILED_TO_CONNECT, echoClientHandler.getState());
}
}