This is an automated email from the ASF dual-hosted git repository.

lgoldstein pushed a commit to branch SSHD-931
in repository https://gitbox.apache.org/repos/asf/mina-sshd.git

commit c2ba677bf094e1e5764d4c4e08ad82544012d586
Author: Lyor Goldstein <lgoldst...@apache.org>
AuthorDate: Wed Jul 31 08:24:42 2019 +0300

    [SSHD-931] Added SFTP ExecutorProtectingSubsystemFactory
---
 docs/sftp.md                                       | 11 +++-
 .../sshd/common/util/threads/NoCloseExecutor.java  |  1 -
 .../sshd/common/util/threads/ThreadUtils.java      |  7 ++-
 .../sftp/ExecutorProtectingSubsystemFactory.java   | 71 ++++++++++++++++++++++
 .../subsystem/sftp/SftpSubsystemFactory.java       |  6 +-
 5 files changed, 89 insertions(+), 7 deletions(-)

diff --git a/docs/sftp.md b/docs/sftp.md
index 49dee63..5faff5f 100644
--- a/docs/sftp.md
+++ b/docs/sftp.md
@@ -25,7 +25,7 @@ On the server side, the following code needs to be added:
 
 ```
 
-### `SftpEventListener`
+#### `SftpEventListener`
 
 Provides information about major SFTP protocol events. The provided 
`File/DirectoryHandle` to the various callbacks can also be used to
 store user-defined attributes via its `AttributeStore` implementation. The 
listener is registered at the `SftpSubsystemFactory`:
@@ -61,7 +61,7 @@ store user-defined attributes via its `AttributeStore` 
implementation. The liste
 whether the close attempt was successful or not. In other words, after 
`SftpEventListener#closed` has been
 called, all attributes associated with the handle are cleared.
 
-### `SftpFileSystemAccessor`
+#### `SftpFileSystemAccessor`
 
 This is the abstraction providing the SFTP server subsystem access to files 
and directories. The SFTP subsystem
 uses this abstraction to obtain file channels and/or directory streams. One 
can override the default implementation
@@ -77,6 +77,13 @@ The accessor is registered/overwritten in via the 
`SftpSubSystemFactory`:
 
 ```
 
+#### Externally provided `CloseableExecutorService` re-use
+
+By default, the `SftpSubsystem` will close the executor service it uses when 
it is destroyed when the SFTP session
+is terminated. This is OK for the default internal executor being used. 
However, if users wish to provide their own
+service which should not be shut down on exit, then a special wrapper is 
required. Such a wrapper is available via
+the `ExecutorProtectingSubsystemFactory` class (available via the 
*sshd-contrib* module).
+
 **Note:**
 
 * Closing of file channel/directory streams created by the accessor are also 
closed
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/util/threads/NoCloseExecutor.java
 
b/sshd-common/src/main/java/org/apache/sshd/common/util/threads/NoCloseExecutor.java
index cb42805..6bb096b 100644
--- 
a/sshd-common/src/main/java/org/apache/sshd/common/util/threads/NoCloseExecutor.java
+++ 
b/sshd-common/src/main/java/org/apache/sshd/common/util/threads/NoCloseExecutor.java
@@ -156,5 +156,4 @@ public class NoCloseExecutor implements 
CloseableExecutorService {
     public boolean isClosing() {
         return isClosed();
     }
-
 }
\ No newline at end of file
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/util/threads/ThreadUtils.java
 
b/sshd-common/src/main/java/org/apache/sshd/common/util/threads/ThreadUtils.java
index bef05f0..dd46612 100644
--- 
a/sshd-common/src/main/java/org/apache/sshd/common/util/threads/ThreadUtils.java
+++ 
b/sshd-common/src/main/java/org/apache/sshd/common/util/threads/ThreadUtils.java
@@ -48,12 +48,13 @@ public final class ThreadUtils {
      *
      * @param executorService The original service - ignored if {@code null}
      * @param shutdownOnExit  If {@code true} then it is OK to shutdown the 
executor
-     *                        so no wrapping takes place.
+     * so no wrapping takes place.
      * @return Either the original service or a wrapped one - depending on the
      * value of the <tt>shutdownOnExit</tt> parameter
      */
-    public static CloseableExecutorService 
protectExecutorServiceShutdown(CloseableExecutorService executorService, 
boolean shutdownOnExit) {
-        if (executorService == null || shutdownOnExit || executorService 
instanceof NoCloseExecutor) {
+    public static CloseableExecutorService protectExecutorServiceShutdown(
+            CloseableExecutorService executorService, boolean shutdownOnExit) {
+        if ((executorService == null) || shutdownOnExit || (executorService 
instanceof NoCloseExecutor)) {
             return executorService;
         } else {
             return new NoCloseExecutor(executorService);
diff --git 
a/sshd-contrib/src/main/java/org/apache/sshd/server/subsystem/sftp/ExecutorProtectingSubsystemFactory.java
 
b/sshd-contrib/src/main/java/org/apache/sshd/server/subsystem/sftp/ExecutorProtectingSubsystemFactory.java
new file mode 100644
index 0000000..b3e6a52
--- /dev/null
+++ 
b/sshd-contrib/src/main/java/org/apache/sshd/server/subsystem/sftp/ExecutorProtectingSubsystemFactory.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sshd.server.subsystem.sftp;
+
+import org.apache.sshd.common.util.threads.CloseableExecutorService;
+import org.apache.sshd.common.util.threads.ThreadUtils;
+
+/**
+ * A {@link SftpSubsystemFactory} that protects its {@link 
CloseableExecutorService}
+ * so that when the subsystem is destroyed it will not close/shutdown the 
service.
+ *
+ * @author <a href="mailto:d...@mina.apache.org";>Apache MINA SSHD Project</a>
+ */
+public class ExecutorProtectingSubsystemFactory extends SftpSubsystemFactory {
+    public static class Builder extends SftpSubsystemFactory.Builder {
+        public Builder() {
+            super();
+        }
+
+        @Override
+        public Builder withExecutorService(CloseableExecutorService service) {
+            return (Builder) super.withExecutorService(service);
+        }
+
+        @Override
+        public Builder withFileSystemAccessor(SftpFileSystemAccessor accessor) 
{
+            return (Builder) super.withFileSystemAccessor(accessor);
+        }
+
+        @Override
+        public Builder 
withSftpErrorStatusDataHandler(SftpErrorStatusDataHandler handler) {
+            return (Builder) super.withSftpErrorStatusDataHandler(handler);
+        }
+
+        @Override
+        public Builder 
withUnsupportedAttributePolicy(UnsupportedAttributePolicy p) {
+            return (Builder) super.withUnsupportedAttributePolicy(p);
+        }
+
+        @Override
+        protected SftpSubsystemFactory createSftpSubsystemFactory() {
+            return new ExecutorProtectingSubsystemFactory();
+        }
+    }
+
+    public ExecutorProtectingSubsystemFactory() {
+        super();
+    }
+
+    @Override   // see SSHD-931
+    public CloseableExecutorService getExecutorService() {
+        return ThreadUtils.noClose(super.getExecutorService());
+    }
+}
diff --git 
a/sshd-sftp/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystemFactory.java
 
b/sshd-sftp/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystemFactory.java
index 056b5fa..015f47f 100644
--- 
a/sshd-sftp/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystemFactory.java
+++ 
b/sshd-sftp/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystemFactory.java
@@ -68,9 +68,13 @@ public class SftpSubsystemFactory
             return this;
         }
 
+        protected SftpSubsystemFactory createSftpSubsystemFactory() {
+            return new SftpSubsystemFactory();
+        }
+
         @Override
         public SftpSubsystemFactory build() {
-            SftpSubsystemFactory factory = new SftpSubsystemFactory();
+            SftpSubsystemFactory factory = createSftpSubsystemFactory();
             factory.setExecutorService(executors);
             factory.setUnsupportedAttributePolicy(policy);
             factory.setFileSystemAccessor(fileSystemAccessor);

Reply via email to