Bump sshd to 2.9.1
[netconf.git] / netconf / mdsal-netconf-ssh / src / main / java / org / opendaylight / netconf / ssh / SshProxyServer.java
index 7e192d7364e2c52896759e3c902cb9bd1568a773..21c44d459120b61ac1e236bf684ca0bd73939934 100644 (file)
@@ -12,14 +12,17 @@ import static java.util.Objects.requireNonNull;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.ImmutableList;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
 import io.netty.channel.EventLoopGroup;
 import java.io.IOException;
 import java.nio.channels.AsynchronousChannelGroup;
 import java.time.Duration;
 import java.util.List;
 import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
 import org.opendaylight.netconf.shaded.sshd.common.FactoryManager;
 import org.opendaylight.netconf.shaded.sshd.common.NamedFactory;
 import org.opendaylight.netconf.shaded.sshd.common.RuntimeSshException;
@@ -127,26 +130,32 @@ public class SshProxyServer implements AutoCloseable {
     private abstract static class AbstractNioServiceFactory extends AbstractCloseable implements IoServiceFactory {
         private final FactoryManager manager;
         private final AsynchronousChannelGroup group;
-
+        private final ExecutorService resumeTasks;
         private IoServiceEventListener eventListener;
 
-        AbstractNioServiceFactory(final FactoryManager manager, final AsynchronousChannelGroup group) {
+        AbstractNioServiceFactory(final FactoryManager manager, final AsynchronousChannelGroup group,
+                final ExecutorService resumeTasks) {
             this.manager = requireNonNull(manager);
             this.group = requireNonNull(group);
+            this.resumeTasks = requireNonNull(resumeTasks);
         }
 
         final AsynchronousChannelGroup group() {
             return group;
         }
 
+        final ExecutorService resumeTasks() {
+            return resumeTasks;
+        }
+
         @Override
         public final IoConnector createConnector(final IoHandler handler) {
-            return new Nio2Connector(manager, handler, group);
+            return new Nio2Connector(manager, handler, group, resumeTasks);
         }
 
         @Override
         public final IoAcceptor createAcceptor(final IoHandler handler) {
-            return new Nio2Acceptor(manager, handler, group);
+            return new Nio2Acceptor(manager, handler, group, resumeTasks);
         }
 
         @Override
@@ -164,14 +173,17 @@ public class SshProxyServer implements AutoCloseable {
      * Based on Nio2ServiceFactory with one addition: injectable executor.
      */
     private static final class NioServiceWithPoolFactory extends AbstractNioServiceFactory {
-        NioServiceWithPoolFactory(final FactoryManager manager, final AsynchronousChannelGroup group) {
-            super(manager, group);
+        NioServiceWithPoolFactory(final FactoryManager manager, final AsynchronousChannelGroup group,
+                final ExecutorService resumeTasks) {
+            super(manager, group, resumeTasks);
         }
 
         @Override
         protected void doCloseImmediately() {
             try {
+                resumeTasks().shutdownNow();
                 group().shutdownNow();
+                resumeTasks().awaitTermination(5, TimeUnit.SECONDS);
                 group().awaitTermination(5, TimeUnit.SECONDS);
             } catch (final IOException | InterruptedException e) {
                 log.debug("Exception caught while closing channel group", e);
@@ -182,6 +194,8 @@ public class SshProxyServer implements AutoCloseable {
     }
 
     private static final class NioServiceWithPoolFactoryFactory extends Nio2ServiceFactoryFactory {
+        private static final AtomicLong COUNTER = new AtomicLong();
+
         private final ExecutorServiceFacade nioExecutor;
 
         NioServiceWithPoolFactoryFactory(final ExecutorService nioExecutor) {
@@ -191,7 +205,10 @@ public class SshProxyServer implements AutoCloseable {
         @Override
         public IoServiceFactory create(final FactoryManager manager) {
             try {
-                return new NioServiceWithPoolFactory(manager, AsynchronousChannelGroup.withThreadPool(nioExecutor));
+                return new NioServiceWithPoolFactory(manager, AsynchronousChannelGroup.withThreadPool(nioExecutor),
+                    Executors.newSingleThreadExecutor(new ThreadFactoryBuilder()
+                        .setNameFormat("sshd-resume-read-" + COUNTER.getAndIncrement() + "-%d")
+                        .build()));
             } catch (final IOException e) {
                 throw new RuntimeSshException("Failed to create channel group", e);
             }
@@ -199,8 +216,9 @@ public class SshProxyServer implements AutoCloseable {
     }
 
     private static final class SharedNioServiceFactory extends AbstractNioServiceFactory {
-        SharedNioServiceFactory(final FactoryManager manager, final AsynchronousChannelGroup group) {
-            super(manager, group);
+        SharedNioServiceFactory(final FactoryManager manager, final AsynchronousChannelGroup group,
+                final ExecutorService resumeTasks) {
+            super(manager, group, resumeTasks);
         }
     }
 
@@ -213,7 +231,7 @@ public class SshProxyServer implements AutoCloseable {
 
         @Override
         public IoServiceFactory create(final FactoryManager manager) {
-            return new SharedNioServiceFactory(manager, group);
+            return new SharedNioServiceFactory(manager, group, Executors.newSingleThreadExecutor());
         }
     }
 }