You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by gn...@apache.org on 2018/05/28 09:37:58 UTC
[1/3] mina-sshd git commit: [SSHD-819] Revert the fact that
CommandFactory now extends NamedFactory
Repository: mina-sshd
Updated Branches:
refs/heads/master 1a0409ee8 -> a4f4e2811
[SSHD-819] Revert the fact that CommandFactory now extends NamedFactory
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/d1c4f608
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/d1c4f608
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/d1c4f608
Branch: refs/heads/master
Commit: d1c4f608c6dc5544eb76334eaa82e46808ec81b1
Parents: 1a0409e
Author: Guillaume Nodet <gn...@apache.org>
Authored: Mon May 28 08:43:31 2018 +0200
Committer: Guillaume Nodet <gn...@apache.org>
Committed: Mon May 28 08:52:27 2018 +0200
----------------------------------------------------------------------
.../apache/sshd/cli/server/SshFsMounter.java | 2 +-
.../AbstractDelegatingCommandFactory.java | 2 +-
.../sshd/server/command/CommandFactory.java | 5 +-
.../shell/ProcessShellCommandFactory.java | 2 +-
.../server/shell/UnknownCommandFactory.java | 2 +-
.../sshd/client/channel/ChannelExecTest.java | 24 +---
.../sshd/client/session/ClientSessionTest.java | 98 +++++--------
.../java/org/apache/sshd/server/ServerTest.java | 144 +++++++------------
8 files changed, 96 insertions(+), 183 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/d1c4f608/sshd-cli/src/test/java/org/apache/sshd/cli/server/SshFsMounter.java
----------------------------------------------------------------------
diff --git a/sshd-cli/src/test/java/org/apache/sshd/cli/server/SshFsMounter.java b/sshd-cli/src/test/java/org/apache/sshd/cli/server/SshFsMounter.java
index c270be7..4fe1d99 100644
--- a/sshd-cli/src/test/java/org/apache/sshd/cli/server/SshFsMounter.java
+++ b/sshd-cli/src/test/java/org/apache/sshd/cli/server/SshFsMounter.java
@@ -232,7 +232,7 @@ public final class SshFsMounter extends SshServerCliSupport {
}
@Override
- public String getName() {
+ public String toString() {
return "mounter";
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/d1c4f608/sshd-core/src/main/java/org/apache/sshd/server/command/AbstractDelegatingCommandFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/command/AbstractDelegatingCommandFactory.java b/sshd-core/src/main/java/org/apache/sshd/server/command/AbstractDelegatingCommandFactory.java
index 3169958..e780c52 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/command/AbstractDelegatingCommandFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/command/AbstractDelegatingCommandFactory.java
@@ -40,7 +40,7 @@ public abstract class AbstractDelegatingCommandFactory extends AbstractLoggingBe
}
@Override
- public String getName() {
+ public String toString() {
return name;
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/d1c4f608/sshd-core/src/main/java/org/apache/sshd/server/command/CommandFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/command/CommandFactory.java b/sshd-core/src/main/java/org/apache/sshd/server/command/CommandFactory.java
index aff407b..807add1 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/command/CommandFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/command/CommandFactory.java
@@ -18,8 +18,6 @@
*/
package org.apache.sshd.server.command;
-import org.apache.sshd.common.NamedResource;
-
/**
* A factory of commands.
* Commands are executed on the server side when an "exec" channel is
@@ -27,7 +25,8 @@ import org.apache.sshd.common.NamedResource;
*
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
-public interface CommandFactory extends NamedResource {
+@FunctionalInterface
+public interface CommandFactory {
/**
* Create a command with the given name.
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/d1c4f608/sshd-core/src/main/java/org/apache/sshd/server/shell/ProcessShellCommandFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/shell/ProcessShellCommandFactory.java b/sshd-core/src/main/java/org/apache/sshd/server/shell/ProcessShellCommandFactory.java
index af9af82..8c33b6f 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/shell/ProcessShellCommandFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/shell/ProcessShellCommandFactory.java
@@ -38,7 +38,7 @@ public class ProcessShellCommandFactory implements CommandFactory {
}
@Override
- public String getName() {
+ public String toString() {
return FACTORY_NAME;
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/d1c4f608/sshd-core/src/main/java/org/apache/sshd/server/shell/UnknownCommandFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/shell/UnknownCommandFactory.java b/sshd-core/src/main/java/org/apache/sshd/server/shell/UnknownCommandFactory.java
index ea94525..ef71d99 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/shell/UnknownCommandFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/shell/UnknownCommandFactory.java
@@ -35,7 +35,7 @@ public class UnknownCommandFactory implements CommandFactory {
}
@Override
- public String getName() {
+ public String toString() {
return FACTORY_NAME;
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/d1c4f608/sshd-core/src/test/java/org/apache/sshd/client/channel/ChannelExecTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/channel/ChannelExecTest.java b/sshd-core/src/test/java/org/apache/sshd/client/channel/ChannelExecTest.java
index 8a48daf..038ce55 100644
--- a/sshd-core/src/test/java/org/apache/sshd/client/channel/ChannelExecTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/client/channel/ChannelExecTest.java
@@ -26,8 +26,6 @@ import java.util.concurrent.TimeUnit;
import org.apache.sshd.client.SshClient;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.server.SshServer;
-import org.apache.sshd.server.command.Command;
-import org.apache.sshd.server.command.CommandFactory;
import org.apache.sshd.util.test.BaseTestSupport;
import org.apache.sshd.util.test.CommandExecutionHelper;
import org.apache.sshd.util.test.Utils;
@@ -53,23 +51,13 @@ public class ChannelExecTest extends BaseTestSupport {
@BeforeClass
public static void setupClientAndServer() throws Exception {
sshd = Utils.setupTestServer(ChannelExecTest.class);
- sshd.setCommandFactory(new CommandFactory() {
+ sshd.setCommandFactory(command -> new CommandExecutionHelper(command) {
@Override
- public String getName() {
- return ChannelExecTest.class.getSimpleName();
- }
-
- @Override
- public Command createCommand(String command) {
- return new CommandExecutionHelper(command) {
- @Override
- protected boolean handleCommandLine(String command) throws Exception {
- OutputStream stdout = getOutputStream();
- stdout.write(command.getBytes(StandardCharsets.US_ASCII));
- stdout.flush();
- return false;
- }
- };
+ protected boolean handleCommandLine(String command) throws Exception {
+ OutputStream stdout = getOutputStream();
+ stdout.write(command.getBytes(StandardCharsets.US_ASCII));
+ stdout.flush();
+ return false;
}
});
sshd.start();
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/d1c4f608/sshd-core/src/test/java/org/apache/sshd/client/session/ClientSessionTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/session/ClientSessionTest.java b/sshd-core/src/test/java/org/apache/sshd/client/session/ClientSessionTest.java
index 517b07c..03acaa4 100644
--- a/sshd-core/src/test/java/org/apache/sshd/client/session/ClientSessionTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/client/session/ClientSessionTest.java
@@ -27,8 +27,6 @@ import java.util.concurrent.TimeUnit;
import org.apache.sshd.client.SshClient;
import org.apache.sshd.server.SshServer;
-import org.apache.sshd.server.command.Command;
-import org.apache.sshd.server.command.CommandFactory;
import org.apache.sshd.util.test.BaseTestSupport;
import org.apache.sshd.util.test.CommandExecutionHelper;
import org.apache.sshd.util.test.Utils;
@@ -84,28 +82,18 @@ public class ClientSessionTest extends BaseTestSupport {
public void testDefaultExecuteCommandMethod() throws Exception {
final String expectedCommand = getCurrentTestName() + "-CMD";
final String expectedResponse = getCurrentTestName() + "-RSP";
- sshd.setCommandFactory(new CommandFactory() {
- @Override
- public String getName() {
- return getCurrentTestName();
- }
+ sshd.setCommandFactory(command -> new CommandExecutionHelper(command) {
+ private boolean cmdProcessed;
@Override
- public Command createCommand(String command) {
- return new CommandExecutionHelper(command) {
- private boolean cmdProcessed;
-
- @Override
- protected boolean handleCommandLine(String command) throws Exception {
- assertEquals("Mismatched incoming command", expectedCommand, command);
- assertFalse("Duplicated command call", cmdProcessed);
- OutputStream stdout = getOutputStream();
- stdout.write(expectedResponse.getBytes(StandardCharsets.US_ASCII));
- stdout.flush();
- cmdProcessed = true;
- return false;
- }
- };
+ protected boolean handleCommandLine(String command) throws Exception {
+ assertEquals("Mismatched incoming command", expectedCommand, command);
+ assertFalse("Duplicated command call", cmdProcessed);
+ OutputStream stdout = getOutputStream();
+ stdout.write(expectedResponse.getBytes(StandardCharsets.US_ASCII));
+ stdout.flush();
+ cmdProcessed = true;
+ return false;
}
});
@@ -123,28 +111,18 @@ public class ClientSessionTest extends BaseTestSupport {
public void testExceptionThrownIfRemoteStderrWrittenTo() throws Exception {
final String expectedCommand = getCurrentTestName() + "-CMD";
final String expectedErrorMessage = getCurrentTestName() + "-ERR";
- sshd.setCommandFactory(new CommandFactory() {
- @Override
- public String getName() {
- return getCurrentTestName();
- }
+ sshd.setCommandFactory(command -> new CommandExecutionHelper(command) {
+ private boolean cmdProcessed;
@Override
- public Command createCommand(String command) {
- return new CommandExecutionHelper(command) {
- private boolean cmdProcessed;
-
- @Override
- protected boolean handleCommandLine(String command) throws Exception {
- assertEquals("Mismatched incoming command", expectedCommand, command);
- assertFalse("Duplicated command call", cmdProcessed);
- OutputStream stderr = getErrorStream();
- stderr.write(expectedErrorMessage.getBytes(StandardCharsets.US_ASCII));
- stderr.flush();
- cmdProcessed = true;
- return false;
- }
- };
+ protected boolean handleCommandLine(String command) throws Exception {
+ assertEquals("Mismatched incoming command", expectedCommand, command);
+ assertFalse("Duplicated command call", cmdProcessed);
+ OutputStream stderr = getErrorStream();
+ stderr.write(expectedErrorMessage.getBytes(StandardCharsets.US_ASCII));
+ stderr.flush();
+ cmdProcessed = true;
+ return false;
}
});
@@ -176,33 +154,23 @@ public class ClientSessionTest extends BaseTestSupport {
public void testExceptionThrownIfNonZeroExitStatus() throws Exception {
final String expectedCommand = getCurrentTestName() + "-CMD";
final int exepectedErrorCode = 7365;
- sshd.setCommandFactory(new CommandFactory() {
+ sshd.setCommandFactory(command -> new CommandExecutionHelper() {
+ private boolean cmdProcessed;
+
@Override
- public String getName() {
- return getCurrentTestName();
+ public void onExit(int exitValue, String exitMessage) {
+ super.onExit((exitValue == 0) ? exepectedErrorCode : exitValue, exitMessage);
}
@Override
- public Command createCommand(String command) {
- return new CommandExecutionHelper(command) {
- private boolean cmdProcessed;
-
- @Override
- public void onExit(int exitValue, String exitMessage) {
- super.onExit((exitValue == 0) ? exepectedErrorCode : exitValue, exitMessage);
- }
-
- @Override
- protected boolean handleCommandLine(String command) throws Exception {
- assertEquals("Mismatched incoming command", expectedCommand, command);
- assertFalse("Duplicated command call", cmdProcessed);
- OutputStream stdout = getOutputStream();
- stdout.write(command.getBytes(StandardCharsets.US_ASCII));
- stdout.flush();
- cmdProcessed = true;
- return false;
- }
- };
+ protected boolean handleCommandLine(String command) throws Exception {
+ assertEquals("Mismatched incoming command", expectedCommand, command);
+ assertFalse("Duplicated command call", cmdProcessed);
+ OutputStream stdout = getOutputStream();
+ stdout.write(command.getBytes(StandardCharsets.US_ASCII));
+ stdout.flush();
+ cmdProcessed = true;
+ return false;
}
});
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/d1c4f608/sshd-core/src/test/java/org/apache/sshd/server/ServerTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/server/ServerTest.java b/sshd-core/src/test/java/org/apache/sshd/server/ServerTest.java
index d1955ef..6b4f0df 100644
--- a/sshd-core/src/test/java/org/apache/sshd/server/ServerTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/server/ServerTest.java
@@ -65,7 +65,6 @@ import org.apache.sshd.common.session.helpers.AbstractConnectionService;
import org.apache.sshd.common.session.helpers.AbstractSession;
import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.OsUtils;
-import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.deprecated.ClientUserAuthServiceOld;
import org.apache.sshd.server.auth.keyboard.InteractiveChallenge;
import org.apache.sshd.server.auth.keyboard.KeyboardInteractiveAuthenticator;
@@ -73,7 +72,6 @@ import org.apache.sshd.server.auth.keyboard.PromptEntry;
import org.apache.sshd.server.auth.password.RejectAllPasswordAuthenticator;
import org.apache.sshd.server.auth.pubkey.RejectAllPublickeyAuthenticator;
import org.apache.sshd.server.command.Command;
-import org.apache.sshd.server.command.CommandFactory;
import org.apache.sshd.server.session.ServerSession;
import org.apache.sshd.server.session.ServerSessionImpl;
import org.apache.sshd.util.test.BaseTestSupport;
@@ -279,7 +277,7 @@ public class ServerTest extends BaseTestSupport {
public void testServerIdleTimeoutWithForce() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
- sshd.setCommandFactory(new StreamCommand.Factory());
+ sshd.setCommandFactory(StreamCommand::new);
final long idleTimeoutValue = TimeUnit.SECONDS.toMillis(5L);
PropertyResolverUtils.updateProperty(sshd, FactoryManager.IDLE_TIMEOUT, idleTimeoutValue);
@@ -524,50 +522,38 @@ public class ServerTest extends BaseTestSupport {
@Test // see SSHD-645
public void testChannelStateChangeNotifications() throws Exception {
final Semaphore exitSignal = new Semaphore(0);
- sshd.setCommandFactory(new CommandFactory() {
+ sshd.setCommandFactory(command -> new Command() {
+ private ExitCallback cb;
+
@Override
- public String getName() {
- return getCurrentTestName();
+ public void setOutputStream(OutputStream out) {
+ // ignored
}
@Override
- public Command createCommand(String command) {
- ValidateUtils.checkTrue(String.CASE_INSENSITIVE_ORDER.compare(command, getCurrentTestName()) == 0, "Unexpected command: %s", command);
-
- return new Command() {
- private ExitCallback cb;
-
- @Override
- public void setOutputStream(OutputStream out) {
- // ignored
- }
-
- @Override
- public void setInputStream(InputStream in) {
- // ignored
- }
+ public void setInputStream(InputStream in) {
+ // ignored
+ }
- @Override
- public void setExitCallback(ExitCallback callback) {
- cb = callback;
- }
+ @Override
+ public void setExitCallback(ExitCallback callback) {
+ cb = callback;
+ }
- @Override
- public void setErrorStream(OutputStream err) {
- // ignored
- }
+ @Override
+ public void setErrorStream(OutputStream err) {
+ // ignored
+ }
- @Override
- public void destroy() {
- // ignored
- }
+ @Override
+ public void destroy() {
+ // ignored
+ }
- @Override
- public void start(Environment env) throws IOException {
- exitSignal.release();
- cb.onExit(0, command);
- }
- };
+ @Override
+ public void start(Environment env) throws IOException {
+ exitSignal.release();
+ cb.onExit(0, command);
}
});
sshd.start();
@@ -605,53 +591,41 @@ public class ServerTest extends BaseTestSupport {
@Test
public void testEnvironmentVariablesPropagationToServer() throws Exception {
final AtomicReference<Environment> envHolder = new AtomicReference<>(null);
- sshd.setCommandFactory(new CommandFactory() {
+ sshd.setCommandFactory(command -> new Command() {
+ private ExitCallback cb;
+
@Override
- public String getName() {
- return getCurrentTestName();
+ public void setOutputStream(OutputStream out) {
+ // ignored
}
@Override
- public Command createCommand(String command) {
- ValidateUtils.checkTrue(String.CASE_INSENSITIVE_ORDER.compare(command, getCurrentTestName()) == 0, "Unexpected command: %s", command);
-
- return new Command() {
- private ExitCallback cb;
-
- @Override
- public void setOutputStream(OutputStream out) {
- // ignored
- }
-
- @Override
- public void setInputStream(InputStream in) {
- // ignored
- }
+ public void setInputStream(InputStream in) {
+ // ignored
+ }
- @Override
- public void setExitCallback(ExitCallback callback) {
- cb = callback;
- }
+ @Override
+ public void setExitCallback(ExitCallback callback) {
+ cb = callback;
+ }
- @Override
- public void setErrorStream(OutputStream err) {
- // ignored
- }
+ @Override
+ public void setErrorStream(OutputStream err) {
+ // ignored
+ }
- @Override
- public void destroy() {
- // ignored
- }
+ @Override
+ public void destroy() {
+ // ignored
+ }
- @Override
- public void start(Environment env) throws IOException {
- if (envHolder.getAndSet(env) != null) {
- throw new StreamCorruptedException("Multiple starts for command=" + command);
- }
+ @Override
+ public void start(Environment env) throws IOException {
+ if (envHolder.getAndSet(env) != null) {
+ throw new StreamCorruptedException("Multiple starts for command=" + command);
+ }
- cb.onExit(0, command);
- }
- };
+ cb.onExit(0, command);
}
});
@@ -951,22 +925,6 @@ public class ServerTest extends BaseTestSupport {
public static CountDownLatch latch;
// CHECKSTYLE:ON
- public static class Factory implements CommandFactory {
- public Factory() {
- super();
- }
-
- @Override
- public String getName() {
- return getClass().getSimpleName();
- }
-
- @Override
- public Command createCommand(String name) {
- return new StreamCommand(name);
- }
- }
-
private final String name;
private OutputStream out;
[2/3] mina-sshd git commit: Small refactoring of the command
implementations to extract common code
Posted by gn...@apache.org.
Small refactoring of the command implementations to extract common code
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/a04f585d
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/a04f585d
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/a04f585d
Branch: refs/heads/master
Commit: a04f585d390a3b49c1a5ad86f74d132189065dea
Parents: d1c4f60
Author: Guillaume Nodet <gn...@apache.org>
Authored: Mon May 28 09:30:59 2018 +0200
Committer: Guillaume Nodet <gn...@apache.org>
Committed: Mon May 28 10:06:47 2018 +0200
----------------------------------------------------------------------
.../server/command/AbstractCommandSupport.java | 78 ++++++++--
.../AbstractDelegatingCommandFactory.java | 12 +-
.../command/AbstractFileSystemCommand.java | 69 +++++++++
.../command/DelegatingCommandFactory.java | 43 ------
.../sshd/client/session/ClientSessionTest.java | 10 +-
.../org/apache/sshd/git/AbstractGitCommand.java | 54 +------
.../org/apache/sshd/server/scp/ScpCommand.java | 146 ++-----------------
.../org/apache/sshd/client/scp/ScpTest.java | 23 +--
8 files changed, 164 insertions(+), 271 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a04f585d/sshd-core/src/main/java/org/apache/sshd/server/command/AbstractCommandSupport.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/command/AbstractCommandSupport.java b/sshd-core/src/main/java/org/apache/sshd/server/command/AbstractCommandSupport.java
index 58cf034..e797456 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/command/AbstractCommandSupport.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/command/AbstractCommandSupport.java
@@ -26,12 +26,17 @@ import java.util.Collection;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
+import org.apache.sshd.common.session.Session;
+import org.apache.sshd.common.session.SessionHolder;
import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.logging.AbstractLoggingBean;
import org.apache.sshd.common.util.threads.ExecutorServiceCarrier;
import org.apache.sshd.common.util.threads.ThreadUtils;
import org.apache.sshd.server.Environment;
import org.apache.sshd.server.ExitCallback;
+import org.apache.sshd.server.SessionAware;
+import org.apache.sshd.server.session.ServerSession;
+import org.apache.sshd.server.session.ServerSessionHolder;
/**
* Provides a basic useful skeleton for {@link Command} executions
@@ -40,17 +45,20 @@ import org.apache.sshd.server.ExitCallback;
*/
public abstract class AbstractCommandSupport
extends AbstractLoggingBean
- implements Command, Runnable, ExitCallback, ExecutorServiceCarrier {
- private final String command;
- private InputStream in;
- private OutputStream out;
- private OutputStream err;
- private ExitCallback callback;
- private Environment environment;
- private Future<?> cmdFuture;
- private ExecutorService executorService;
- private boolean shutdownOnExit;
- private boolean cbCalled;
+ implements Command, Runnable, ExecutorServiceCarrier, SessionAware,
+ SessionHolder<Session>, ServerSessionHolder {
+ protected final String command;
+ protected InputStream in;
+ protected OutputStream out;
+ protected OutputStream err;
+ protected ExitCallback callback;
+ protected Environment environment;
+ protected Future<?> cmdFuture;
+ protected Thread cmdRunner;
+ protected ExecutorService executorService;
+ protected boolean shutdownOnExit;
+ protected boolean cbCalled;
+ protected ServerSession serverSession;
protected AbstractCommandSupport(String command, ExecutorService executorService, boolean shutdownOnExit) {
this.command = command;
@@ -70,6 +78,21 @@ public abstract class AbstractCommandSupport
}
@Override
+ public Session getSession() {
+ return getServerSession();
+ }
+
+ @Override
+ public ServerSession getServerSession() {
+ return serverSession;
+ }
+
+ @Override
+ public void setSession(ServerSession session) {
+ serverSession = session;
+ }
+
+ @Override
public ExecutorService getExecutorService() {
return executorService;
}
@@ -126,24 +149,47 @@ public abstract class AbstractCommandSupport
@Override
public void start(Environment env) throws IOException {
environment = env;
- ExecutorService executors = getExecutorService();
- cmdFuture = executors.submit(this);
+ try {
+ ExecutorService executors = getExecutorService();
+ cmdFuture = executors.submit(() -> {
+ cmdRunner = Thread.currentThread();
+ this.run();
+ });
+ } catch (RuntimeException e) { // e.g., RejectedExecutionException
+ log.error("Failed (" + e.getClass().getSimpleName() + ") to start command=" + command + ": " + e.getMessage(), e);
+ throw new IOException(e);
+ }
}
@Override
public void destroy() {
+ // if thread has not completed, cancel it
+ boolean debugEnabled = log.isDebugEnabled();
+ if ((cmdFuture != null) && (!cmdFuture.isDone()) && (cmdRunner != Thread.currentThread())) {
+ boolean result = cmdFuture.cancel(true);
+ // TODO consider waiting some reasonable (?) amount of time for cancellation
+ if (debugEnabled) {
+ log.debug("destroy() - cancel pending future=" + result);
+ }
+ }
+
+ cmdFuture = null;
+
ExecutorService executors = getExecutorService();
if ((executors != null) && (!executors.isShutdown()) && isShutdownOnExit()) {
Collection<Runnable> runners = executors.shutdownNow();
- if (log.isDebugEnabled()) {
+ if (debugEnabled) {
log.debug("destroy() - shutdown executor service - runners count=" + runners.size());
}
}
this.executorService = null;
}
- @Override
- public void onExit(int exitValue, String exitMessage) {
+ protected void onExit(int exitValue) {
+ onExit(exitValue, "");
+ }
+
+ protected void onExit(int exitValue, String exitMessage) {
if (cbCalled) {
if (log.isTraceEnabled()) {
log.trace("onExit({}) ignore exitValue={}, message={} - already called",
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a04f585d/sshd-core/src/main/java/org/apache/sshd/server/command/AbstractDelegatingCommandFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/command/AbstractDelegatingCommandFactory.java b/sshd-core/src/main/java/org/apache/sshd/server/command/AbstractDelegatingCommandFactory.java
index e780c52..6005038 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/command/AbstractDelegatingCommandFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/command/AbstractDelegatingCommandFactory.java
@@ -27,7 +27,7 @@ import org.apache.sshd.common.util.logging.AbstractLoggingBean;
*
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
-public abstract class AbstractDelegatingCommandFactory extends AbstractLoggingBean implements DelegatingCommandFactory {
+public abstract class AbstractDelegatingCommandFactory extends AbstractLoggingBean implements CommandFactory {
private final String name;
/*
* NOTE: we expose setters since there is no problem to change these settings between
@@ -44,12 +44,10 @@ public abstract class AbstractDelegatingCommandFactory extends AbstractLoggingBe
return name;
}
- @Override
public CommandFactory getDelegateCommandFactory() {
return delegate;
}
- @Override
public void setDelegateCommandFactory(CommandFactory factory) {
delegate = factory;
}
@@ -68,6 +66,14 @@ public abstract class AbstractDelegatingCommandFactory extends AbstractLoggingBe
return createUnsupportedCommand(command);
}
+ /**
+ * @param command The command about to be executed
+ * @return {@code true} if this command is supported by the command
+ * factory, {@code false} if it will be passed on to the
+ * {@link #getDelegateCommandFactory() delegate} factory
+ */
+ public abstract boolean isSupportedCommand(String command);
+
protected abstract Command executeSupportedCommand(String command);
protected Command createUnsupportedCommand(String command) {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a04f585d/sshd-core/src/main/java/org/apache/sshd/server/command/AbstractFileSystemCommand.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/command/AbstractFileSystemCommand.java b/sshd-core/src/main/java/org/apache/sshd/server/command/AbstractFileSystemCommand.java
new file mode 100644
index 0000000..e4d0f58
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/server/command/AbstractFileSystemCommand.java
@@ -0,0 +1,69 @@
+/*
+ * 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.command;
+
+import java.io.IOException;
+import java.nio.file.FileSystem;
+import java.util.concurrent.ExecutorService;
+
+import org.apache.sshd.common.file.FileSystemAware;
+
+/**
+ * Provides a basic useful skeleton for {@link Command} executions that require file system access
+ *
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public abstract class AbstractFileSystemCommand extends AbstractCommandSupport implements FileSystemAware {
+
+ protected FileSystem fileSystem;
+
+ public AbstractFileSystemCommand(String command, ExecutorService executorService, boolean shutdownOnExit) {
+ super(command, executorService, shutdownOnExit);
+ }
+
+ public FileSystem getFileSystem() {
+ return fileSystem;
+ }
+
+ @Override
+ public void setFileSystem(FileSystem fileSystem) {
+ this.fileSystem = fileSystem;
+ }
+
+ @Override
+ public void destroy() {
+ try {
+ super.destroy();
+ } finally {
+ if (fileSystem != null) {
+ try {
+ fileSystem.close();
+ } catch (UnsupportedOperationException | IOException e) {
+ if (log.isDebugEnabled()) {
+ log.debug("destroy({}) - failed ({}) to close file system={}: {}",
+ this, e.getClass().getSimpleName(), fileSystem, e.getMessage());
+ }
+ } finally {
+ fileSystem = null;
+ }
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a04f585d/sshd-core/src/main/java/org/apache/sshd/server/command/DelegatingCommandFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/command/DelegatingCommandFactory.java b/sshd-core/src/main/java/org/apache/sshd/server/command/DelegatingCommandFactory.java
deleted file mode 100644
index e1ce89c..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/server/command/DelegatingCommandFactory.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.command;
-
-/**
- * Represents a {@link CommandFactory} that filters the commands it recognizes
- * and delegates the ones it doesn't to another delegate factory. The behavior
- * of such a delegating factory is undefined if it receives a command it does
- * not recognize and not delegate has been set. The recommended behavior in this
- * case is to throw some exception - though this is not mandatory
- *
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public interface DelegatingCommandFactory extends CommandFactory {
- CommandFactory getDelegateCommandFactory();
-
- void setDelegateCommandFactory(CommandFactory factory);
-
- /**
- * @param command The command about to be executed
- * @return {@code true} if this command is supported by the command
- * factory, {@code false} if it will be passed on to the
- * {@link #getDelegateCommandFactory() delegate} factory
- */
- boolean isSupportedCommand(String command);
-}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a04f585d/sshd-core/src/test/java/org/apache/sshd/client/session/ClientSessionTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/session/ClientSessionTest.java b/sshd-core/src/test/java/org/apache/sshd/client/session/ClientSessionTest.java
index 03acaa4..87dc5ff 100644
--- a/sshd-core/src/test/java/org/apache/sshd/client/session/ClientSessionTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/client/session/ClientSessionTest.java
@@ -153,13 +153,13 @@ public class ClientSessionTest extends BaseTestSupport {
@Test
public void testExceptionThrownIfNonZeroExitStatus() throws Exception {
final String expectedCommand = getCurrentTestName() + "-CMD";
- final int exepectedErrorCode = 7365;
- sshd.setCommandFactory(command -> new CommandExecutionHelper() {
+ final int expectedErrorCode = 7365;
+ sshd.setCommandFactory(command -> new CommandExecutionHelper(command) {
private boolean cmdProcessed;
@Override
- public void onExit(int exitValue, String exitMessage) {
- super.onExit((exitValue == 0) ? exepectedErrorCode : exitValue, exitMessage);
+ protected void onExit(int exitValue, String exitMessage) {
+ super.onExit((exitValue == 0) ? expectedErrorCode : exitValue, exitMessage);
}
@Override
@@ -195,6 +195,6 @@ public class ClientSessionTest extends BaseTestSupport {
actualErrorMessage = cause.getMessage();
}
- assertEquals("Mismatched captured error code", Integer.toString(exepectedErrorCode), actualErrorMessage);
+ assertEquals("Mismatched captured error code", Integer.toString(expectedErrorCode), actualErrorMessage);
}
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a04f585d/sshd-git/src/main/java/org/apache/sshd/git/AbstractGitCommand.java
----------------------------------------------------------------------
diff --git a/sshd-git/src/main/java/org/apache/sshd/git/AbstractGitCommand.java b/sshd-git/src/main/java/org/apache/sshd/git/AbstractGitCommand.java
index 7315610..1542e75 100644
--- a/sshd-git/src/main/java/org/apache/sshd/git/AbstractGitCommand.java
+++ b/sshd-git/src/main/java/org/apache/sshd/git/AbstractGitCommand.java
@@ -19,7 +19,6 @@
package org.apache.sshd.git;
-import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.FileSystem;
import java.util.ArrayList;
@@ -28,11 +27,7 @@ import java.util.Objects;
import java.util.concurrent.ExecutorService;
import org.apache.sshd.common.channel.ChannelOutputStream;
-import org.apache.sshd.common.file.FileSystemAware;
-import org.apache.sshd.server.SessionAware;
-import org.apache.sshd.server.command.AbstractCommandSupport;
-import org.apache.sshd.server.session.ServerSession;
-import org.apache.sshd.server.session.ServerSessionHolder;
+import org.apache.sshd.server.command.AbstractFileSystemCommand;
/**
* Provides basic support for GIT command implementations
@@ -40,16 +35,15 @@ import org.apache.sshd.server.session.ServerSessionHolder;
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
public abstract class AbstractGitCommand
- extends AbstractCommandSupport
- implements SessionAware, FileSystemAware, ServerSessionHolder, GitLocationResolverCarrier {
+ extends AbstractFileSystemCommand
+ implements GitLocationResolverCarrier {
public static final int CHAR = 0x001;
public static final int DELIMITER = 0x002;
public static final int STARTQUOTE = 0x004;
public static final int ENDQUOTE = 0x008;
- private final GitLocationResolver rootDirResolver;
- private FileSystem fileSystem;
- private ServerSession session;
+ protected final GitLocationResolver rootDirResolver;
+ protected FileSystem fileSystem;
protected AbstractGitCommand(GitLocationResolver rootDirResolver, String command, ExecutorService executorService, boolean shutdownOnExit) {
super(command, executorService, shutdownOnExit);
@@ -61,25 +55,6 @@ public abstract class AbstractGitCommand
return rootDirResolver;
}
- public FileSystem getFileSystem() {
- return fileSystem;
- }
-
- @Override
- public void setFileSystem(FileSystem fileSystem) {
- this.fileSystem = fileSystem;
- }
-
- @Override
- public ServerSession getServerSession() {
- return session;
- }
-
- @Override
- public void setSession(ServerSession session) {
- this.session = session;
- }
-
@Override
public void setOutputStream(OutputStream out) {
super.setOutputStream(out);
@@ -97,25 +72,6 @@ public abstract class AbstractGitCommand
}
@Override
- public void destroy() {
- try {
- super.destroy();
- } finally {
- FileSystem fs = getFileSystem();
- if (fs != null) {
- try {
- fs.close();
- } catch (UnsupportedOperationException | IOException e) {
- if (log.isDebugEnabled()) {
- log.debug("destroy({}) - failed ({}) to close file system={}: {}",
- this, e.getClass().getSimpleName(), fs, e.getMessage());
- }
- }
- }
- }
- }
-
- @Override
public String toString() {
return super.toString() + "[session=" + getServerSession() + "]";
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a04f585d/sshd-scp/src/main/java/org/apache/sshd/server/scp/ScpCommand.java
----------------------------------------------------------------------
diff --git a/sshd-scp/src/main/java/org/apache/sshd/server/scp/ScpCommand.java b/sshd-scp/src/main/java/org/apache/sshd/server/scp/ScpCommand.java
index 7729859..3bb4453 100644
--- a/sshd-scp/src/main/java/org/apache/sshd/server/scp/ScpCommand.java
+++ b/sshd-scp/src/main/java/org/apache/sshd/server/scp/ScpCommand.java
@@ -19,32 +19,19 @@
package org.apache.sshd.server.scp;
import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.file.FileSystem;
-import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
-import org.apache.sshd.common.file.FileSystemAware;
import org.apache.sshd.common.scp.ScpException;
import org.apache.sshd.common.scp.ScpFileOpener;
import org.apache.sshd.common.scp.ScpHelper;
import org.apache.sshd.common.scp.ScpTransferEventListener;
import org.apache.sshd.common.scp.helpers.DefaultScpFileOpener;
-import org.apache.sshd.common.session.Session;
-import org.apache.sshd.common.session.SessionHolder;
import org.apache.sshd.common.util.GenericUtils;
-import org.apache.sshd.common.util.logging.AbstractLoggingBean;
-import org.apache.sshd.common.util.threads.ExecutorServiceCarrier;
import org.apache.sshd.common.util.threads.ThreadUtils;
import org.apache.sshd.server.Environment;
-import org.apache.sshd.server.ExitCallback;
-import org.apache.sshd.server.SessionAware;
-import org.apache.sshd.server.command.Command;
+import org.apache.sshd.server.command.AbstractFileSystemCommand;
import org.apache.sshd.server.session.ServerSession;
-import org.apache.sshd.server.session.ServerSessionHolder;
/**
* This commands provide SCP support on both server and client side.
@@ -54,11 +41,8 @@ import org.apache.sshd.server.session.ServerSessionHolder;
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
public class ScpCommand
- extends AbstractLoggingBean
- implements Command, Runnable, FileSystemAware, SessionAware,
- SessionHolder<Session>, ServerSessionHolder, ExecutorServiceCarrier {
+ extends AbstractFileSystemCommand {
- protected final String name;
protected final int sendBufferSize;
protected final int receiveBufferSize;
protected final ScpFileOpener opener;
@@ -67,19 +51,9 @@ public class ScpCommand
protected boolean optF;
protected boolean optD;
protected boolean optP; // TODO: handle modification times
- protected FileSystem fileSystem;
protected String path;
- protected InputStream in;
- protected OutputStream out;
- protected OutputStream err;
- protected ExitCallback callback;
protected IOException error;
- protected Future<?> pendingFuture;
protected ScpTransferEventListener listener;
- protected ServerSession serverSession;
-
- private ExecutorService executorService;
- private boolean shutdownOnExit;
/**
* @param command The command to be executed
@@ -101,16 +75,7 @@ public class ScpCommand
ExecutorService executorService, boolean shutdownOnExit,
int sendSize, int receiveSize,
ScpFileOpener fileOpener, ScpTransferEventListener eventListener) {
- name = command;
-
- if (executorService == null) {
- String poolName = command.replace(' ', '_').replace('/', ':');
- this.executorService = ThreadUtils.newSingleThreadExecutor(poolName);
- this.shutdownOnExit = true; // we always close the ad-hoc executor service
- } else {
- this.executorService = executorService;
- this.shutdownOnExit = shutdownOnExit;
- }
+ super(command, executorService, shutdownOnExit);
if (sendSize < ScpHelper.MIN_SEND_BUFFER_SIZE) {
throw new IllegalArgumentException("<ScpCommmand>(" + command + ") send buffer size "
@@ -184,100 +149,11 @@ public class ScpCommand
}
@Override
- public ExecutorService getExecutorService() {
- return executorService;
- }
-
- @Override
- public boolean isShutdownOnExit() {
- return shutdownOnExit;
- }
-
- @Override
- public Session getSession() {
- return getServerSession();
- }
-
- @Override
- public ServerSession getServerSession() {
- return serverSession;
- }
-
- @Override
- public void setSession(ServerSession session) {
- serverSession = session;
- }
-
- @Override
- public void setInputStream(InputStream in) {
- this.in = in;
- }
-
- @Override
- public void setOutputStream(OutputStream out) {
- this.out = out;
- }
-
- @Override
- public void setErrorStream(OutputStream err) {
- this.err = err;
- }
-
- @Override
- public void setExitCallback(ExitCallback callback) {
- this.callback = callback;
- }
-
- @Override
- public void setFileSystem(FileSystem fs) {
- this.fileSystem = fs;
- }
-
- @Override
public void start(Environment env) throws IOException {
if (error != null) {
throw error;
}
-
- try {
- ExecutorService executors = getExecutorService();
- pendingFuture = executors.submit(this);
- } catch (RuntimeException e) { // e.g., RejectedExecutionException
- log.error("Failed (" + e.getClass().getSimpleName() + ") to start command=" + name + ": " + e.getMessage(), e);
- throw new IOException(e);
- }
- }
-
- @Override
- public void destroy() {
- // if thread has not completed, cancel it
- boolean debugEnabled = log.isDebugEnabled();
- if ((pendingFuture != null) && (!pendingFuture.isDone())) {
- boolean result = pendingFuture.cancel(true);
- // TODO consider waiting some reasonable (?) amount of time for cancellation
- if (debugEnabled) {
- log.debug("destroy() - cancel pending future=" + result);
- }
- }
-
- pendingFuture = null;
-
- ExecutorService executors = getExecutorService();
- if ((executors != null) && (!executors.isShutdown()) && isShutdownOnExit()) {
- Collection<Runnable> runners = executors.shutdownNow();
- if (debugEnabled) {
- log.debug("destroy() - shutdown executor service - runners count=" + runners.size());
- }
- }
- this.executorService = null;
-
- try {
- fileSystem.close();
- } catch (UnsupportedOperationException e) {
- // Ignore
- } catch (IOException e) {
- log.debug("Error closing FileSystem", e);
- }
+ super.start(env);
}
@Override
@@ -305,28 +181,28 @@ public class ScpCommand
// this is an exception so status cannot be OK/WARNING
if ((exitValue == ScpHelper.OK) || (exitValue == ScpHelper.WARNING)) {
if (debugEnabled) {
- log.debug("run({})[{}] normalize status code={}", session, name, exitValue);
+ log.debug("run({})[{}] normalize status code={}", session, command, exitValue);
}
exitValue = ScpHelper.ERROR;
}
exitMessage = GenericUtils.trimToEmpty(e.getMessage());
- writeCommandResponseMessage(name, exitValue, exitMessage);
+ writeCommandResponseMessage(command, exitValue, exitMessage);
} catch (IOException e2) {
if (debugEnabled) {
log.debug("run({})[{}] Failed ({}) to send error response: {}",
- session, name, e.getClass().getSimpleName(), e.getMessage());
+ session, command, e.getClass().getSimpleName(), e.getMessage());
}
if (log.isTraceEnabled()) {
- log.trace("run(" + session + ")[" + name + "] error response failure details", e2);
+ log.trace("run(" + session + ")[" + command + "] error response failure details", e2);
}
}
if (debugEnabled) {
log.debug("run({})[{}] Failed ({}) to run command: {}",
- session, name, e.getClass().getSimpleName(), e.getMessage());
+ session, command, e.getClass().getSimpleName(), e.getMessage());
}
if (log.isTraceEnabled()) {
- log.trace("run(" + session + ")[" + name + "] command execution failure details", e);
+ log.trace("run(" + session + ")[" + command + "] command execution failure details", e);
}
} finally {
if (callback != null) {
@@ -345,6 +221,6 @@ public class ScpCommand
@Override
public String toString() {
- return getClass().getSimpleName() + "(" + getSession() + ") " + name;
+ return getClass().getSimpleName() + "(" + getSession() + ") " + command;
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a04f585d/sshd-scp/src/test/java/org/apache/sshd/client/scp/ScpTest.java
----------------------------------------------------------------------
diff --git a/sshd-scp/src/test/java/org/apache/sshd/client/scp/ScpTest.java b/sshd-scp/src/test/java/org/apache/sshd/client/scp/ScpTest.java
index 9db3587..3cc15b7 100644
--- a/sshd-scp/src/test/java/org/apache/sshd/client/scp/ScpTest.java
+++ b/sshd-scp/src/test/java/org/apache/sshd/client/scp/ScpTest.java
@@ -60,7 +60,6 @@ import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.OsUtils;
import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.io.IoUtils;
-import org.apache.sshd.server.ExitCallback;
import org.apache.sshd.server.SshServer;
import org.apache.sshd.server.command.Command;
import org.apache.sshd.server.scp.ScpCommand;
@@ -767,8 +766,7 @@ public class ScpTest extends BaseTestSupport {
@Test // see SSHD-628
public void testScpExitStatusPropagation() throws Exception {
final int testExitValue = 7365;
- class InternalScpCommand extends ScpCommand implements ExitCallback {
- private ExitCallback delegate;
+ class InternalScpCommand extends ScpCommand {
InternalScpCommand(String command, ExecutorService executorService, boolean shutdownOnExit,
int sendSize, int receiveSize, ScpFileOpener opener, ScpTransferEventListener eventListener) {
@@ -782,24 +780,9 @@ public class ScpTest extends BaseTestSupport {
}
@Override
- public void setExitCallback(ExitCallback callback) {
- delegate = callback;
- super.setExitCallback(this);
- }
-
- @Override
- public void onExit(int exitValue) {
- onExit(exitValue, Integer.toString(exitValue));
- }
-
- @Override
- public void onExit(int exitValue, String exitMessage) {
+ protected void onExit(int exitValue, String exitMessage) {
outputDebugMessage("onExit(%s) status=%d", this, exitValue);
- if (exitValue == ScpHelper.OK) {
- delegate.onExit(testExitValue, exitMessage);
- } else {
- delegate.onExit(exitValue, exitMessage);
- }
+ super.onExit((exitValue == ScpHelper.OK) ? testExitValue : exitValue, exitMessage);
}
}
[3/3] mina-sshd git commit: [SSHD-449] SSH Exec channel with
ClientChannel.Streaming.Async
Posted by gn...@apache.org.
[SSHD-449] SSH Exec channel with ClientChannel.Streaming.Async
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/a4f4e281
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/a4f4e281
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/a4f4e281
Branch: refs/heads/master
Commit: a4f4e28112e83d2430f4431e9e07ebba07ddc484
Parents: a04f585
Author: Guillaume Nodet <gn...@apache.org>
Authored: Mon May 28 10:38:10 2018 +0200
Committer: Guillaume Nodet <gn...@apache.org>
Committed: Mon May 28 11:37:48 2018 +0200
----------------------------------------------------------------------
.../common/channel/ChannelAsyncInputStream.java | 13 +++-
.../java/org/apache/sshd/client/ClientTest.java | 63 ++++++++++++++++++++
2 files changed, 75 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a4f4e281/sshd-core/src/main/java/org/apache/sshd/common/channel/ChannelAsyncInputStream.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/channel/ChannelAsyncInputStream.java b/sshd-core/src/main/java/org/apache/sshd/common/channel/ChannelAsyncInputStream.java
index e699540..e0c6c26 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/channel/ChannelAsyncInputStream.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/channel/ChannelAsyncInputStream.java
@@ -64,7 +64,18 @@ public class ChannelAsyncInputStream extends AbstractCloseable implements IoInpu
public IoReadFuture read(Buffer buf) {
IoReadFutureImpl future = new IoReadFutureImpl(readFutureId, buf);
if (isClosing()) {
- future.setValue(new IOException("Closed"));
+ synchronized (buffer) {
+ if (pending != null) {
+ throw new ReadPendingException("Previous pending read not handled");
+ }
+ if (buffer.available() > 0) {
+ int nbRead = future.buffer.putBuffer(buffer, false);
+ buffer.compact();
+ future.setValue(nbRead);
+ } else {
+ future.setValue(new IOException("Closed"));
+ }
+ }
} else {
synchronized (buffer) {
if (pending != null) {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a4f4e281/sshd-core/src/test/java/org/apache/sshd/client/ClientTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/ClientTest.java b/sshd-core/src/test/java/org/apache/sshd/client/ClientTest.java
index 0026cc3..43d6d33 100644
--- a/sshd-core/src/test/java/org/apache/sshd/client/ClientTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/client/ClientTest.java
@@ -588,6 +588,69 @@ public class ClientTest extends BaseTestSupport {
}
@Test
+ public void testExecAsyncClient() throws Exception {
+ Logger log = LoggerFactory.getLogger(getClass());
+ client.start();
+ try (ClientSession session = createTestClientSession()) {
+ final ByteArrayOutputStream baosOut = new ByteArrayOutputStream();
+ final ByteArrayOutputStream baosErr = new ByteArrayOutputStream();
+
+ final ChannelExec channel = session.createExecChannel("test");
+ channel.setStreaming(ClientChannel.Streaming.Async);
+ OpenFuture open = channel.open();
+
+ Thread.sleep(100); // Removing this line will make the test succeed
+ open.addListener(new SshFutureListener<OpenFuture>() {
+ @Override
+ public void operationComplete(OpenFuture future) {
+ channel.getAsyncOut().read(new ByteArrayBuffer())
+ .addListener(new SshFutureListener<IoReadFuture>() {
+ @Override
+ public void operationComplete(IoReadFuture future) {
+ try {
+ future.verify();
+ Buffer buffer = future.getBuffer();
+ baosOut.write(buffer.array(), buffer.rpos(), buffer.available());
+ buffer.rpos(buffer.rpos() + buffer.available());
+ buffer.compact();
+ channel.getAsyncOut().read(buffer).addListener(this);
+ } catch (IOException e) {
+ if (!channel.isClosing()) {
+ log.error("Error reading", e);
+ channel.close(true);
+ }
+ }
+ }
+ });
+ channel.getAsyncErr().read(new ByteArrayBuffer())
+ .addListener(new SshFutureListener<IoReadFuture>() {
+ @Override
+ public void operationComplete(IoReadFuture future) {
+ try {
+ future.verify();
+ Buffer buffer = future.getBuffer();
+ baosErr.write(buffer.array(), buffer.rpos(), buffer.available());
+ buffer.rpos(buffer.rpos() + buffer.available());
+ buffer.compact();
+ channel.getAsyncErr().read(buffer).addListener(this);
+ } catch (IOException e) {
+ if (!channel.isClosing()) {
+ log.error("Error reading", e);
+ channel.close(true);
+ }
+ }
+ }
+ });
+ }
+ });
+
+ channel.waitFor(EnumSet.of(ClientChannelEvent.CLOSED), 0);
+
+ assertNotEquals(0, baosErr.size());
+ }
+ }
+
+ @Test
public void testCommandDeadlock() throws Exception {
client.start();