Add option to provide custom SshClient for netconf-client 70/87970/1
authorTibor Král <tibor.kral@pantheon.tech>
Mon, 24 Feb 2020 15:28:11 +0000 (16:28 +0100)
committerRobert Varga <nite@hq.sk>
Tue, 3 Mar 2020 15:18:52 +0000 (15:18 +0000)
When creating netconf-client the DEFAULT SshClient is
used on the background by the AsyncSshHandler. This adds
the option to provide custom SshClient to be used instead.

JIRA: NETCONF-641
Change-Id: I99b1c2e882353732a2e55d0523ee6adbd1ca8cc0
Signed-off-by: Tibor Král <tibor.kral@pantheon.tech>
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit 995f11a17da91d69a4c6650016ff4b6afafc1259)

netconf/netconf-client/src/main/java/org/opendaylight/netconf/client/NetconfClientDispatcherImpl.java
netconf/netconf-client/src/main/java/org/opendaylight/netconf/client/SshClientChannelInitializer.java
netconf/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/ssh/client/AsyncSshHandler.java
netconf/tools/netconf-testtool/src/main/java/org/opendaylight/netconf/test/tool/client/stress/ConfigurableClientDispatcher.java
netconf/tools/netconf-testtool/src/main/java/org/opendaylight/netconf/test/tool/client/stress/StressClient.java

index 2f76f2b8b7ee4ae0815c1a633b536b8b2dcfe4ae..321cb4ba44a20d9b6c71cd524aa71e553a6511fe 100644 (file)
@@ -13,6 +13,8 @@ import io.netty.util.concurrent.Future;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
+import org.apache.sshd.client.SshClient;
+import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.netconf.client.conf.NetconfClientConfiguration;
 import org.opendaylight.netconf.client.conf.NetconfReconnectingClientConfiguration;
 import org.opendaylight.netconf.nettyutil.AbstractNetconfDispatcher;
@@ -27,11 +29,18 @@ public class NetconfClientDispatcherImpl
     private static final Logger LOG = LoggerFactory.getLogger(NetconfClientDispatcherImpl.class);
 
     private final Timer timer;
+    private final SshClient sshClient;
 
     public NetconfClientDispatcherImpl(final EventLoopGroup bossGroup, final EventLoopGroup workerGroup,
-                                       final Timer timer) {
+                                       final Timer timer, @Nullable final SshClient sshClient) {
         super(bossGroup, workerGroup);
         this.timer = timer;
+        this.sshClient = sshClient;
+    }
+
+    public NetconfClientDispatcherImpl(final EventLoopGroup bossGroup, final EventLoopGroup workerGroup,
+            final Timer timer) {
+        this(bossGroup, workerGroup, timer, null);
     }
 
     protected Timer getTimer() {
@@ -90,15 +99,15 @@ public class NetconfClientDispatcherImpl
         LOG.debug("Creating SSH client with configuration: {}", currentConfiguration);
         return super.createClient(currentConfiguration.getAddress(), currentConfiguration.getReconnectStrategy(),
             (ch, sessionPromise) -> new SshClientChannelInitializer(currentConfiguration.getAuthHandler(),
-                        getNegotiatorFactory(currentConfiguration), currentConfiguration.getSessionListener())
-                        .initialize(ch, sessionPromise));
+                        getNegotiatorFactory(currentConfiguration), currentConfiguration.getSessionListener(),
+                    sshClient).initialize(ch, sessionPromise));
     }
 
     private Future<Void> createReconnectingSshClient(
             final NetconfReconnectingClientConfiguration currentConfiguration) {
         LOG.debug("Creating reconnecting SSH client with configuration: {}", currentConfiguration);
         final SshClientChannelInitializer init = new SshClientChannelInitializer(currentConfiguration.getAuthHandler(),
-                getNegotiatorFactory(currentConfiguration), currentConfiguration.getSessionListener());
+                getNegotiatorFactory(currentConfiguration), currentConfiguration.getSessionListener(), sshClient);
 
         return super.createReconnectingClient(currentConfiguration.getAddress(), currentConfiguration
                 .getConnectStrategyFactory(), currentConfiguration.getReconnectStrategy(),
index 37211c9a791e7fec105335e2a55f3b115f01e9cb..66278ef2ec853be69ade42ffdc1ddad7f15938de 100644 (file)
@@ -9,6 +9,8 @@ package org.opendaylight.netconf.client;
 
 import io.netty.channel.Channel;
 import io.netty.util.concurrent.Promise;
+import org.apache.sshd.client.SshClient;
+import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.netconf.nettyutil.AbstractChannelInitializer;
 import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
 import org.opendaylight.netconf.nettyutil.handler.ssh.client.AsyncSshHandler;
@@ -18,19 +20,27 @@ final class SshClientChannelInitializer extends AbstractChannelInitializer<Netco
     private final AuthenticationHandler authenticationHandler;
     private final NetconfClientSessionNegotiatorFactory negotiatorFactory;
     private final NetconfClientSessionListener sessionListener;
+    private final SshClient sshClient;
 
     SshClientChannelInitializer(final AuthenticationHandler authHandler,
-                                final NetconfClientSessionNegotiatorFactory negotiatorFactory,
-                                final NetconfClientSessionListener sessionListener) {
+            final NetconfClientSessionNegotiatorFactory negotiatorFactory,
+            final NetconfClientSessionListener sessionListener, @Nullable final SshClient sshClient) {
         this.authenticationHandler = authHandler;
         this.negotiatorFactory = negotiatorFactory;
         this.sessionListener = sessionListener;
+        this.sshClient = sshClient;
+    }
+
+    SshClientChannelInitializer(final AuthenticationHandler authHandler,
+            final NetconfClientSessionNegotiatorFactory negotiatorFactory,
+            final NetconfClientSessionListener sessionListener) {
+        this(authHandler, negotiatorFactory, sessionListener, null);
     }
 
     @Override
     public void initialize(final Channel ch, final Promise<NetconfClientSession> promise) {
         // ssh handler has to be the first handler in pipeline
-        ch.pipeline().addFirst(AsyncSshHandler.createForNetconfSubsystem(authenticationHandler, promise));
+        ch.pipeline().addFirst(AsyncSshHandler.createForNetconfSubsystem(authenticationHandler, promise, sshClient));
         super.initialize(ch, promise);
     }
 
index 15882ded63ec8d1acfdf09f0f9284e5d59a65f8e..513873cbdd6c0f678f9eb07ee46c5cf479e55e63 100644 (file)
@@ -22,6 +22,7 @@ import org.apache.sshd.client.channel.ClientChannel;
 import org.apache.sshd.client.future.AuthFuture;
 import org.apache.sshd.client.future.ConnectFuture;
 import org.apache.sshd.client.session.ClientSession;
+import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -95,8 +96,9 @@ public class AsyncSshHandler extends ChannelOutboundHandlerAdapter {
      * @return                      {@code AsyncSshHandler}
      */
     public static AsyncSshHandler createForNetconfSubsystem(final AuthenticationHandler authenticationHandler,
-            final Future<?> negotiationFuture) {
-        return new AsyncSshHandler(authenticationHandler, DEFAULT_CLIENT, negotiationFuture);
+            final Future<?> negotiationFuture, @Nullable final SshClient sshClient) {
+        return new AsyncSshHandler(authenticationHandler, sshClient != null ? sshClient : DEFAULT_CLIENT,
+                negotiationFuture);
     }
 
     private void startSsh(final ChannelHandlerContext ctx, final SocketAddress address) throws IOException {
index 2b1279b54399fc9c6434720f26b5e3651e1c1ce2..22a70e5fb1c90fbc73d582727e27c68950cd4c7a 100644 (file)
@@ -11,6 +11,8 @@ package org.opendaylight.netconf.test.tool.client.stress;
 import io.netty.channel.EventLoopGroup;
 import io.netty.util.Timer;
 import java.util.Set;
+import org.apache.sshd.client.SshClient;
+import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.netconf.client.NetconfClientDispatcherImpl;
 import org.opendaylight.netconf.client.NetconfClientSessionNegotiatorFactory;
 import org.opendaylight.netconf.client.conf.NetconfClientConfiguration;
@@ -20,8 +22,8 @@ public final class ConfigurableClientDispatcher extends NetconfClientDispatcherI
     private final Set<String> capabilities;
 
     private ConfigurableClientDispatcher(final EventLoopGroup bossGroup, final EventLoopGroup workerGroup,
-                                         final Timer timer, final Set<String> capabilities) {
-        super(bossGroup, workerGroup, timer);
+            final Timer timer, final Set<String> capabilities, @Nullable final SshClient sshClient) {
+        super(bossGroup, workerGroup, timer, sshClient);
         this.capabilities = capabilities;
     }
 
@@ -29,36 +31,36 @@ public final class ConfigurableClientDispatcher extends NetconfClientDispatcherI
      * EXI + chunked framing.
      */
     public static ConfigurableClientDispatcher createChunkedExi(final EventLoopGroup bossGroup,
-                                                                final EventLoopGroup workerGroup, final Timer timer) {
+            final EventLoopGroup workerGroup, final Timer timer, @Nullable final SshClient sshClient) {
         return new ConfigurableClientDispatcher(bossGroup, workerGroup, timer,
-            NetconfClientSessionNegotiatorFactory.EXI_CLIENT_CAPABILITIES);
+            NetconfClientSessionNegotiatorFactory.EXI_CLIENT_CAPABILITIES, sshClient);
     }
 
     /**
      * EXI + ]]gt;]]gt; framing.
      */
     public static ConfigurableClientDispatcher createLegacyExi(final EventLoopGroup bossGroup,
-                                                               final EventLoopGroup workerGroup, final Timer timer) {
+            final EventLoopGroup workerGroup, final Timer timer, @Nullable final SshClient sshClient) {
         return new ConfigurableClientDispatcher(bossGroup, workerGroup, timer,
-            NetconfClientSessionNegotiatorFactory.LEGACY_EXI_CLIENT_CAPABILITIES);
+            NetconfClientSessionNegotiatorFactory.LEGACY_EXI_CLIENT_CAPABILITIES, sshClient);
     }
 
     /**
      * Chunked framing.
      */
     public static ConfigurableClientDispatcher createChunked(final EventLoopGroup bossGroup,
-                                                             final EventLoopGroup workerGroup, final Timer timer) {
+            final EventLoopGroup workerGroup, final Timer timer, @Nullable final SshClient sshClient) {
         return new ConfigurableClientDispatcher(bossGroup, workerGroup, timer,
-            NetconfClientSessionNegotiatorFactory.DEFAULT_CLIENT_CAPABILITIES);
+            NetconfClientSessionNegotiatorFactory.DEFAULT_CLIENT_CAPABILITIES, sshClient);
     }
 
     /**
      * ]]gt;]]gt; framing.
      */
     public static ConfigurableClientDispatcher createLegacy(final EventLoopGroup bossGroup,
-                                                            final EventLoopGroup workerGroup, final Timer timer) {
+            final EventLoopGroup workerGroup, final Timer timer, @Nullable final SshClient sshClient) {
         return new ConfigurableClientDispatcher(bossGroup, workerGroup, timer,
-            NetconfClientSessionNegotiatorFactory.LEGACY_FRAMING_CLIENT_CAPABILITIES);
+            NetconfClientSessionNegotiatorFactory.LEGACY_FRAMING_CLIENT_CAPABILITIES, sshClient);
     }
 
     @Override
index 6d02ba259a94585aa3c4fdedcfc763ce522f8967..3832d9e11db1928028fc3748b8771276c4e7865e 100644 (file)
@@ -234,15 +234,17 @@ public final class StressClient {
         final NetconfClientDispatcherImpl netconfClientDispatcher;
         if (params.exi) {
             if (params.legacyFraming) {
-                netconfClientDispatcher = ConfigurableClientDispatcher.createLegacyExi(nioGroup, nioGroup, timer);
+                netconfClientDispatcher = ConfigurableClientDispatcher.createLegacyExi(nioGroup, nioGroup, timer,
+                        null);
             } else {
-                netconfClientDispatcher = ConfigurableClientDispatcher.createChunkedExi(nioGroup, nioGroup, timer);
+                netconfClientDispatcher = ConfigurableClientDispatcher.createChunkedExi(nioGroup, nioGroup, timer,
+                        null);
             }
         } else {
             if (params.legacyFraming) {
-                netconfClientDispatcher = ConfigurableClientDispatcher.createLegacy(nioGroup, nioGroup, timer);
+                netconfClientDispatcher = ConfigurableClientDispatcher.createLegacy(nioGroup, nioGroup, timer, null);
             } else {
-                netconfClientDispatcher = ConfigurableClientDispatcher.createChunked(nioGroup, nioGroup, timer);
+                netconfClientDispatcher = ConfigurableClientDispatcher.createChunked(nioGroup, nioGroup, timer, null);
             }
         }
         return netconfClientDispatcher;