You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by lg...@apache.org on 2018/05/15 07:48:13 UTC
[2/2] mina-sshd git commit: [SSHD-819] Standardized the
DelegateCommandFactory behavior
[SSHD-819] Standardized the DelegateCommandFactory behavior
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/f1a8077b
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/f1a8077b
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/f1a8077b
Branch: refs/heads/master
Commit: f1a8077be3875184b067095b236793e4801c2ad5
Parents: 3182ad8
Author: Goldstein Lyor <ly...@c-b4.com>
Authored: Tue May 15 10:41:24 2018 +0300
Committer: Goldstein Lyor <ly...@c-b4.com>
Committed: Tue May 15 10:48:02 2018 +0300
----------------------------------------------------------------------
.../sshd/cli/server/SshServerCliSupport.java | 2 +-
.../apache/sshd/cli/server/SshServerMain.java | 6 +-
.../apache/sshd/cli/server/SshFsMounter.java | 9 +-
.../sshd/server/AbstractCommandSupport.java | 168 ------------------
.../org/apache/sshd/server/AsyncCommand.java | 52 ------
.../apache/sshd/server/ChannelSessionAware.java | 1 +
.../java/org/apache/sshd/server/Command.java | 65 -------
.../org/apache/sshd/server/CommandFactory.java | 40 -----
.../apache/sshd/server/CommandLifecycle.java | 48 ------
.../sshd/server/ServerFactoryManager.java | 2 +
.../java/org/apache/sshd/server/SshServer.java | 2 +
.../server/channel/ChannelDataReceiver.java | 4 +-
.../sshd/server/channel/ChannelSession.java | 8 +-
.../server/command/AbstractCommandSupport.java | 170 +++++++++++++++++++
.../AbstractDelegatingCommandFactory.java | 76 +++++++++
.../sshd/server/command/AsyncCommand.java | 52 ++++++
.../org/apache/sshd/server/command/Command.java | 67 ++++++++
.../sshd/server/command/CommandFactory.java | 41 +++++
.../sshd/server/command/CommandLifecycle.java | 50 ++++++
.../command/DelegatingCommandFactory.java | 43 +++++
.../apache/sshd/server/shell/InvertedShell.java | 2 +-
.../sshd/server/shell/InvertedShellWrapper.java | 2 +-
.../shell/ProcessShellCommandFactory.java | 50 ++++++
.../sshd/server/shell/ProcessShellFactory.java | 2 +-
.../apache/sshd/server/shell/ShellFactory.java | 2 +-
.../sshd/server/shell/UnknownCommand.java | 2 +-
.../server/shell/UnknownCommandFactory.java | 11 +-
.../sshd/server/subsystem/SubsystemFactory.java | 2 +-
.../java/org/apache/sshd/KeepAliveTest.java | 2 +-
.../java/org/apache/sshd/KeyReExchangeTest.java | 2 +-
.../java/org/apache/sshd/WindowAdjustTest.java | 2 +-
.../java/org/apache/sshd/agent/AgentTest.java | 2 +-
.../java/org/apache/sshd/client/ClientTest.java | 2 +-
.../sshd/client/channel/ChannelExecTest.java | 24 ++-
.../sshd/client/session/ClientSessionTest.java | 69 +++++---
.../apache/sshd/common/channel/WindowTest.java | 2 +-
.../java/org/apache/sshd/server/ServerTest.java | 149 +++++++++-------
.../sshd/util/test/AsyncEchoShellFactory.java | 4 +-
.../sshd/util/test/CommandExecutionHelper.java | 2 +-
.../apache/sshd/util/test/EchoShellFactory.java | 2 +-
.../org/apache/sshd/git/AbstractGitCommand.java | 2 +-
.../sshd/git/AbstractGitCommandFactory.java | 47 ++---
.../sshd/git/pack/GitPackCommandFactory.java | 7 +-
.../sshd/git/pgm/GitPgmCommandFactory.java | 7 +-
.../org/apache/sshd/server/scp/ScpCommand.java | 2 +-
.../sshd/server/scp/ScpCommandFactory.java | 63 +++----
.../org/apache/sshd/client/scp/ScpTest.java | 2 +-
.../sshd/server/scp/ScpCommandFactoryTest.java | 2 +-
.../server/subsystem/sftp/SftpSubsystem.java | 4 +-
.../subsystem/sftp/SftpSubsystemFactory.java | 2 +-
.../sshd/client/subsystem/sftp/ClientTest.java | 2 +-
.../sshd/client/subsystem/sftp/SftpTest.java | 2 +-
.../client/subsystem/sftp/SftpVersionsTest.java | 2 +-
.../SpaceAvailableExtensionImplTest.java | 2 +-
.../openssh/helpers/OpenSSHExtensionsTest.java | 2 +-
55 files changed, 815 insertions(+), 574 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerCliSupport.java
----------------------------------------------------------------------
diff --git a/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerCliSupport.java b/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerCliSupport.java
index 910566f..8b392bc 100644
--- a/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerCliSupport.java
+++ b/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerCliSupport.java
@@ -49,10 +49,10 @@ import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.security.SecurityUtils;
import org.apache.sshd.common.util.threads.ThreadUtils;
-import org.apache.sshd.server.Command;
import org.apache.sshd.server.ServerAuthenticationManager;
import org.apache.sshd.server.ServerFactoryManager;
import org.apache.sshd.server.SshServer;
+import org.apache.sshd.server.command.Command;
import org.apache.sshd.server.config.SshServerConfigFileReader;
import org.apache.sshd.server.forward.ForwardingFilter;
import org.apache.sshd.server.keyprovider.AbstractGeneratorHostKeyProvider;
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerMain.java
----------------------------------------------------------------------
diff --git a/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerMain.java b/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerMain.java
index cba6fc2..b9f6d1e 100644
--- a/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerMain.java
+++ b/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerMain.java
@@ -33,13 +33,13 @@ import org.apache.sshd.common.PropertyResolverUtils;
import org.apache.sshd.common.config.SshConfigFileReader;
import org.apache.sshd.common.keyprovider.KeyPairProvider;
import org.apache.sshd.common.util.GenericUtils;
-import org.apache.sshd.server.Command;
import org.apache.sshd.server.SshServer;
import org.apache.sshd.server.auth.pubkey.AcceptAllPublickeyAuthenticator;
+import org.apache.sshd.server.command.Command;
import org.apache.sshd.server.config.keys.ServerIdentity;
import org.apache.sshd.server.keyprovider.AbstractGeneratorHostKeyProvider;
import org.apache.sshd.server.scp.ScpCommandFactory;
-import org.apache.sshd.server.shell.ProcessShellFactory;
+import org.apache.sshd.server.shell.ProcessShellCommandFactory;
import org.apache.sshd.server.shell.ShellFactory;
/**
@@ -181,7 +181,7 @@ public class SshServerMain extends SshServerCliSupport {
sshd.setPublickeyAuthenticator(AcceptAllPublickeyAuthenticator.INSTANCE);
setupServerForwarding(sshd, resolver);
sshd.setCommandFactory(new ScpCommandFactory.Builder()
- .withDelegate(command -> new ProcessShellFactory(GenericUtils.split(command, ' ')).create())
+ .withDelegate(ProcessShellCommandFactory.INSTANCE)
.build());
List<NamedFactory<Command>> subsystems = resolveServerSubsystems(System.err, resolver);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/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 74a5a83..c270be7 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
@@ -43,13 +43,13 @@ import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.logging.AbstractLoggingBean;
import org.apache.sshd.common.util.security.SecurityUtils;
import org.apache.sshd.common.util.threads.ThreadUtils;
-import org.apache.sshd.server.Command;
-import org.apache.sshd.server.CommandFactory;
import org.apache.sshd.server.Environment;
import org.apache.sshd.server.ExitCallback;
import org.apache.sshd.server.SessionAware;
import org.apache.sshd.server.SshServer;
import org.apache.sshd.server.auth.password.AcceptAllPasswordAuthenticator;
+import org.apache.sshd.server.command.Command;
+import org.apache.sshd.server.command.CommandFactory;
import org.apache.sshd.server.forward.AcceptAllForwardingFilter;
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
import org.apache.sshd.server.scp.ScpCommandFactory;
@@ -232,6 +232,11 @@ public final class SshFsMounter extends SshServerCliSupport {
}
@Override
+ public String getName() {
+ return "mounter";
+ }
+
+ @Override
public Command createCommand(String command) {
return new MounterCommand(command);
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/AbstractCommandSupport.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/AbstractCommandSupport.java b/sshd-core/src/main/java/org/apache/sshd/server/AbstractCommandSupport.java
deleted file mode 100644
index 7533157..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/server/AbstractCommandSupport.java
+++ /dev/null
@@ -1,168 +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;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Collection;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
-
-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;
-
-/**
- * Provides a basic useful skeleton for {@link Command} executions
- *
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-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;
-
- protected AbstractCommandSupport(String command, ExecutorService executorService, boolean shutdownOnExit) {
- this.command = command;
-
- if (executorService == null) {
- String poolName = GenericUtils.isEmpty(command) ? getClass().getSimpleName() : 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;
- }
- }
-
- public String getCommand() {
- return command;
- }
-
- @Override
- public ExecutorService getExecutorService() {
- return executorService;
- }
-
- @Override
- public boolean isShutdownOnExit() {
- return shutdownOnExit;
- }
-
- public InputStream getInputStream() {
- return in;
- }
-
- @Override
- public void setInputStream(InputStream in) {
- this.in = in;
- }
-
- public OutputStream getOutputStream() {
- return out;
- }
-
- @Override
- public void setOutputStream(OutputStream out) {
- this.out = out;
- }
-
- public OutputStream getErrorStream() {
- return err;
- }
-
- @Override
- public void setErrorStream(OutputStream err) {
- this.err = err;
- }
-
- public ExitCallback getExitCallback() {
- return callback;
- }
-
- @Override
- public void setExitCallback(ExitCallback callback) {
- this.callback = callback;
- }
-
- public Environment getEnvironment() {
- return environment;
- }
-
- protected Future<?> getStartedCommandFuture() {
- return cmdFuture;
- }
-
- @Override
- public void start(Environment env) throws IOException {
- environment = env;
- ExecutorService executors = getExecutorService();
- cmdFuture = executors.submit(this);
- }
-
- @Override
- public void destroy() {
- ExecutorService executors = getExecutorService();
- if ((executors != null) && (!executors.isShutdown()) && isShutdownOnExit()) {
- Collection<Runnable> runners = executors.shutdownNow();
- if (log.isDebugEnabled()) {
- log.debug("destroy() - shutdown executor service - runners count=" + runners.size());
- }
- }
- this.executorService = null;
- }
-
- @Override
- public void onExit(int exitValue, String exitMessage) {
- if (cbCalled) {
- if (log.isTraceEnabled()) {
- log.trace("onExit({}) ignore exitValue={}, message={} - already called",
- this, exitValue, exitMessage);
- }
- return;
- }
-
- ExitCallback cb = getExitCallback();
- try {
- if (log.isDebugEnabled()) {
- log.debug("onExit({}) exiting - value={}, message={}", this, exitValue, exitMessage);
- }
- cb.onExit(exitValue, exitMessage);
- } finally {
- cbCalled = true;
- }
- }
-
- @Override
- public String toString() {
- return getClass().getSimpleName() + "[" + getCommand() + "]";
- }
-}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/AsyncCommand.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/AsyncCommand.java b/sshd-core/src/main/java/org/apache/sshd/server/AsyncCommand.java
deleted file mode 100644
index b49af64..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/server/AsyncCommand.java
+++ /dev/null
@@ -1,52 +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;
-
-import org.apache.sshd.common.io.IoInputStream;
-import org.apache.sshd.common.io.IoOutputStream;
-
-/**
- * Represents a command capable of doing non-blocking io.
- * If this interface is implemented by a command, the usual
- * blocking input / output / error streams won't be set.
- */
-public interface AsyncCommand extends Command {
-
- /**
- * Set the input stream that can be used by the shell to read input.
- *
- * @param in The {@link IoInputStream} used by the shell to read input
- */
- void setIoInputStream(IoInputStream in);
-
- /**
- * Set the output stream that can be used by the shell to write its output.
- *
- * @param out The {@link IoOutputStream} used by the shell to write its output
- */
- void setIoOutputStream(IoOutputStream out);
-
- /**
- * Set the error stream that can be used by the shell to write its errors.
- *
- * @param err The {@link IoOutputStream} used by the shell to write its errors
- */
- void setIoErrorStream(IoOutputStream err);
-
-}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/ChannelSessionAware.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/ChannelSessionAware.java b/sshd-core/src/main/java/org/apache/sshd/server/ChannelSessionAware.java
index 150e719..d6d7c8b 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/ChannelSessionAware.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/ChannelSessionAware.java
@@ -19,6 +19,7 @@
package org.apache.sshd.server;
import org.apache.sshd.server.channel.ChannelSession;
+import org.apache.sshd.server.command.Command;
/**
* {@link Command} can implement this optional interface
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/Command.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/Command.java b/sshd-core/src/main/java/org/apache/sshd/server/Command.java
deleted file mode 100644
index 4043e48..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/server/Command.java
+++ /dev/null
@@ -1,65 +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;
-
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/**
- * <p>
- * Represents a command, shell or subsystem that can be used to send command.
- * </p>
- *
- * <p>
- * This command have direct streams, meaning those streams will be provided by the ssh server
- * for the shell to use directly. This interface is suitable for implementing commands in java,
- * rather than using external processes. For wrapping such processes or using inverted streams,
- * </p>
- * see {@link org.apache.sshd.server.shell.InvertedShellWrapper}.
- */
-public interface Command extends CommandLifecycle {
-
- /**
- * Set the input stream that can be used by the shell to read input.
- *
- * @param in The {@link InputStream} used by the shell to read input.
- */
- void setInputStream(InputStream in);
-
- /**
- * Set the output stream that can be used by the shell to write its output.
- *
- * @param out The {@link OutputStream} used by the shell to write its output
- */
- void setOutputStream(OutputStream out);
-
- /**
- * Set the error stream that can be used by the shell to write its errors.
- *
- * @param err The {@link OutputStream} used by the shell to write its errors
- */
- void setErrorStream(OutputStream err);
-
- /**
- * Set the callback that the shell has to call when it is closed.
- *
- * @param callback The {@link ExitCallback} to call when shell is closed
- */
- void setExitCallback(ExitCallback callback);
-}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/CommandFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/CommandFactory.java b/sshd-core/src/main/java/org/apache/sshd/server/CommandFactory.java
deleted file mode 100644
index 650abe1..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/server/CommandFactory.java
+++ /dev/null
@@ -1,40 +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;
-
-/**
- * A factory of commands.
- * Commands are executed on the server side when an "exec" channel is
- * requested by the SSH client.
- *
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-@FunctionalInterface
-public interface CommandFactory {
-
- /**
- * Create a command with the given name.
- * If the command is not known, a dummy command should be returned to allow
- * the display output to be sent back to the client.
- *
- * @param command The command that will be run
- * @return a non {@code null} {@link Command} instance
- */
- Command createCommand(String command);
-}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/CommandLifecycle.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/CommandLifecycle.java b/sshd-core/src/main/java/org/apache/sshd/server/CommandLifecycle.java
deleted file mode 100644
index cbe3cf0..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/server/CommandLifecycle.java
+++ /dev/null
@@ -1,48 +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;
-
-import java.io.IOException;
-
-/**
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public interface CommandLifecycle {
- /**
- * Starts the command execution. All streams must have been set <U>before</U>
- * calling this method. The command should implement {@link java.lang.Runnable},
- * and this method should spawn a new thread like:
- * <pre>
- * {@code Thread(this).start(); }
- * </pre>
- *
- * @param env The {@link Environment}
- * @throws IOException If failed to start
- */
- void start(Environment env) throws IOException;
-
- /**
- * This method is called by the SSH server to destroy the command because
- * the client has disconnected somehow.
- *
- * @throws Exception if failed to destroy
- */
- void destroy() throws Exception;
-}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/ServerFactoryManager.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/ServerFactoryManager.java b/sshd-core/src/main/java/org/apache/sshd/server/ServerFactoryManager.java
index 68531ed..60bd655 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/ServerFactoryManager.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/ServerFactoryManager.java
@@ -24,6 +24,8 @@ import java.util.concurrent.TimeUnit;
import org.apache.sshd.common.Factory;
import org.apache.sshd.common.FactoryManager;
import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.server.command.Command;
+import org.apache.sshd.server.command.CommandFactory;
import org.apache.sshd.server.session.ServerProxyAcceptorHolder;
/**
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java b/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
index f93c5d0..35b72cc 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
@@ -49,6 +49,8 @@ import org.apache.sshd.server.auth.hostbased.HostBasedAuthenticator;
import org.apache.sshd.server.auth.keyboard.KeyboardInteractiveAuthenticator;
import org.apache.sshd.server.auth.password.PasswordAuthenticator;
import org.apache.sshd.server.auth.pubkey.PublickeyAuthenticator;
+import org.apache.sshd.server.command.Command;
+import org.apache.sshd.server.command.CommandFactory;
import org.apache.sshd.server.session.ServerConnectionServiceFactory;
import org.apache.sshd.server.session.ServerProxyAcceptor;
import org.apache.sshd.server.session.ServerUserAuthServiceFactory;
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelDataReceiver.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelDataReceiver.java b/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelDataReceiver.java
index f336c89..59ade13 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelDataReceiver.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelDataReceiver.java
@@ -30,10 +30,10 @@ import java.io.IOException;
* Sequence of bytes that SSH client sends to the server is eventually sent to this interface
* to be passed on to the final consumer.
* By default {@link ChannelSession} spools this in a buffer so that you can read it from
- * the input stream you get from {@link org.apache.sshd.server.Command#setInputStream(java.io.InputStream)}, but if command
+ * the input stream you get from {@link org.apache.sshd.server.command.Command#setInputStream(java.io.InputStream)}, but if command
* wants to do a callback-driven I/O for the data it receives from the client, it can
* call {@link ChannelSession#setDataReceiver(ChannelDataReceiver)} to do so.
- * (And to grab a reference to {@link ChannelSession}, a {@link org.apache.sshd.server.Command} should implement
+ * (And to grab a reference to {@link ChannelSession}, a {@link org.apache.sshd.server.command.Command} should implement
* {@link org.apache.sshd.server.ChannelSessionAware}.)
* </p>
*
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java b/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
index b884d80..cfaa499 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
@@ -62,15 +62,15 @@ import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
import org.apache.sshd.common.util.closeable.IoBaseCloseable;
import org.apache.sshd.common.util.io.IoUtils;
import org.apache.sshd.common.util.io.LoggingFilterOutputStream;
-import org.apache.sshd.server.AsyncCommand;
import org.apache.sshd.server.ChannelSessionAware;
-import org.apache.sshd.server.Command;
-import org.apache.sshd.server.CommandFactory;
import org.apache.sshd.server.Environment;
import org.apache.sshd.server.ServerFactoryManager;
import org.apache.sshd.server.SessionAware;
import org.apache.sshd.server.Signal;
import org.apache.sshd.server.StandardEnvironment;
+import org.apache.sshd.server.command.AsyncCommand;
+import org.apache.sshd.server.command.Command;
+import org.apache.sshd.server.command.CommandFactory;
import org.apache.sshd.server.forward.AgentForwardingFilter;
import org.apache.sshd.server.forward.X11ForwardingFilter;
import org.apache.sshd.server.session.ServerSession;
@@ -602,7 +602,7 @@ public class ChannelSession extends AbstractServerChannel {
/**
* For {@link Command} to install {@link ChannelDataReceiver}.
* When you do this, {@link Command#setInputStream(java.io.InputStream)} or
- * {@link org.apache.sshd.server.AsyncCommand#setIoInputStream(org.apache.sshd.common.io.IoInputStream)}
+ * {@link org.apache.sshd.server.command.AsyncCommand#setIoInputStream(org.apache.sshd.common.io.IoInputStream)}
* will no longer be invoked. If you call this method from {@link Command#start(Environment)},
* the input stream you received in {@link Command#setInputStream(java.io.InputStream)} will
* not read any data.
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/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
new file mode 100644
index 0000000..58cf034
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/server/command/AbstractCommandSupport.java
@@ -0,0 +1,170 @@
+/*
+ * 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.io.InputStream;
+import java.io.OutputStream;
+import java.util.Collection;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+
+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;
+
+/**
+ * Provides a basic useful skeleton for {@link Command} executions
+ *
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+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;
+
+ protected AbstractCommandSupport(String command, ExecutorService executorService, boolean shutdownOnExit) {
+ this.command = command;
+
+ if (executorService == null) {
+ String poolName = GenericUtils.isEmpty(command) ? getClass().getSimpleName() : 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;
+ }
+ }
+
+ public String getCommand() {
+ return command;
+ }
+
+ @Override
+ public ExecutorService getExecutorService() {
+ return executorService;
+ }
+
+ @Override
+ public boolean isShutdownOnExit() {
+ return shutdownOnExit;
+ }
+
+ public InputStream getInputStream() {
+ return in;
+ }
+
+ @Override
+ public void setInputStream(InputStream in) {
+ this.in = in;
+ }
+
+ public OutputStream getOutputStream() {
+ return out;
+ }
+
+ @Override
+ public void setOutputStream(OutputStream out) {
+ this.out = out;
+ }
+
+ public OutputStream getErrorStream() {
+ return err;
+ }
+
+ @Override
+ public void setErrorStream(OutputStream err) {
+ this.err = err;
+ }
+
+ public ExitCallback getExitCallback() {
+ return callback;
+ }
+
+ @Override
+ public void setExitCallback(ExitCallback callback) {
+ this.callback = callback;
+ }
+
+ public Environment getEnvironment() {
+ return environment;
+ }
+
+ protected Future<?> getStartedCommandFuture() {
+ return cmdFuture;
+ }
+
+ @Override
+ public void start(Environment env) throws IOException {
+ environment = env;
+ ExecutorService executors = getExecutorService();
+ cmdFuture = executors.submit(this);
+ }
+
+ @Override
+ public void destroy() {
+ ExecutorService executors = getExecutorService();
+ if ((executors != null) && (!executors.isShutdown()) && isShutdownOnExit()) {
+ Collection<Runnable> runners = executors.shutdownNow();
+ if (log.isDebugEnabled()) {
+ log.debug("destroy() - shutdown executor service - runners count=" + runners.size());
+ }
+ }
+ this.executorService = null;
+ }
+
+ @Override
+ public void onExit(int exitValue, String exitMessage) {
+ if (cbCalled) {
+ if (log.isTraceEnabled()) {
+ log.trace("onExit({}) ignore exitValue={}, message={} - already called",
+ this, exitValue, exitMessage);
+ }
+ return;
+ }
+
+ ExitCallback cb = getExitCallback();
+ try {
+ if (log.isDebugEnabled()) {
+ log.debug("onExit({}) exiting - value={}, message={}", this, exitValue, exitMessage);
+ }
+ cb.onExit(exitValue, exitMessage);
+ } finally {
+ cbCalled = true;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + "[" + getCommand() + "]";
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/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
new file mode 100644
index 0000000..3169958
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/server/command/AbstractDelegatingCommandFactory.java
@@ -0,0 +1,76 @@
+/*
+ * 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 org.apache.sshd.common.util.ValidateUtils;
+import org.apache.sshd.common.util.logging.AbstractLoggingBean;
+
+/**
+ * TODO Add javadoc
+ *
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public abstract class AbstractDelegatingCommandFactory extends AbstractLoggingBean implements DelegatingCommandFactory {
+ private final String name;
+ /*
+ * NOTE: we expose setters since there is no problem to change these settings between
+ * successive invocations of the 'createCommand' method
+ */
+ private CommandFactory delegate;
+
+ protected AbstractDelegatingCommandFactory(String name) {
+ this.name = ValidateUtils.checkNotNullAndNotEmpty(name, "No delegating command factory name provided");
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public CommandFactory getDelegateCommandFactory() {
+ return delegate;
+ }
+
+ @Override
+ public void setDelegateCommandFactory(CommandFactory factory) {
+ delegate = factory;
+ }
+
+ @Override
+ public Command createCommand(String command) {
+ if (isSupportedCommand(command)) {
+ return executeSupportedCommand(command);
+ }
+
+ CommandFactory factory = getDelegateCommandFactory();
+ if (factory != null) {
+ return factory.createCommand(command);
+ }
+
+ return createUnsupportedCommand(command);
+ }
+
+ protected abstract Command executeSupportedCommand(String command);
+
+ protected Command createUnsupportedCommand(String command) {
+ throw new IllegalArgumentException("Unknown command to execute: " + command);
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/command/AsyncCommand.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/command/AsyncCommand.java b/sshd-core/src/main/java/org/apache/sshd/server/command/AsyncCommand.java
new file mode 100644
index 0000000..f3d2173
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/server/command/AsyncCommand.java
@@ -0,0 +1,52 @@
+/*
+ * 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 org.apache.sshd.common.io.IoInputStream;
+import org.apache.sshd.common.io.IoOutputStream;
+
+/**
+ * Represents a command capable of doing non-blocking io.
+ * If this interface is implemented by a command, the usual
+ * blocking input / output / error streams won't be set.
+ */
+public interface AsyncCommand extends Command {
+
+ /**
+ * Set the input stream that can be used by the shell to read input.
+ *
+ * @param in The {@link IoInputStream} used by the shell to read input
+ */
+ void setIoInputStream(IoInputStream in);
+
+ /**
+ * Set the output stream that can be used by the shell to write its output.
+ *
+ * @param out The {@link IoOutputStream} used by the shell to write its output
+ */
+ void setIoOutputStream(IoOutputStream out);
+
+ /**
+ * Set the error stream that can be used by the shell to write its errors.
+ *
+ * @param err The {@link IoOutputStream} used by the shell to write its errors
+ */
+ void setIoErrorStream(IoOutputStream err);
+
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/command/Command.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/command/Command.java b/sshd-core/src/main/java/org/apache/sshd/server/command/Command.java
new file mode 100644
index 0000000..5425d3a
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/server/command/Command.java
@@ -0,0 +1,67 @@
+/*
+ * 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.InputStream;
+import java.io.OutputStream;
+
+import org.apache.sshd.server.ExitCallback;
+
+/**
+ * <p>
+ * Represents a command, shell or subsystem that can be used to send command.
+ * </p>
+ *
+ * <p>
+ * This command have direct streams, meaning those streams will be provided by the ssh server
+ * for the shell to use directly. This interface is suitable for implementing commands in java,
+ * rather than using external processes. For wrapping such processes or using inverted streams,
+ * </p>
+ * see {@link org.apache.sshd.server.shell.InvertedShellWrapper}.
+ */
+public interface Command extends CommandLifecycle {
+
+ /**
+ * Set the input stream that can be used by the shell to read input.
+ *
+ * @param in The {@link InputStream} used by the shell to read input.
+ */
+ void setInputStream(InputStream in);
+
+ /**
+ * Set the output stream that can be used by the shell to write its output.
+ *
+ * @param out The {@link OutputStream} used by the shell to write its output
+ */
+ void setOutputStream(OutputStream out);
+
+ /**
+ * Set the error stream that can be used by the shell to write its errors.
+ *
+ * @param err The {@link OutputStream} used by the shell to write its errors
+ */
+ void setErrorStream(OutputStream err);
+
+ /**
+ * Set the callback that the shell has to call when it is closed.
+ *
+ * @param callback The {@link ExitCallback} to call when shell is closed
+ */
+ void setExitCallback(ExitCallback callback);
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/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
new file mode 100644
index 0000000..aff407b
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/server/command/CommandFactory.java
@@ -0,0 +1,41 @@
+/*
+ * 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 org.apache.sshd.common.NamedResource;
+
+/**
+ * A factory of commands.
+ * Commands are executed on the server side when an "exec" channel is
+ * requested by the SSH client.
+ *
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public interface CommandFactory extends NamedResource {
+
+ /**
+ * Create a command with the given name.
+ * If the command is not known, a dummy command should be returned to allow
+ * the display output to be sent back to the client.
+ *
+ * @param command The command that will be run
+ * @return a non {@code null} {@link Command} instance
+ */
+ Command createCommand(String command);
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/command/CommandLifecycle.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/command/CommandLifecycle.java b/sshd-core/src/main/java/org/apache/sshd/server/command/CommandLifecycle.java
new file mode 100644
index 0000000..ac694d5
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/server/command/CommandLifecycle.java
@@ -0,0 +1,50 @@
+/*
+ * 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 org.apache.sshd.server.Environment;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public interface CommandLifecycle {
+ /**
+ * Starts the command execution. All streams must have been set <U>before</U>
+ * calling this method. The command should implement {@link java.lang.Runnable},
+ * and this method should spawn a new thread like:
+ * <pre>
+ * {@code Thread(this).start(); }
+ * </pre>
+ *
+ * @param env The {@link Environment}
+ * @throws IOException If failed to start
+ */
+ void start(Environment env) throws IOException;
+
+ /**
+ * This method is called by the SSH server to destroy the command because
+ * the client has disconnected somehow.
+ *
+ * @throws Exception if failed to destroy
+ */
+ void destroy() throws Exception;
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/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
new file mode 100644
index 0000000..e1ce89c
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/server/command/DelegatingCommandFactory.java
@@ -0,0 +1,43 @@
+/*
+ * 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/f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShell.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShell.java b/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShell.java
index 3d7de3c..3abc523 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShell.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShell.java
@@ -21,8 +21,8 @@ package org.apache.sshd.server.shell;
import java.io.InputStream;
import java.io.OutputStream;
-import org.apache.sshd.server.CommandLifecycle;
import org.apache.sshd.server.SessionAware;
+import org.apache.sshd.server.command.CommandLifecycle;
/**
* This shell have inverted streams, such as the one obtained when launching a
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShellWrapper.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShellWrapper.java b/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShellWrapper.java
index 4819064..3c19e2c 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShellWrapper.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShellWrapper.java
@@ -31,10 +31,10 @@ import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.io.IoUtils;
import org.apache.sshd.common.util.logging.AbstractLoggingBean;
import org.apache.sshd.common.util.threads.ThreadUtils;
-import org.apache.sshd.server.Command;
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.session.ServerSession;
/**
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/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
new file mode 100644
index 0000000..af9af82
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/server/shell/ProcessShellCommandFactory.java
@@ -0,0 +1,50 @@
+/*
+ * 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.shell;
+
+import org.apache.sshd.common.Factory;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.server.command.Command;
+import org.apache.sshd.server.command.CommandFactory;
+
+/**
+ * Executes commands by invoking the underlying shell
+ *
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public class ProcessShellCommandFactory implements CommandFactory {
+ public static final String FACTORY_NAME = "shell-command";
+ public static final ProcessShellCommandFactory INSTANCE = new ProcessShellCommandFactory();
+
+ public ProcessShellCommandFactory() {
+ super();
+ }
+
+ @Override
+ public String getName() {
+ return FACTORY_NAME;
+ }
+
+ @Override
+ public Command createCommand(String command) {
+ Factory<Command> factory = new ProcessShellFactory(GenericUtils.split(command, ' '));
+ return factory.create();
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/shell/ProcessShellFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/shell/ProcessShellFactory.java b/sshd-core/src/main/java/org/apache/sshd/server/shell/ProcessShellFactory.java
index 3398e63..529b701 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/shell/ProcessShellFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/shell/ProcessShellFactory.java
@@ -27,7 +27,7 @@ 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.logging.AbstractLoggingBean;
-import org.apache.sshd.server.Command;
+import org.apache.sshd.server.command.Command;
/**
* A {@link Factory} of {@link Command} that will create a new process and bridge
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/shell/ShellFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/shell/ShellFactory.java b/sshd-core/src/main/java/org/apache/sshd/server/shell/ShellFactory.java
index 0a80f67..d403d42 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/shell/ShellFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/shell/ShellFactory.java
@@ -20,7 +20,7 @@
package org.apache.sshd.server.shell;
import org.apache.sshd.common.Factory;
-import org.apache.sshd.server.Command;
+import org.apache.sshd.server.command.Command;
/**
* Useful marker interface
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/shell/UnknownCommand.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/shell/UnknownCommand.java b/sshd-core/src/main/java/org/apache/sshd/server/shell/UnknownCommand.java
index 59d970c..43b9b9f 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/shell/UnknownCommand.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/shell/UnknownCommand.java
@@ -25,9 +25,9 @@ import java.nio.charset.StandardCharsets;
import java.util.Objects;
import org.apache.sshd.common.util.ValidateUtils;
-import org.apache.sshd.server.Command;
import org.apache.sshd.server.Environment;
import org.apache.sshd.server.ExitCallback;
+import org.apache.sshd.server.command.Command;
/**
* Implementation of an unknown command that can be returned by <code>CommandFactory</code>
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/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 871ca60..ea94525 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
@@ -19,13 +19,15 @@
package org.apache.sshd.server.shell;
-import org.apache.sshd.server.Command;
-import org.apache.sshd.server.CommandFactory;
+import org.apache.sshd.server.command.Command;
+import org.apache.sshd.server.command.CommandFactory;
/**
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
public class UnknownCommandFactory implements CommandFactory {
+ public static final String FACTORY_NAME = "unknown";
+
public static final UnknownCommandFactory INSTANCE = new UnknownCommandFactory();
public UnknownCommandFactory() {
@@ -33,6 +35,11 @@ public class UnknownCommandFactory implements CommandFactory {
}
@Override
+ public String getName() {
+ return FACTORY_NAME;
+ }
+
+ @Override
public Command createCommand(String command) {
return new UnknownCommand(command);
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/subsystem/SubsystemFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/subsystem/SubsystemFactory.java b/sshd-core/src/main/java/org/apache/sshd/server/subsystem/SubsystemFactory.java
index f9dbf0f..8b0cc3f 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/subsystem/SubsystemFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/subsystem/SubsystemFactory.java
@@ -20,7 +20,7 @@
package org.apache.sshd.server.subsystem;
import org.apache.sshd.common.NamedFactory;
-import org.apache.sshd.server.Command;
+import org.apache.sshd.server.command.Command;
/**
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/sshd-core/src/test/java/org/apache/sshd/KeepAliveTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/KeepAliveTest.java b/sshd-core/src/test/java/org/apache/sshd/KeepAliveTest.java
index dd649e5..4e09447 100644
--- a/sshd-core/src/test/java/org/apache/sshd/KeepAliveTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/KeepAliveTest.java
@@ -32,8 +32,8 @@ import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.common.FactoryManager;
import org.apache.sshd.common.PropertyResolverUtils;
import org.apache.sshd.common.channel.Channel;
-import org.apache.sshd.server.Command;
import org.apache.sshd.server.SshServer;
+import org.apache.sshd.server.command.Command;
import org.apache.sshd.util.test.BaseTestSupport;
import org.apache.sshd.util.test.EchoShell;
import org.apache.sshd.util.test.EchoShellFactory;
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/sshd-core/src/test/java/org/apache/sshd/KeyReExchangeTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/KeyReExchangeTest.java b/sshd-core/src/test/java/org/apache/sshd/KeyReExchangeTest.java
index f2ca9df..4fdb932 100644
--- a/sshd-core/src/test/java/org/apache/sshd/KeyReExchangeTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/KeyReExchangeTest.java
@@ -55,10 +55,10 @@ import org.apache.sshd.common.session.Session;
import org.apache.sshd.common.session.SessionListener;
import org.apache.sshd.common.util.io.NullOutputStream;
import org.apache.sshd.common.util.security.SecurityUtils;
-import org.apache.sshd.server.Command;
import org.apache.sshd.server.Environment;
import org.apache.sshd.server.ExitCallback;
import org.apache.sshd.server.SshServer;
+import org.apache.sshd.server.command.Command;
import org.apache.sshd.server.subsystem.SubsystemFactory;
import org.apache.sshd.util.test.BaseTestSupport;
import org.apache.sshd.util.test.JSchLogger;
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/sshd-core/src/test/java/org/apache/sshd/WindowAdjustTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/WindowAdjustTest.java b/sshd-core/src/test/java/org/apache/sshd/WindowAdjustTest.java
index cac8e32..fd1fd84 100644
--- a/sshd-core/src/test/java/org/apache/sshd/WindowAdjustTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/WindowAdjustTest.java
@@ -45,10 +45,10 @@ import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
import org.apache.sshd.common.util.io.NoCloseOutputStream;
import org.apache.sshd.common.util.logging.AbstractLoggingBean;
import org.apache.sshd.common.util.threads.ThreadUtils;
-import org.apache.sshd.server.AsyncCommand;
import org.apache.sshd.server.Environment;
import org.apache.sshd.server.ExitCallback;
import org.apache.sshd.server.SshServer;
+import org.apache.sshd.server.command.AsyncCommand;
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
import org.apache.sshd.util.test.BaseTestSupport;
import org.junit.After;
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/sshd-core/src/test/java/org/apache/sshd/agent/AgentTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/agent/AgentTest.java b/sshd-core/src/test/java/org/apache/sshd/agent/AgentTest.java
index f252be7..7deebfc 100644
--- a/sshd-core/src/test/java/org/apache/sshd/agent/AgentTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/agent/AgentTest.java
@@ -38,9 +38,9 @@ import org.apache.sshd.client.channel.ChannelShell;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.common.keyprovider.KeyPairProvider;
import org.apache.sshd.common.util.security.SecurityUtils;
-import org.apache.sshd.server.Command;
import org.apache.sshd.server.Environment;
import org.apache.sshd.server.SshServer;
+import org.apache.sshd.server.command.Command;
import org.apache.sshd.server.forward.AcceptAllForwardingFilter;
import org.apache.sshd.util.test.BaseTestSupport;
import org.apache.sshd.util.test.EchoShell;
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/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 f3d94a8..0026cc3 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
@@ -95,13 +95,13 @@ import org.apache.sshd.common.util.buffer.Buffer;
import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
import org.apache.sshd.common.util.io.NoCloseOutputStream;
import org.apache.sshd.common.util.net.SshdSocketAddress;
-import org.apache.sshd.server.Command;
import org.apache.sshd.server.SshServer;
import org.apache.sshd.server.auth.keyboard.DefaultKeyboardInteractiveAuthenticator;
import org.apache.sshd.server.auth.keyboard.KeyboardInteractiveAuthenticator;
import org.apache.sshd.server.auth.password.RejectAllPasswordAuthenticator;
import org.apache.sshd.server.channel.ChannelSession;
import org.apache.sshd.server.channel.ChannelSessionFactory;
+import org.apache.sshd.server.command.Command;
import org.apache.sshd.server.forward.DirectTcpipFactory;
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
import org.apache.sshd.server.session.ServerConnectionServiceFactory;
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/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 038ce55..8a48daf 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,6 +26,8 @@ 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;
@@ -51,13 +53,23 @@ public class ChannelExecTest extends BaseTestSupport {
@BeforeClass
public static void setupClientAndServer() throws Exception {
sshd = Utils.setupTestServer(ChannelExecTest.class);
- sshd.setCommandFactory(command -> new CommandExecutionHelper(command) {
+ sshd.setCommandFactory(new CommandFactory() {
@Override
- protected boolean handleCommandLine(String command) throws Exception {
- OutputStream stdout = getOutputStream();
- stdout.write(command.getBytes(StandardCharsets.US_ASCII));
- stdout.flush();
- return false;
+ 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;
+ }
+ };
}
});
sshd.start();
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/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 aeb5e3b..517b07c 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
@@ -26,9 +26,9 @@ import java.rmi.ServerException;
import java.util.concurrent.TimeUnit;
import org.apache.sshd.client.SshClient;
-import org.apache.sshd.server.Command;
-import org.apache.sshd.server.CommandFactory;
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,18 +84,28 @@ public class ClientSessionTest extends BaseTestSupport {
public void testDefaultExecuteCommandMethod() throws Exception {
final String expectedCommand = getCurrentTestName() + "-CMD";
final String expectedResponse = getCurrentTestName() + "-RSP";
- sshd.setCommandFactory(command -> new CommandExecutionHelper(command) {
- private boolean cmdProcessed;
+ sshd.setCommandFactory(new CommandFactory() {
+ @Override
+ public String getName() {
+ return getCurrentTestName();
+ }
@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;
+ 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;
+ }
+ };
}
});
@@ -113,18 +123,28 @@ public class ClientSessionTest extends BaseTestSupport {
public void testExceptionThrownIfRemoteStderrWrittenTo() throws Exception {
final String expectedCommand = getCurrentTestName() + "-CMD";
final String expectedErrorMessage = getCurrentTestName() + "-ERR";
- sshd.setCommandFactory(command -> new CommandExecutionHelper(command) {
- private boolean cmdProcessed;
+ sshd.setCommandFactory(new CommandFactory() {
+ @Override
+ public String getName() {
+ return getCurrentTestName();
+ }
@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;
+ 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;
+ }
+ };
}
});
@@ -158,6 +178,11 @@ public class ClientSessionTest extends BaseTestSupport {
final int exepectedErrorCode = 7365;
sshd.setCommandFactory(new CommandFactory() {
@Override
+ public String getName() {
+ return getCurrentTestName();
+ }
+
+ @Override
public Command createCommand(String command) {
return new CommandExecutionHelper(command) {
private boolean cmdProcessed;
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/sshd-core/src/test/java/org/apache/sshd/common/channel/WindowTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/channel/WindowTest.java b/sshd-core/src/test/java/org/apache/sshd/common/channel/WindowTest.java
index 93c37be..864fc23 100644
--- a/sshd-core/src/test/java/org/apache/sshd/common/channel/WindowTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/common/channel/WindowTest.java
@@ -45,10 +45,10 @@ import org.apache.sshd.common.io.IoReadFuture;
import org.apache.sshd.common.session.Session;
import org.apache.sshd.common.util.buffer.Buffer;
import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
-import org.apache.sshd.server.Command;
import org.apache.sshd.server.SshServer;
import org.apache.sshd.server.channel.ChannelSession;
import org.apache.sshd.server.channel.ChannelSessionFactory;
+import org.apache.sshd.server.command.Command;
import org.apache.sshd.server.forward.DirectTcpipFactory;
import org.apache.sshd.server.session.ServerConnectionService;
import org.apache.sshd.server.session.ServerConnectionServiceFactory;
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/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 8c083a3..d1955ef 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
@@ -72,6 +72,8 @@ import org.apache.sshd.server.auth.keyboard.KeyboardInteractiveAuthenticator;
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;
@@ -522,43 +524,51 @@ public class ServerTest extends BaseTestSupport {
@Test // see SSHD-645
public void testChannelStateChangeNotifications() throws Exception {
final Semaphore exitSignal = new Semaphore(0);
- sshd.setCommandFactory(command -> {
- ValidateUtils.checkTrue(String.CASE_INSENSITIVE_ORDER.compare(command, getCurrentTestName()) == 0, "Unexpected command: %s", command);
+ sshd.setCommandFactory(new CommandFactory() {
+ @Override
+ public String getName() {
+ return getCurrentTestName();
+ }
- return new Command() {
- private ExitCallback cb;
+ @Override
+ public Command createCommand(String command) {
+ ValidateUtils.checkTrue(String.CASE_INSENSITIVE_ORDER.compare(command, getCurrentTestName()) == 0, "Unexpected command: %s", command);
- @Override
- public void setOutputStream(OutputStream out) {
- // ignored
- }
+ return new Command() {
+ private ExitCallback cb;
- @Override
- public void setInputStream(InputStream in) {
- // ignored
- }
+ @Override
+ public void setOutputStream(OutputStream out) {
+ // ignored
+ }
- @Override
- public void setExitCallback(ExitCallback callback) {
- cb = callback;
- }
+ @Override
+ public void setInputStream(InputStream in) {
+ // ignored
+ }
- @Override
- public void setErrorStream(OutputStream err) {
- // ignored
- }
+ @Override
+ public void setExitCallback(ExitCallback callback) {
+ cb = callback;
+ }
- @Override
- public void destroy() {
- // ignored
- }
+ @Override
+ public void setErrorStream(OutputStream err) {
+ // ignored
+ }
- @Override
- public void start(Environment env) throws IOException {
- exitSignal.release();
- cb.onExit(0, command);
- }
- };
+ @Override
+ public void destroy() {
+ // ignored
+ }
+
+ @Override
+ public void start(Environment env) throws IOException {
+ exitSignal.release();
+ cb.onExit(0, command);
+ }
+ };
+ }
});
sshd.start();
client.start();
@@ -595,46 +605,54 @@ public class ServerTest extends BaseTestSupport {
@Test
public void testEnvironmentVariablesPropagationToServer() throws Exception {
final AtomicReference<Environment> envHolder = new AtomicReference<>(null);
- sshd.setCommandFactory(command -> {
- ValidateUtils.checkTrue(String.CASE_INSENSITIVE_ORDER.compare(command, getCurrentTestName()) == 0, "Unexpected command: %s", command);
+ sshd.setCommandFactory(new CommandFactory() {
+ @Override
+ public String getName() {
+ return getCurrentTestName();
+ }
- return new Command() {
- private ExitCallback cb;
+ @Override
+ public Command createCommand(String command) {
+ ValidateUtils.checkTrue(String.CASE_INSENSITIVE_ORDER.compare(command, getCurrentTestName()) == 0, "Unexpected command: %s", command);
- @Override
- public void setOutputStream(OutputStream out) {
- // ignored
- }
+ return new Command() {
+ private ExitCallback cb;
- @Override
- public void setInputStream(InputStream in) {
- // ignored
- }
+ @Override
+ public void setOutputStream(OutputStream out) {
+ // ignored
+ }
- @Override
- public void setExitCallback(ExitCallback callback) {
- cb = callback;
- }
+ @Override
+ public void setInputStream(InputStream in) {
+ // ignored
+ }
- @Override
- public void setErrorStream(OutputStream err) {
- // ignored
- }
+ @Override
+ public void setExitCallback(ExitCallback callback) {
+ cb = callback;
+ }
- @Override
- public void destroy() {
- // ignored
- }
+ @Override
+ public void setErrorStream(OutputStream err) {
+ // 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 destroy() {
+ // ignored
}
- cb.onExit(0, 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);
+ }
+ };
+ }
});
TestChannelListener channelListener = new TestChannelListener(getCurrentTestName());
@@ -934,6 +952,15 @@ public class ServerTest extends BaseTestSupport {
// 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);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/sshd-core/src/test/java/org/apache/sshd/util/test/AsyncEchoShellFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/util/test/AsyncEchoShellFactory.java b/sshd-core/src/test/java/org/apache/sshd/util/test/AsyncEchoShellFactory.java
index 5193cec..de9dbf4 100644
--- a/sshd-core/src/test/java/org/apache/sshd/util/test/AsyncEchoShellFactory.java
+++ b/sshd-core/src/test/java/org/apache/sshd/util/test/AsyncEchoShellFactory.java
@@ -29,13 +29,13 @@ import org.apache.sshd.common.io.IoInputStream;
import org.apache.sshd.common.io.IoOutputStream;
import org.apache.sshd.common.session.Session;
import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
-import org.apache.sshd.server.AsyncCommand;
import org.apache.sshd.server.ChannelSessionAware;
-import org.apache.sshd.server.Command;
import org.apache.sshd.server.Environment;
import org.apache.sshd.server.ExitCallback;
import org.apache.sshd.server.channel.ChannelDataReceiver;
import org.apache.sshd.server.channel.ChannelSession;
+import org.apache.sshd.server.command.AsyncCommand;
+import org.apache.sshd.server.command.Command;
import org.apache.sshd.server.shell.ShellFactory;
/**
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/sshd-core/src/test/java/org/apache/sshd/util/test/CommandExecutionHelper.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/util/test/CommandExecutionHelper.java b/sshd-core/src/test/java/org/apache/sshd/util/test/CommandExecutionHelper.java
index c44a2ad..c199a38 100644
--- a/sshd-core/src/test/java/org/apache/sshd/util/test/CommandExecutionHelper.java
+++ b/sshd-core/src/test/java/org/apache/sshd/util/test/CommandExecutionHelper.java
@@ -26,7 +26,7 @@ import java.io.InterruptedIOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
-import org.apache.sshd.server.AbstractCommandSupport;
+import org.apache.sshd.server.command.AbstractCommandSupport;
/**
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/sshd-core/src/test/java/org/apache/sshd/util/test/EchoShellFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/util/test/EchoShellFactory.java b/sshd-core/src/test/java/org/apache/sshd/util/test/EchoShellFactory.java
index fe97a2f..a9ec9d3 100644
--- a/sshd-core/src/test/java/org/apache/sshd/util/test/EchoShellFactory.java
+++ b/sshd-core/src/test/java/org/apache/sshd/util/test/EchoShellFactory.java
@@ -18,7 +18,7 @@
*/
package org.apache.sshd.util.test;
-import org.apache.sshd.server.Command;
+import org.apache.sshd.server.command.Command;
import org.apache.sshd.server.shell.ShellFactory;
/**
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1a8077b/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 d4dacfa..7315610 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
@@ -29,8 +29,8 @@ import java.util.concurrent.ExecutorService;
import org.apache.sshd.common.channel.ChannelOutputStream;
import org.apache.sshd.common.file.FileSystemAware;
-import org.apache.sshd.server.AbstractCommandSupport;
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;
Re: [2/2] mina-sshd git commit: [SSHD-819] Standardized the
DelegateCommandFactory behavior
Posted by Guillaume Nodet <gn...@apache.org>.
Please revert the change and implement it again without turning the
CommandFactory into a NamedResource.
A CommandFactory is not limited to implement a single command, so having a
named on it does not make much sense to me, and it breaks all existing
implementations for no benefit.
2018-05-15 9:48 GMT+02:00 <lg...@apache.org>:
> [SSHD-819] Standardized the DelegateCommandFactory behavior
>
>
> Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
> Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/f1a8077b
> Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/f1a8077b
> Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/f1a8077b
>
> Branch: refs/heads/master
> Commit: f1a8077be3875184b067095b236793e4801c2ad5
> Parents: 3182ad8
> Author: Goldstein Lyor <ly...@c-b4.com>
> Authored: Tue May 15 10:41:24 2018 +0300
> Committer: Goldstein Lyor <ly...@c-b4.com>
> Committed: Tue May 15 10:48:02 2018 +0300
>
> ----------------------------------------------------------------------
> .../sshd/cli/server/SshServerCliSupport.java | 2 +-
> .../apache/sshd/cli/server/SshServerMain.java | 6 +-
> .../apache/sshd/cli/server/SshFsMounter.java | 9 +-
> .../sshd/server/AbstractCommandSupport.java | 168 ------------------
> .../org/apache/sshd/server/AsyncCommand.java | 52 ------
> .../apache/sshd/server/ChannelSessionAware.java | 1 +
> .../java/org/apache/sshd/server/Command.java | 65 -------
> .../org/apache/sshd/server/CommandFactory.java | 40 -----
> .../apache/sshd/server/CommandLifecycle.java | 48 ------
> .../sshd/server/ServerFactoryManager.java | 2 +
> .../java/org/apache/sshd/server/SshServer.java | 2 +
> .../server/channel/ChannelDataReceiver.java | 4 +-
> .../sshd/server/channel/ChannelSession.java | 8 +-
> .../server/command/AbstractCommandSupport.java | 170 +++++++++++++++++++
> .../AbstractDelegatingCommandFactory.java | 76 +++++++++
> .../sshd/server/command/AsyncCommand.java | 52 ++++++
> .../org/apache/sshd/server/command/Command.java | 67 ++++++++
> .../sshd/server/command/CommandFactory.java | 41 +++++
> .../sshd/server/command/CommandLifecycle.java | 50 ++++++
> .../command/DelegatingCommandFactory.java | 43 +++++
> .../apache/sshd/server/shell/InvertedShell.java | 2 +-
> .../sshd/server/shell/InvertedShellWrapper.java | 2 +-
> .../shell/ProcessShellCommandFactory.java | 50 ++++++
> .../sshd/server/shell/ProcessShellFactory.java | 2 +-
> .../apache/sshd/server/shell/ShellFactory.java | 2 +-
> .../sshd/server/shell/UnknownCommand.java | 2 +-
> .../server/shell/UnknownCommandFactory.java | 11 +-
> .../sshd/server/subsystem/SubsystemFactory.java | 2 +-
> .../java/org/apache/sshd/KeepAliveTest.java | 2 +-
> .../java/org/apache/sshd/KeyReExchangeTest.java | 2 +-
> .../java/org/apache/sshd/WindowAdjustTest.java | 2 +-
> .../java/org/apache/sshd/agent/AgentTest.java | 2 +-
> .../java/org/apache/sshd/client/ClientTest.java | 2 +-
> .../sshd/client/channel/ChannelExecTest.java | 24 ++-
> .../sshd/client/session/ClientSessionTest.java | 69 +++++---
> .../apache/sshd/common/channel/WindowTest.java | 2 +-
> .../java/org/apache/sshd/server/ServerTest.java | 149 +++++++++-------
> .../sshd/util/test/AsyncEchoShellFactory.java | 4 +-
> .../sshd/util/test/CommandExecutionHelper.java | 2 +-
> .../apache/sshd/util/test/EchoShellFactory.java | 2 +-
> .../org/apache/sshd/git/AbstractGitCommand.java | 2 +-
> .../sshd/git/AbstractGitCommandFactory.java | 47 ++---
> .../sshd/git/pack/GitPackCommandFactory.java | 7 +-
> .../sshd/git/pgm/GitPgmCommandFactory.java | 7 +-
> .../org/apache/sshd/server/scp/ScpCommand.java | 2 +-
> .../sshd/server/scp/ScpCommandFactory.java | 63 +++----
> .../org/apache/sshd/client/scp/ScpTest.java | 2 +-
> .../sshd/server/scp/ScpCommandFactoryTest.java | 2 +-
> .../server/subsystem/sftp/SftpSubsystem.java | 4 +-
> .../subsystem/sftp/SftpSubsystemFactory.java | 2 +-
> .../sshd/client/subsystem/sftp/ClientTest.java | 2 +-
> .../sshd/client/subsystem/sftp/SftpTest.java | 2 +-
> .../client/subsystem/sftp/SftpVersionsTest.java | 2 +-
> .../SpaceAvailableExtensionImplTest.java | 2 +-
> .../openssh/helpers/OpenSSHExtensionsTest.java | 2 +-
> 55 files changed, 815 insertions(+), 574 deletions(-)
> ----------------------------------------------------------------------
>
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/sshd-cli/src/main/java/org/apache/sshd/cli/
> server/SshServerCliSupport.java
> ----------------------------------------------------------------------
> diff --git a/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerCliSupport.java
> b/sshd-cli/src/main/java/org/apache/sshd/cli/server/
> SshServerCliSupport.java
> index 910566f..8b392bc 100644
> --- a/sshd-cli/src/main/java/org/apache/sshd/cli/server/
> SshServerCliSupport.java
> +++ b/sshd-cli/src/main/java/org/apache/sshd/cli/server/
> SshServerCliSupport.java
> @@ -49,10 +49,10 @@ import org.apache.sshd.common.util.GenericUtils;
> import org.apache.sshd.common.util.ValidateUtils;
> import org.apache.sshd.common.util.security.SecurityUtils;
> import org.apache.sshd.common.util.threads.ThreadUtils;
> -import org.apache.sshd.server.Command;
> import org.apache.sshd.server.ServerAuthenticationManager;
> import org.apache.sshd.server.ServerFactoryManager;
> import org.apache.sshd.server.SshServer;
> +import org.apache.sshd.server.command.Command;
> import org.apache.sshd.server.config.SshServerConfigFileReader;
> import org.apache.sshd.server.forward.ForwardingFilter;
> import org.apache.sshd.server.keyprovider.AbstractGeneratorHostKeyProvid
> er;
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/sshd-cli/src/main/java/org/apache/sshd/cli/
> server/SshServerMain.java
> ----------------------------------------------------------------------
> diff --git a/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerMain.java
> b/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerMain.java
> index cba6fc2..b9f6d1e 100644
> --- a/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerMain.java
> +++ b/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerMain.java
> @@ -33,13 +33,13 @@ import org.apache.sshd.common.PropertyResolverUtils;
> import org.apache.sshd.common.config.SshConfigFileReader;
> import org.apache.sshd.common.keyprovider.KeyPairProvider;
> import org.apache.sshd.common.util.GenericUtils;
> -import org.apache.sshd.server.Command;
> import org.apache.sshd.server.SshServer;
> import org.apache.sshd.server.auth.pubkey.AcceptAllPublickeyAuthenticato
> r;
> +import org.apache.sshd.server.command.Command;
> import org.apache.sshd.server.config.keys.ServerIdentity;
> import org.apache.sshd.server.keyprovider.AbstractGeneratorHostKeyProvid
> er;
> import org.apache.sshd.server.scp.ScpCommandFactory;
> -import org.apache.sshd.server.shell.ProcessShellFactory;
> +import org.apache.sshd.server.shell.ProcessShellCommandFactory;
> import org.apache.sshd.server.shell.ShellFactory;
>
> /**
> @@ -181,7 +181,7 @@ public class SshServerMain extends SshServerCliSupport
> {
> sshd.setPublickeyAuthenticator(AcceptAllPublickeyAuthenticato
> r.INSTANCE);
> setupServerForwarding(sshd, resolver);
> sshd.setCommandFactory(new ScpCommandFactory.Builder()
> - .withDelegate(command -> new ProcessShellFactory(GenericUtils.split(command,
> ' ')).create())
> + .withDelegate(ProcessShellCommandFactory.INSTANCE)
> .build());
>
> List<NamedFactory<Command>> subsystems = resolveServerSubsystems(System.err,
> resolver);
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/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 74a5a83..c270be7 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
> @@ -43,13 +43,13 @@ import org.apache.sshd.common.util.ValidateUtils;
> import org.apache.sshd.common.util.logging.AbstractLoggingBean;
> import org.apache.sshd.common.util.security.SecurityUtils;
> import org.apache.sshd.common.util.threads.ThreadUtils;
> -import org.apache.sshd.server.Command;
> -import org.apache.sshd.server.CommandFactory;
> import org.apache.sshd.server.Environment;
> import org.apache.sshd.server.ExitCallback;
> import org.apache.sshd.server.SessionAware;
> import org.apache.sshd.server.SshServer;
> import org.apache.sshd.server.auth.password.
> AcceptAllPasswordAuthenticator;
> +import org.apache.sshd.server.command.Command;
> +import org.apache.sshd.server.command.CommandFactory;
> import org.apache.sshd.server.forward.AcceptAllForwardingFilter;
> import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
> import org.apache.sshd.server.scp.ScpCommandFactory;
> @@ -232,6 +232,11 @@ public final class SshFsMounter extends
> SshServerCliSupport {
> }
>
> @Override
> + public String getName() {
> + return "mounter";
> + }
> +
> + @Override
> public Command createCommand(String command) {
> return new MounterCommand(command);
> }
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/
> AbstractCommandSupport.java
> ----------------------------------------------------------------------
> diff --git a/sshd-core/src/main/java/org/apache/sshd/server/AbstractCommandSupport.java
> b/sshd-core/src/main/java/org/apache/sshd/server/
> AbstractCommandSupport.java
> deleted file mode 100644
> index 7533157..0000000
> --- a/sshd-core/src/main/java/org/apache/sshd/server/
> AbstractCommandSupport.java
> +++ /dev/null
> @@ -1,168 +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;
> -
> -import java.io.IOException;
> -import java.io.InputStream;
> -import java.io.OutputStream;
> -import java.util.Collection;
> -import java.util.concurrent.ExecutorService;
> -import java.util.concurrent.Future;
> -
> -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;
> -
> -/**
> - * Provides a basic useful skeleton for {@link Command} executions
> - *
> - * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD
> Project</a>
> - */
> -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;
> -
> - protected AbstractCommandSupport(String command, ExecutorService
> executorService, boolean shutdownOnExit) {
> - this.command = command;
> -
> - if (executorService == null) {
> - String poolName = GenericUtils.isEmpty(command) ?
> getClass().getSimpleName() : 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;
> - }
> - }
> -
> - public String getCommand() {
> - return command;
> - }
> -
> - @Override
> - public ExecutorService getExecutorService() {
> - return executorService;
> - }
> -
> - @Override
> - public boolean isShutdownOnExit() {
> - return shutdownOnExit;
> - }
> -
> - public InputStream getInputStream() {
> - return in;
> - }
> -
> - @Override
> - public void setInputStream(InputStream in) {
> - this.in = in;
> - }
> -
> - public OutputStream getOutputStream() {
> - return out;
> - }
> -
> - @Override
> - public void setOutputStream(OutputStream out) {
> - this.out = out;
> - }
> -
> - public OutputStream getErrorStream() {
> - return err;
> - }
> -
> - @Override
> - public void setErrorStream(OutputStream err) {
> - this.err = err;
> - }
> -
> - public ExitCallback getExitCallback() {
> - return callback;
> - }
> -
> - @Override
> - public void setExitCallback(ExitCallback callback) {
> - this.callback = callback;
> - }
> -
> - public Environment getEnvironment() {
> - return environment;
> - }
> -
> - protected Future<?> getStartedCommandFuture() {
> - return cmdFuture;
> - }
> -
> - @Override
> - public void start(Environment env) throws IOException {
> - environment = env;
> - ExecutorService executors = getExecutorService();
> - cmdFuture = executors.submit(this);
> - }
> -
> - @Override
> - public void destroy() {
> - ExecutorService executors = getExecutorService();
> - if ((executors != null) && (!executors.isShutdown()) &&
> isShutdownOnExit()) {
> - Collection<Runnable> runners = executors.shutdownNow();
> - if (log.isDebugEnabled()) {
> - log.debug("destroy() - shutdown executor service -
> runners count=" + runners.size());
> - }
> - }
> - this.executorService = null;
> - }
> -
> - @Override
> - public void onExit(int exitValue, String exitMessage) {
> - if (cbCalled) {
> - if (log.isTraceEnabled()) {
> - log.trace("onExit({}) ignore exitValue={}, message={} -
> already called",
> - this, exitValue, exitMessage);
> - }
> - return;
> - }
> -
> - ExitCallback cb = getExitCallback();
> - try {
> - if (log.isDebugEnabled()) {
> - log.debug("onExit({}) exiting - value={}, message={}",
> this, exitValue, exitMessage);
> - }
> - cb.onExit(exitValue, exitMessage);
> - } finally {
> - cbCalled = true;
> - }
> - }
> -
> - @Override
> - public String toString() {
> - return getClass().getSimpleName() + "[" + getCommand() + "]";
> - }
> -}
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/AsyncCommand.java
> ----------------------------------------------------------------------
> diff --git a/sshd-core/src/main/java/org/apache/sshd/server/AsyncCommand.java
> b/sshd-core/src/main/java/org/apache/sshd/server/AsyncCommand.java
> deleted file mode 100644
> index b49af64..0000000
> --- a/sshd-core/src/main/java/org/apache/sshd/server/AsyncCommand.java
> +++ /dev/null
> @@ -1,52 +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;
> -
> -import org.apache.sshd.common.io.IoInputStream;
> -import org.apache.sshd.common.io.IoOutputStream;
> -
> -/**
> - * Represents a command capable of doing non-blocking io.
> - * If this interface is implemented by a command, the usual
> - * blocking input / output / error streams won't be set.
> - */
> -public interface AsyncCommand extends Command {
> -
> - /**
> - * Set the input stream that can be used by the shell to read input.
> - *
> - * @param in The {@link IoInputStream} used by the shell to read input
> - */
> - void setIoInputStream(IoInputStream in);
> -
> - /**
> - * Set the output stream that can be used by the shell to write its
> output.
> - *
> - * @param out The {@link IoOutputStream} used by the shell to write
> its output
> - */
> - void setIoOutputStream(IoOutputStream out);
> -
> - /**
> - * Set the error stream that can be used by the shell to write its
> errors.
> - *
> - * @param err The {@link IoOutputStream} used by the shell to write
> its errors
> - */
> - void setIoErrorStream(IoOutputStream err);
> -
> -}
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/
> ChannelSessionAware.java
> ----------------------------------------------------------------------
> diff --git a/sshd-core/src/main/java/org/apache/sshd/server/ChannelSessionAware.java
> b/sshd-core/src/main/java/org/apache/sshd/server/ChannelSessionAware.java
> index 150e719..d6d7c8b 100644
> --- a/sshd-core/src/main/java/org/apache/sshd/server/
> ChannelSessionAware.java
> +++ b/sshd-core/src/main/java/org/apache/sshd/server/
> ChannelSessionAware.java
> @@ -19,6 +19,7 @@
> package org.apache.sshd.server;
>
> import org.apache.sshd.server.channel.ChannelSession;
> +import org.apache.sshd.server.command.Command;
>
> /**
> * {@link Command} can implement this optional interface
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/Command.java
> ----------------------------------------------------------------------
> diff --git a/sshd-core/src/main/java/org/apache/sshd/server/Command.java
> b/sshd-core/src/main/java/org/apache/sshd/server/Command.java
> deleted file mode 100644
> index 4043e48..0000000
> --- a/sshd-core/src/main/java/org/apache/sshd/server/Command.java
> +++ /dev/null
> @@ -1,65 +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;
> -
> -import java.io.InputStream;
> -import java.io.OutputStream;
> -
> -/**
> - * <p>
> - * Represents a command, shell or subsystem that can be used to send
> command.
> - * </p>
> - *
> - * <p>
> - * This command have direct streams, meaning those streams will be
> provided by the ssh server
> - * for the shell to use directly. This interface is suitable for
> implementing commands in java,
> - * rather than using external processes. For wrapping such processes or
> using inverted streams,
> - * </p>
> - * see {@link org.apache.sshd.server.shell.InvertedShellWrapper}.
> - */
> -public interface Command extends CommandLifecycle {
> -
> - /**
> - * Set the input stream that can be used by the shell to read input.
> - *
> - * @param in The {@link InputStream} used by the shell to read input.
> - */
> - void setInputStream(InputStream in);
> -
> - /**
> - * Set the output stream that can be used by the shell to write its
> output.
> - *
> - * @param out The {@link OutputStream} used by the shell to write its
> output
> - */
> - void setOutputStream(OutputStream out);
> -
> - /**
> - * Set the error stream that can be used by the shell to write its
> errors.
> - *
> - * @param err The {@link OutputStream} used by the shell to write its
> errors
> - */
> - void setErrorStream(OutputStream err);
> -
> - /**
> - * Set the callback that the shell has to call when it is closed.
> - *
> - * @param callback The {@link ExitCallback} to call when shell is
> closed
> - */
> - void setExitCallback(ExitCallback callback);
> -}
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/
> CommandFactory.java
> ----------------------------------------------------------------------
> diff --git a/sshd-core/src/main/java/org/apache/sshd/server/CommandFactory.java
> b/sshd-core/src/main/java/org/apache/sshd/server/CommandFactory.java
> deleted file mode 100644
> index 650abe1..0000000
> --- a/sshd-core/src/main/java/org/apache/sshd/server/CommandFactory.java
> +++ /dev/null
> @@ -1,40 +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;
> -
> -/**
> - * A factory of commands.
> - * Commands are executed on the server side when an "exec" channel is
> - * requested by the SSH client.
> - *
> - * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD
> Project</a>
> - */
> -@FunctionalInterface
> -public interface CommandFactory {
> -
> - /**
> - * Create a command with the given name.
> - * If the command is not known, a dummy command should be returned to
> allow
> - * the display output to be sent back to the client.
> - *
> - * @param command The command that will be run
> - * @return a non {@code null} {@link Command} instance
> - */
> - Command createCommand(String command);
> -}
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/
> CommandLifecycle.java
> ----------------------------------------------------------------------
> diff --git a/sshd-core/src/main/java/org/apache/sshd/server/CommandLifecycle.java
> b/sshd-core/src/main/java/org/apache/sshd/server/CommandLifecycle.java
> deleted file mode 100644
> index cbe3cf0..0000000
> --- a/sshd-core/src/main/java/org/apache/sshd/server/CommandLifecycle.java
> +++ /dev/null
> @@ -1,48 +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;
> -
> -import java.io.IOException;
> -
> -/**
> - * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD
> Project</a>
> - */
> -public interface CommandLifecycle {
> - /**
> - * Starts the command execution. All streams must have been set
> <U>before</U>
> - * calling this method. The command should implement {@link
> java.lang.Runnable},
> - * and this method should spawn a new thread like:
> - * <pre>
> - * {@code Thread(this).start(); }
> - * </pre>
> - *
> - * @param env The {@link Environment}
> - * @throws IOException If failed to start
> - */
> - void start(Environment env) throws IOException;
> -
> - /**
> - * This method is called by the SSH server to destroy the command
> because
> - * the client has disconnected somehow.
> - *
> - * @throws Exception if failed to destroy
> - */
> - void destroy() throws Exception;
> -}
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/
> ServerFactoryManager.java
> ----------------------------------------------------------------------
> diff --git a/sshd-core/src/main/java/org/apache/sshd/server/ServerFactoryManager.java
> b/sshd-core/src/main/java/org/apache/sshd/server/ServerFactoryManager.java
> index 68531ed..60bd655 100644
> --- a/sshd-core/src/main/java/org/apache/sshd/server/
> ServerFactoryManager.java
> +++ b/sshd-core/src/main/java/org/apache/sshd/server/
> ServerFactoryManager.java
> @@ -24,6 +24,8 @@ import java.util.concurrent.TimeUnit;
> import org.apache.sshd.common.Factory;
> import org.apache.sshd.common.FactoryManager;
> import org.apache.sshd.common.NamedFactory;
> +import org.apache.sshd.server.command.Command;
> +import org.apache.sshd.server.command.CommandFactory;
> import org.apache.sshd.server.session.ServerProxyAcceptorHolder;
>
> /**
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
> ----------------------------------------------------------------------
> diff --git a/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
> b/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
> index f93c5d0..35b72cc 100644
> --- a/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
> +++ b/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
> @@ -49,6 +49,8 @@ import org.apache.sshd.server.auth.hostbased.
> HostBasedAuthenticator;
> import org.apache.sshd.server.auth.keyboard.
> KeyboardInteractiveAuthenticator;
> import org.apache.sshd.server.auth.password.PasswordAuthenticator;
> import org.apache.sshd.server.auth.pubkey.PublickeyAuthenticator;
> +import org.apache.sshd.server.command.Command;
> +import org.apache.sshd.server.command.CommandFactory;
> import org.apache.sshd.server.session.ServerConnectionServiceFactory;
> import org.apache.sshd.server.session.ServerProxyAcceptor;
> import org.apache.sshd.server.session.ServerUserAuthServiceFactory;
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/
> channel/ChannelDataReceiver.java
> ----------------------------------------------------------------------
> diff --git a/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelDataReceiver.java
> b/sshd-core/src/main/java/org/apache/sshd/server/channel/
> ChannelDataReceiver.java
> index f336c89..59ade13 100644
> --- a/sshd-core/src/main/java/org/apache/sshd/server/channel/
> ChannelDataReceiver.java
> +++ b/sshd-core/src/main/java/org/apache/sshd/server/channel/
> ChannelDataReceiver.java
> @@ -30,10 +30,10 @@ import java.io.IOException;
> * Sequence of bytes that SSH client sends to the server is eventually
> sent to this interface
> * to be passed on to the final consumer.
> * By default {@link ChannelSession} spools this in a buffer so that you
> can read it from
> - * the input stream you get from {@link org.apache.sshd.server.
> Command#setInputStream(java.io.InputStream)}, but if command
> + * the input stream you get from {@link org.apache.sshd.server.
> command.Command#setInputStream(java.io.InputStream)}, but if command
> * wants to do a callback-driven I/O for the data it receives from the
> client, it can
> * call {@link ChannelSession#setDataReceiver(ChannelDataReceiver)} to
> do so.
> - * (And to grab a reference to {@link ChannelSession}, a {@link
> org.apache.sshd.server.Command} should implement
> + * (And to grab a reference to {@link ChannelSession}, a {@link
> org.apache.sshd.server.command.Command} should implement
> * {@link org.apache.sshd.server.ChannelSessionAware}.)
> * </p>
> *
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/
> channel/ChannelSession.java
> ----------------------------------------------------------------------
> diff --git a/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
> b/sshd-core/src/main/java/org/apache/sshd/server/channel/
> ChannelSession.java
> index b884d80..cfaa499 100644
> --- a/sshd-core/src/main/java/org/apache/sshd/server/channel/
> ChannelSession.java
> +++ b/sshd-core/src/main/java/org/apache/sshd/server/channel/
> ChannelSession.java
> @@ -62,15 +62,15 @@ import org.apache.sshd.common.util.
> buffer.ByteArrayBuffer;
> import org.apache.sshd.common.util.closeable.IoBaseCloseable;
> import org.apache.sshd.common.util.io.IoUtils;
> import org.apache.sshd.common.util.io.LoggingFilterOutputStream;
> -import org.apache.sshd.server.AsyncCommand;
> import org.apache.sshd.server.ChannelSessionAware;
> -import org.apache.sshd.server.Command;
> -import org.apache.sshd.server.CommandFactory;
> import org.apache.sshd.server.Environment;
> import org.apache.sshd.server.ServerFactoryManager;
> import org.apache.sshd.server.SessionAware;
> import org.apache.sshd.server.Signal;
> import org.apache.sshd.server.StandardEnvironment;
> +import org.apache.sshd.server.command.AsyncCommand;
> +import org.apache.sshd.server.command.Command;
> +import org.apache.sshd.server.command.CommandFactory;
> import org.apache.sshd.server.forward.AgentForwardingFilter;
> import org.apache.sshd.server.forward.X11ForwardingFilter;
> import org.apache.sshd.server.session.ServerSession;
> @@ -602,7 +602,7 @@ public class ChannelSession extends
> AbstractServerChannel {
> /**
> * For {@link Command} to install {@link ChannelDataReceiver}.
> * When you do this, {@link Command#setInputStream(java.io.InputStream)}
> or
> - * {@link org.apache.sshd.server.AsyncCommand#setIoInputStream(
> org.apache.sshd.common.io.IoInputStream)}
> + * {@link org.apache.sshd.server.command.AsyncCommand#
> setIoInputStream(org.apache.sshd.common.io.IoInputStream)}
> * will no longer be invoked. If you call this method from {@link
> Command#start(Environment)},
> * the input stream you received in {@link
> Command#setInputStream(java.io.InputStream)} will
> * not read any data.
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/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
> new file mode 100644
> index 0000000..58cf034
> --- /dev/null
> +++ b/sshd-core/src/main/java/org/apache/sshd/server/command/
> AbstractCommandSupport.java
> @@ -0,0 +1,170 @@
> +/*
> + * 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.io.InputStream;
> +import java.io.OutputStream;
> +import java.util.Collection;
> +import java.util.concurrent.ExecutorService;
> +import java.util.concurrent.Future;
> +
> +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;
> +
> +/**
> + * Provides a basic useful skeleton for {@link Command} executions
> + *
> + * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD
> Project</a>
> + */
> +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;
> +
> + protected AbstractCommandSupport(String command, ExecutorService
> executorService, boolean shutdownOnExit) {
> + this.command = command;
> +
> + if (executorService == null) {
> + String poolName = GenericUtils.isEmpty(command) ?
> getClass().getSimpleName() : 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;
> + }
> + }
> +
> + public String getCommand() {
> + return command;
> + }
> +
> + @Override
> + public ExecutorService getExecutorService() {
> + return executorService;
> + }
> +
> + @Override
> + public boolean isShutdownOnExit() {
> + return shutdownOnExit;
> + }
> +
> + public InputStream getInputStream() {
> + return in;
> + }
> +
> + @Override
> + public void setInputStream(InputStream in) {
> + this.in = in;
> + }
> +
> + public OutputStream getOutputStream() {
> + return out;
> + }
> +
> + @Override
> + public void setOutputStream(OutputStream out) {
> + this.out = out;
> + }
> +
> + public OutputStream getErrorStream() {
> + return err;
> + }
> +
> + @Override
> + public void setErrorStream(OutputStream err) {
> + this.err = err;
> + }
> +
> + public ExitCallback getExitCallback() {
> + return callback;
> + }
> +
> + @Override
> + public void setExitCallback(ExitCallback callback) {
> + this.callback = callback;
> + }
> +
> + public Environment getEnvironment() {
> + return environment;
> + }
> +
> + protected Future<?> getStartedCommandFuture() {
> + return cmdFuture;
> + }
> +
> + @Override
> + public void start(Environment env) throws IOException {
> + environment = env;
> + ExecutorService executors = getExecutorService();
> + cmdFuture = executors.submit(this);
> + }
> +
> + @Override
> + public void destroy() {
> + ExecutorService executors = getExecutorService();
> + if ((executors != null) && (!executors.isShutdown()) &&
> isShutdownOnExit()) {
> + Collection<Runnable> runners = executors.shutdownNow();
> + if (log.isDebugEnabled()) {
> + log.debug("destroy() - shutdown executor service -
> runners count=" + runners.size());
> + }
> + }
> + this.executorService = null;
> + }
> +
> + @Override
> + public void onExit(int exitValue, String exitMessage) {
> + if (cbCalled) {
> + if (log.isTraceEnabled()) {
> + log.trace("onExit({}) ignore exitValue={}, message={} -
> already called",
> + this, exitValue, exitMessage);
> + }
> + return;
> + }
> +
> + ExitCallback cb = getExitCallback();
> + try {
> + if (log.isDebugEnabled()) {
> + log.debug("onExit({}) exiting - value={}, message={}",
> this, exitValue, exitMessage);
> + }
> + cb.onExit(exitValue, exitMessage);
> + } finally {
> + cbCalled = true;
> + }
> + }
> +
> + @Override
> + public String toString() {
> + return getClass().getSimpleName() + "[" + getCommand() + "]";
> + }
> +}
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/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
> new file mode 100644
> index 0000000..3169958
> --- /dev/null
> +++ b/sshd-core/src/main/java/org/apache/sshd/server/command/
> AbstractDelegatingCommandFactory.java
> @@ -0,0 +1,76 @@
> +/*
> + * 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 org.apache.sshd.common.util.ValidateUtils;
> +import org.apache.sshd.common.util.logging.AbstractLoggingBean;
> +
> +/**
> + * TODO Add javadoc
> + *
> + * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD
> Project</a>
> + */
> +public abstract class AbstractDelegatingCommandFactory extends
> AbstractLoggingBean implements DelegatingCommandFactory {
> + private final String name;
> + /*
> + * NOTE: we expose setters since there is no problem to change these
> settings between
> + * successive invocations of the 'createCommand' method
> + */
> + private CommandFactory delegate;
> +
> + protected AbstractDelegatingCommandFactory(String name) {
> + this.name = ValidateUtils.checkNotNullAndNotEmpty(name, "No
> delegating command factory name provided");
> + }
> +
> + @Override
> + public String getName() {
> + return name;
> + }
> +
> + @Override
> + public CommandFactory getDelegateCommandFactory() {
> + return delegate;
> + }
> +
> + @Override
> + public void setDelegateCommandFactory(CommandFactory factory) {
> + delegate = factory;
> + }
> +
> + @Override
> + public Command createCommand(String command) {
> + if (isSupportedCommand(command)) {
> + return executeSupportedCommand(command);
> + }
> +
> + CommandFactory factory = getDelegateCommandFactory();
> + if (factory != null) {
> + return factory.createCommand(command);
> + }
> +
> + return createUnsupportedCommand(command);
> + }
> +
> + protected abstract Command executeSupportedCommand(String command);
> +
> + protected Command createUnsupportedCommand(String command) {
> + throw new IllegalArgumentException("Unknown command to execute:
> " + command);
> + }
> +}
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/
> command/AsyncCommand.java
> ----------------------------------------------------------------------
> diff --git a/sshd-core/src/main/java/org/apache/sshd/server/command/AsyncCommand.java
> b/sshd-core/src/main/java/org/apache/sshd/server/command/AsyncCommand.java
> new file mode 100644
> index 0000000..f3d2173
> --- /dev/null
> +++ b/sshd-core/src/main/java/org/apache/sshd/server/command/
> AsyncCommand.java
> @@ -0,0 +1,52 @@
> +/*
> + * 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 org.apache.sshd.common.io.IoInputStream;
> +import org.apache.sshd.common.io.IoOutputStream;
> +
> +/**
> + * Represents a command capable of doing non-blocking io.
> + * If this interface is implemented by a command, the usual
> + * blocking input / output / error streams won't be set.
> + */
> +public interface AsyncCommand extends Command {
> +
> + /**
> + * Set the input stream that can be used by the shell to read input.
> + *
> + * @param in The {@link IoInputStream} used by the shell to read input
> + */
> + void setIoInputStream(IoInputStream in);
> +
> + /**
> + * Set the output stream that can be used by the shell to write its
> output.
> + *
> + * @param out The {@link IoOutputStream} used by the shell to write
> its output
> + */
> + void setIoOutputStream(IoOutputStream out);
> +
> + /**
> + * Set the error stream that can be used by the shell to write its
> errors.
> + *
> + * @param err The {@link IoOutputStream} used by the shell to write
> its errors
> + */
> + void setIoErrorStream(IoOutputStream err);
> +
> +}
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/
> command/Command.java
> ----------------------------------------------------------------------
> diff --git a/sshd-core/src/main/java/org/apache/sshd/server/command/Command.java
> b/sshd-core/src/main/java/org/apache/sshd/server/command/Command.java
> new file mode 100644
> index 0000000..5425d3a
> --- /dev/null
> +++ b/sshd-core/src/main/java/org/apache/sshd/server/command/Command.java
> @@ -0,0 +1,67 @@
> +/*
> + * 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.InputStream;
> +import java.io.OutputStream;
> +
> +import org.apache.sshd.server.ExitCallback;
> +
> +/**
> + * <p>
> + * Represents a command, shell or subsystem that can be used to send
> command.
> + * </p>
> + *
> + * <p>
> + * This command have direct streams, meaning those streams will be
> provided by the ssh server
> + * for the shell to use directly. This interface is suitable for
> implementing commands in java,
> + * rather than using external processes. For wrapping such processes or
> using inverted streams,
> + * </p>
> + * see {@link org.apache.sshd.server.shell.InvertedShellWrapper}.
> + */
> +public interface Command extends CommandLifecycle {
> +
> + /**
> + * Set the input stream that can be used by the shell to read input.
> + *
> + * @param in The {@link InputStream} used by the shell to read input.
> + */
> + void setInputStream(InputStream in);
> +
> + /**
> + * Set the output stream that can be used by the shell to write its
> output.
> + *
> + * @param out The {@link OutputStream} used by the shell to write its
> output
> + */
> + void setOutputStream(OutputStream out);
> +
> + /**
> + * Set the error stream that can be used by the shell to write its
> errors.
> + *
> + * @param err The {@link OutputStream} used by the shell to write its
> errors
> + */
> + void setErrorStream(OutputStream err);
> +
> + /**
> + * Set the callback that the shell has to call when it is closed.
> + *
> + * @param callback The {@link ExitCallback} to call when shell is
> closed
> + */
> + void setExitCallback(ExitCallback callback);
> +}
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/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
> new file mode 100644
> index 0000000..aff407b
> --- /dev/null
> +++ b/sshd-core/src/main/java/org/apache/sshd/server/command/
> CommandFactory.java
> @@ -0,0 +1,41 @@
> +/*
> + * 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 org.apache.sshd.common.NamedResource;
> +
> +/**
> + * A factory of commands.
> + * Commands are executed on the server side when an "exec" channel is
> + * requested by the SSH client.
> + *
> + * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD
> Project</a>
> + */
> +public interface CommandFactory extends NamedResource {
> +
> + /**
> + * Create a command with the given name.
> + * If the command is not known, a dummy command should be returned to
> allow
> + * the display output to be sent back to the client.
> + *
> + * @param command The command that will be run
> + * @return a non {@code null} {@link Command} instance
> + */
> + Command createCommand(String command);
> +}
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/
> command/CommandLifecycle.java
> ----------------------------------------------------------------------
> diff --git a/sshd-core/src/main/java/org/apache/sshd/server/command/CommandLifecycle.java
> b/sshd-core/src/main/java/org/apache/sshd/server/command/
> CommandLifecycle.java
> new file mode 100644
> index 0000000..ac694d5
> --- /dev/null
> +++ b/sshd-core/src/main/java/org/apache/sshd/server/command/
> CommandLifecycle.java
> @@ -0,0 +1,50 @@
> +/*
> + * 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 org.apache.sshd.server.Environment;
> +
> +/**
> + * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD
> Project</a>
> + */
> +public interface CommandLifecycle {
> + /**
> + * Starts the command execution. All streams must have been set
> <U>before</U>
> + * calling this method. The command should implement {@link
> java.lang.Runnable},
> + * and this method should spawn a new thread like:
> + * <pre>
> + * {@code Thread(this).start(); }
> + * </pre>
> + *
> + * @param env The {@link Environment}
> + * @throws IOException If failed to start
> + */
> + void start(Environment env) throws IOException;
> +
> + /**
> + * This method is called by the SSH server to destroy the command
> because
> + * the client has disconnected somehow.
> + *
> + * @throws Exception if failed to destroy
> + */
> + void destroy() throws Exception;
> +}
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/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
> new file mode 100644
> index 0000000..e1ce89c
> --- /dev/null
> +++ b/sshd-core/src/main/java/org/apache/sshd/server/command/
> DelegatingCommandFactory.java
> @@ -0,0 +1,43 @@
> +/*
> + * 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/
> f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/
> shell/InvertedShell.java
> ----------------------------------------------------------------------
> diff --git a/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShell.java
> b/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShell.java
> index 3d7de3c..3abc523 100644
> --- a/sshd-core/src/main/java/org/apache/sshd/server/shell/
> InvertedShell.java
> +++ b/sshd-core/src/main/java/org/apache/sshd/server/shell/
> InvertedShell.java
> @@ -21,8 +21,8 @@ package org.apache.sshd.server.shell;
> import java.io.InputStream;
> import java.io.OutputStream;
>
> -import org.apache.sshd.server.CommandLifecycle;
> import org.apache.sshd.server.SessionAware;
> +import org.apache.sshd.server.command.CommandLifecycle;
>
> /**
> * This shell have inverted streams, such as the one obtained when
> launching a
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/
> shell/InvertedShellWrapper.java
> ----------------------------------------------------------------------
> diff --git a/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShellWrapper.java
> b/sshd-core/src/main/java/org/apache/sshd/server/shell/
> InvertedShellWrapper.java
> index 4819064..3c19e2c 100644
> --- a/sshd-core/src/main/java/org/apache/sshd/server/shell/
> InvertedShellWrapper.java
> +++ b/sshd-core/src/main/java/org/apache/sshd/server/shell/
> InvertedShellWrapper.java
> @@ -31,10 +31,10 @@ import org.apache.sshd.common.util.ValidateUtils;
> import org.apache.sshd.common.util.io.IoUtils;
> import org.apache.sshd.common.util.logging.AbstractLoggingBean;
> import org.apache.sshd.common.util.threads.ThreadUtils;
> -import org.apache.sshd.server.Command;
> 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.session.ServerSession;
>
> /**
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/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
> new file mode 100644
> index 0000000..af9af82
> --- /dev/null
> +++ b/sshd-core/src/main/java/org/apache/sshd/server/shell/
> ProcessShellCommandFactory.java
> @@ -0,0 +1,50 @@
> +/*
> + * 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.shell;
> +
> +import org.apache.sshd.common.Factory;
> +import org.apache.sshd.common.util.GenericUtils;
> +import org.apache.sshd.server.command.Command;
> +import org.apache.sshd.server.command.CommandFactory;
> +
> +/**
> + * Executes commands by invoking the underlying shell
> + *
> + * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD
> Project</a>
> + */
> +public class ProcessShellCommandFactory implements CommandFactory {
> + public static final String FACTORY_NAME = "shell-command";
> + public static final ProcessShellCommandFactory INSTANCE = new
> ProcessShellCommandFactory();
> +
> + public ProcessShellCommandFactory() {
> + super();
> + }
> +
> + @Override
> + public String getName() {
> + return FACTORY_NAME;
> + }
> +
> + @Override
> + public Command createCommand(String command) {
> + Factory<Command> factory = new ProcessShellFactory(GenericUtils.split(command,
> ' '));
> + return factory.create();
> + }
> +}
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/
> shell/ProcessShellFactory.java
> ----------------------------------------------------------------------
> diff --git a/sshd-core/src/main/java/org/apache/sshd/server/shell/ProcessShellFactory.java
> b/sshd-core/src/main/java/org/apache/sshd/server/shell/
> ProcessShellFactory.java
> index 3398e63..529b701 100644
> --- a/sshd-core/src/main/java/org/apache/sshd/server/shell/
> ProcessShellFactory.java
> +++ b/sshd-core/src/main/java/org/apache/sshd/server/shell/
> ProcessShellFactory.java
> @@ -27,7 +27,7 @@ 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.logging.AbstractLoggingBean;
> -import org.apache.sshd.server.Command;
> +import org.apache.sshd.server.command.Command;
>
> /**
> * A {@link Factory} of {@link Command} that will create a new process
> and bridge
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/
> shell/ShellFactory.java
> ----------------------------------------------------------------------
> diff --git a/sshd-core/src/main/java/org/apache/sshd/server/shell/ShellFactory.java
> b/sshd-core/src/main/java/org/apache/sshd/server/shell/ShellFactory.java
> index 0a80f67..d403d42 100644
> --- a/sshd-core/src/main/java/org/apache/sshd/server/shell/
> ShellFactory.java
> +++ b/sshd-core/src/main/java/org/apache/sshd/server/shell/
> ShellFactory.java
> @@ -20,7 +20,7 @@
> package org.apache.sshd.server.shell;
>
> import org.apache.sshd.common.Factory;
> -import org.apache.sshd.server.Command;
> +import org.apache.sshd.server.command.Command;
>
> /**
> * Useful marker interface
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/
> shell/UnknownCommand.java
> ----------------------------------------------------------------------
> diff --git a/sshd-core/src/main/java/org/apache/sshd/server/shell/UnknownCommand.java
> b/sshd-core/src/main/java/org/apache/sshd/server/shell/UnknownCommand.java
> index 59d970c..43b9b9f 100644
> --- a/sshd-core/src/main/java/org/apache/sshd/server/shell/
> UnknownCommand.java
> +++ b/sshd-core/src/main/java/org/apache/sshd/server/shell/
> UnknownCommand.java
> @@ -25,9 +25,9 @@ import java.nio.charset.StandardCharsets;
> import java.util.Objects;
>
> import org.apache.sshd.common.util.ValidateUtils;
> -import org.apache.sshd.server.Command;
> import org.apache.sshd.server.Environment;
> import org.apache.sshd.server.ExitCallback;
> +import org.apache.sshd.server.command.Command;
>
> /**
> * Implementation of an unknown command that can be returned by
> <code>CommandFactory</code>
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/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 871ca60..ea94525 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
> @@ -19,13 +19,15 @@
>
> package org.apache.sshd.server.shell;
>
> -import org.apache.sshd.server.Command;
> -import org.apache.sshd.server.CommandFactory;
> +import org.apache.sshd.server.command.Command;
> +import org.apache.sshd.server.command.CommandFactory;
>
> /**
> * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD
> Project</a>
> */
> public class UnknownCommandFactory implements CommandFactory {
> + public static final String FACTORY_NAME = "unknown";
> +
> public static final UnknownCommandFactory INSTANCE = new
> UnknownCommandFactory();
>
> public UnknownCommandFactory() {
> @@ -33,6 +35,11 @@ public class UnknownCommandFactory implements
> CommandFactory {
> }
>
> @Override
> + public String getName() {
> + return FACTORY_NAME;
> + }
> +
> + @Override
> public Command createCommand(String command) {
> return new UnknownCommand(command);
> }
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/sshd-core/src/main/java/org/apache/sshd/server/
> subsystem/SubsystemFactory.java
> ----------------------------------------------------------------------
> diff --git a/sshd-core/src/main/java/org/apache/sshd/server/subsystem/SubsystemFactory.java
> b/sshd-core/src/main/java/org/apache/sshd/server/subsystem/
> SubsystemFactory.java
> index f9dbf0f..8b0cc3f 100644
> --- a/sshd-core/src/main/java/org/apache/sshd/server/subsystem/
> SubsystemFactory.java
> +++ b/sshd-core/src/main/java/org/apache/sshd/server/subsystem/
> SubsystemFactory.java
> @@ -20,7 +20,7 @@
> package org.apache.sshd.server.subsystem;
>
> import org.apache.sshd.common.NamedFactory;
> -import org.apache.sshd.server.Command;
> +import org.apache.sshd.server.command.Command;
>
> /**
> * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD
> Project</a>
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/sshd-core/src/test/java/org/apache/sshd/KeepAliveTest.java
> ----------------------------------------------------------------------
> diff --git a/sshd-core/src/test/java/org/apache/sshd/KeepAliveTest.java
> b/sshd-core/src/test/java/org/apache/sshd/KeepAliveTest.java
> index dd649e5..4e09447 100644
> --- a/sshd-core/src/test/java/org/apache/sshd/KeepAliveTest.java
> +++ b/sshd-core/src/test/java/org/apache/sshd/KeepAliveTest.java
> @@ -32,8 +32,8 @@ import org.apache.sshd.client.session.ClientSession;
> import org.apache.sshd.common.FactoryManager;
> import org.apache.sshd.common.PropertyResolverUtils;
> import org.apache.sshd.common.channel.Channel;
> -import org.apache.sshd.server.Command;
> import org.apache.sshd.server.SshServer;
> +import org.apache.sshd.server.command.Command;
> import org.apache.sshd.util.test.BaseTestSupport;
> import org.apache.sshd.util.test.EchoShell;
> import org.apache.sshd.util.test.EchoShellFactory;
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/sshd-core/src/test/java/org/apache/sshd/KeyReExchangeTest.java
> ----------------------------------------------------------------------
> diff --git a/sshd-core/src/test/java/org/apache/sshd/KeyReExchangeTest.java
> b/sshd-core/src/test/java/org/apache/sshd/KeyReExchangeTest.java
> index f2ca9df..4fdb932 100644
> --- a/sshd-core/src/test/java/org/apache/sshd/KeyReExchangeTest.java
> +++ b/sshd-core/src/test/java/org/apache/sshd/KeyReExchangeTest.java
> @@ -55,10 +55,10 @@ import org.apache.sshd.common.session.Session;
> import org.apache.sshd.common.session.SessionListener;
> import org.apache.sshd.common.util.io.NullOutputStream;
> import org.apache.sshd.common.util.security.SecurityUtils;
> -import org.apache.sshd.server.Command;
> import org.apache.sshd.server.Environment;
> import org.apache.sshd.server.ExitCallback;
> import org.apache.sshd.server.SshServer;
> +import org.apache.sshd.server.command.Command;
> import org.apache.sshd.server.subsystem.SubsystemFactory;
> import org.apache.sshd.util.test.BaseTestSupport;
> import org.apache.sshd.util.test.JSchLogger;
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/sshd-core/src/test/java/org/apache/sshd/WindowAdjustTest.java
> ----------------------------------------------------------------------
> diff --git a/sshd-core/src/test/java/org/apache/sshd/WindowAdjustTest.java
> b/sshd-core/src/test/java/org/apache/sshd/WindowAdjustTest.java
> index cac8e32..fd1fd84 100644
> --- a/sshd-core/src/test/java/org/apache/sshd/WindowAdjustTest.java
> +++ b/sshd-core/src/test/java/org/apache/sshd/WindowAdjustTest.java
> @@ -45,10 +45,10 @@ import org.apache.sshd.common.util.
> buffer.ByteArrayBuffer;
> import org.apache.sshd.common.util.io.NoCloseOutputStream;
> import org.apache.sshd.common.util.logging.AbstractLoggingBean;
> import org.apache.sshd.common.util.threads.ThreadUtils;
> -import org.apache.sshd.server.AsyncCommand;
> import org.apache.sshd.server.Environment;
> import org.apache.sshd.server.ExitCallback;
> import org.apache.sshd.server.SshServer;
> +import org.apache.sshd.server.command.AsyncCommand;
> import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
> import org.apache.sshd.util.test.BaseTestSupport;
> import org.junit.After;
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/sshd-core/src/test/java/org/apache/sshd/agent/AgentTest.java
> ----------------------------------------------------------------------
> diff --git a/sshd-core/src/test/java/org/apache/sshd/agent/AgentTest.java
> b/sshd-core/src/test/java/org/apache/sshd/agent/AgentTest.java
> index f252be7..7deebfc 100644
> --- a/sshd-core/src/test/java/org/apache/sshd/agent/AgentTest.java
> +++ b/sshd-core/src/test/java/org/apache/sshd/agent/AgentTest.java
> @@ -38,9 +38,9 @@ import org.apache.sshd.client.channel.ChannelShell;
> import org.apache.sshd.client.session.ClientSession;
> import org.apache.sshd.common.keyprovider.KeyPairProvider;
> import org.apache.sshd.common.util.security.SecurityUtils;
> -import org.apache.sshd.server.Command;
> import org.apache.sshd.server.Environment;
> import org.apache.sshd.server.SshServer;
> +import org.apache.sshd.server.command.Command;
> import org.apache.sshd.server.forward.AcceptAllForwardingFilter;
> import org.apache.sshd.util.test.BaseTestSupport;
> import org.apache.sshd.util.test.EchoShell;
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/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 f3d94a8..0026cc3 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
> @@ -95,13 +95,13 @@ import org.apache.sshd.common.util.buffer.Buffer;
> import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
> import org.apache.sshd.common.util.io.NoCloseOutputStream;
> import org.apache.sshd.common.util.net.SshdSocketAddress;
> -import org.apache.sshd.server.Command;
> import org.apache.sshd.server.SshServer;
> import org.apache.sshd.server.auth.keyboard.
> DefaultKeyboardInteractiveAuthenticator;
> import org.apache.sshd.server.auth.keyboard.
> KeyboardInteractiveAuthenticator;
> import org.apache.sshd.server.auth.password.
> RejectAllPasswordAuthenticator;
> import org.apache.sshd.server.channel.ChannelSession;
> import org.apache.sshd.server.channel.ChannelSessionFactory;
> +import org.apache.sshd.server.command.Command;
> import org.apache.sshd.server.forward.DirectTcpipFactory;
> import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
> import org.apache.sshd.server.session.ServerConnectionServiceFactory;
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/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 038ce55..8a48daf 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,6 +26,8 @@ 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;
> @@ -51,13 +53,23 @@ public class ChannelExecTest extends BaseTestSupport {
> @BeforeClass
> public static void setupClientAndServer() throws Exception {
> sshd = Utils.setupTestServer(ChannelExecTest.class);
> - sshd.setCommandFactory(command -> new CommandExecutionHelper(command)
> {
> + sshd.setCommandFactory(new CommandFactory() {
> @Override
> - protected boolean handleCommandLine(String command) throws
> Exception {
> - OutputStream stdout = getOutputStream();
> - stdout.write(command.getBytes(
> StandardCharsets.US_ASCII));
> - stdout.flush();
> - return false;
> + 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;
> + }
> + };
> }
> });
> sshd.start();
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/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 aeb5e3b..517b07c 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
> @@ -26,9 +26,9 @@ import java.rmi.ServerException;
> import java.util.concurrent.TimeUnit;
>
> import org.apache.sshd.client.SshClient;
> -import org.apache.sshd.server.Command;
> -import org.apache.sshd.server.CommandFactory;
> 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,18 +84,28 @@ public class ClientSessionTest extends BaseTestSupport
> {
> public void testDefaultExecuteCommandMethod() throws Exception {
> final String expectedCommand = getCurrentTestName() + "-CMD";
> final String expectedResponse = getCurrentTestName() + "-RSP";
> - sshd.setCommandFactory(command -> new CommandExecutionHelper(command)
> {
> - private boolean cmdProcessed;
> + sshd.setCommandFactory(new CommandFactory() {
> + @Override
> + public String getName() {
> + return getCurrentTestName();
> + }
>
> @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;
> + 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;
> + }
> + };
> }
> });
>
> @@ -113,18 +123,28 @@ public class ClientSessionTest extends
> BaseTestSupport {
> public void testExceptionThrownIfRemoteStderrWrittenTo() throws
> Exception {
> final String expectedCommand = getCurrentTestName() + "-CMD";
> final String expectedErrorMessage = getCurrentTestName() + "-ERR";
> - sshd.setCommandFactory(command -> new CommandExecutionHelper(command)
> {
> - private boolean cmdProcessed;
> + sshd.setCommandFactory(new CommandFactory() {
> + @Override
> + public String getName() {
> + return getCurrentTestName();
> + }
>
> @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;
> + 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;
> + }
> + };
> }
> });
>
> @@ -158,6 +178,11 @@ public class ClientSessionTest extends
> BaseTestSupport {
> final int exepectedErrorCode = 7365;
> sshd.setCommandFactory(new CommandFactory() {
> @Override
> + public String getName() {
> + return getCurrentTestName();
> + }
> +
> + @Override
> public Command createCommand(String command) {
> return new CommandExecutionHelper(command) {
> private boolean cmdProcessed;
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/sshd-core/src/test/java/org/apache/sshd/common/
> channel/WindowTest.java
> ----------------------------------------------------------------------
> diff --git a/sshd-core/src/test/java/org/apache/sshd/common/channel/WindowTest.java
> b/sshd-core/src/test/java/org/apache/sshd/common/channel/WindowTest.java
> index 93c37be..864fc23 100644
> --- a/sshd-core/src/test/java/org/apache/sshd/common/channel/
> WindowTest.java
> +++ b/sshd-core/src/test/java/org/apache/sshd/common/channel/
> WindowTest.java
> @@ -45,10 +45,10 @@ import org.apache.sshd.common.io.IoReadFuture;
> import org.apache.sshd.common.session.Session;
> import org.apache.sshd.common.util.buffer.Buffer;
> import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
> -import org.apache.sshd.server.Command;
> import org.apache.sshd.server.SshServer;
> import org.apache.sshd.server.channel.ChannelSession;
> import org.apache.sshd.server.channel.ChannelSessionFactory;
> +import org.apache.sshd.server.command.Command;
> import org.apache.sshd.server.forward.DirectTcpipFactory;
> import org.apache.sshd.server.session.ServerConnectionService;
> import org.apache.sshd.server.session.ServerConnectionServiceFactory;
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/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 8c083a3..d1955ef 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
> @@ -72,6 +72,8 @@ import org.apache.sshd.server.auth.keyboard.
> KeyboardInteractiveAuthenticator;
> import org.apache.sshd.server.auth.keyboard.PromptEntry;
> import org.apache.sshd.server.auth.password.
> RejectAllPasswordAuthenticator;
> import org.apache.sshd.server.auth.pubkey.RejectAllPublickeyAuthenticato
> r;
> +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;
> @@ -522,43 +524,51 @@ public class ServerTest extends BaseTestSupport {
> @Test // see SSHD-645
> public void testChannelStateChangeNotifications() throws Exception {
> final Semaphore exitSignal = new Semaphore(0);
> - sshd.setCommandFactory(command -> {
> - ValidateUtils.checkTrue(String.CASE_INSENSITIVE_ORDER.compare(command,
> getCurrentTestName()) == 0, "Unexpected command: %s", command);
> + sshd.setCommandFactory(new CommandFactory() {
> + @Override
> + public String getName() {
> + return getCurrentTestName();
> + }
>
> - return new Command() {
> - private ExitCallback cb;
> + @Override
> + public Command createCommand(String command) {
> + ValidateUtils.checkTrue(String.CASE_INSENSITIVE_ORDER.compare(command,
> getCurrentTestName()) == 0, "Unexpected command: %s", command);
>
> - @Override
> - public void setOutputStream(OutputStream out) {
> - // ignored
> - }
> + return new Command() {
> + private ExitCallback cb;
>
> - @Override
> - public void setInputStream(InputStream in) {
> - // ignored
> - }
> + @Override
> + public void setOutputStream(OutputStream out) {
> + // ignored
> + }
>
> - @Override
> - public void setExitCallback(ExitCallback callback) {
> - cb = callback;
> - }
> + @Override
> + public void setInputStream(InputStream in) {
> + // ignored
> + }
>
> - @Override
> - public void setErrorStream(OutputStream err) {
> - // ignored
> - }
> + @Override
> + public void setExitCallback(ExitCallback callback) {
> + cb = callback;
> + }
>
> - @Override
> - public void destroy() {
> - // ignored
> - }
> + @Override
> + public void setErrorStream(OutputStream err) {
> + // ignored
> + }
>
> - @Override
> - public void start(Environment env) throws IOException {
> - exitSignal.release();
> - cb.onExit(0, command);
> - }
> - };
> + @Override
> + public void destroy() {
> + // ignored
> + }
> +
> + @Override
> + public void start(Environment env) throws IOException
> {
> + exitSignal.release();
> + cb.onExit(0, command);
> + }
> + };
> + }
> });
> sshd.start();
> client.start();
> @@ -595,46 +605,54 @@ public class ServerTest extends BaseTestSupport {
> @Test
> public void testEnvironmentVariablesPropagationToServer() throws
> Exception {
> final AtomicReference<Environment> envHolder = new
> AtomicReference<>(null);
> - sshd.setCommandFactory(command -> {
> - ValidateUtils.checkTrue(String.CASE_INSENSITIVE_ORDER.compare(command,
> getCurrentTestName()) == 0, "Unexpected command: %s", command);
> + sshd.setCommandFactory(new CommandFactory() {
> + @Override
> + public String getName() {
> + return getCurrentTestName();
> + }
>
> - return new Command() {
> - private ExitCallback cb;
> + @Override
> + public Command createCommand(String command) {
> + ValidateUtils.checkTrue(String.CASE_INSENSITIVE_ORDER.compare(command,
> getCurrentTestName()) == 0, "Unexpected command: %s", command);
>
> - @Override
> - public void setOutputStream(OutputStream out) {
> - // ignored
> - }
> + return new Command() {
> + private ExitCallback cb;
>
> - @Override
> - public void setInputStream(InputStream in) {
> - // ignored
> - }
> + @Override
> + public void setOutputStream(OutputStream out) {
> + // ignored
> + }
>
> - @Override
> - public void setExitCallback(ExitCallback callback) {
> - cb = callback;
> - }
> + @Override
> + public void setInputStream(InputStream in) {
> + // ignored
> + }
>
> - @Override
> - public void setErrorStream(OutputStream err) {
> - // ignored
> - }
> + @Override
> + public void setExitCallback(ExitCallback callback) {
> + cb = callback;
> + }
>
> - @Override
> - public void destroy() {
> - // ignored
> - }
> + @Override
> + public void setErrorStream(OutputStream err) {
> + // 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 destroy() {
> + // ignored
> }
>
> - cb.onExit(0, 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);
> + }
> + };
> + }
> });
>
> TestChannelListener channelListener = new TestChannelListener(
> getCurrentTestName());
> @@ -934,6 +952,15 @@ public class ServerTest extends BaseTestSupport {
> // 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);
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/sshd-core/src/test/java/org/apache/sshd/util/
> test/AsyncEchoShellFactory.java
> ----------------------------------------------------------------------
> diff --git a/sshd-core/src/test/java/org/apache/sshd/util/test/AsyncEchoShellFactory.java
> b/sshd-core/src/test/java/org/apache/sshd/util/test/
> AsyncEchoShellFactory.java
> index 5193cec..de9dbf4 100644
> --- a/sshd-core/src/test/java/org/apache/sshd/util/test/
> AsyncEchoShellFactory.java
> +++ b/sshd-core/src/test/java/org/apache/sshd/util/test/
> AsyncEchoShellFactory.java
> @@ -29,13 +29,13 @@ import org.apache.sshd.common.io.IoInputStream;
> import org.apache.sshd.common.io.IoOutputStream;
> import org.apache.sshd.common.session.Session;
> import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
> -import org.apache.sshd.server.AsyncCommand;
> import org.apache.sshd.server.ChannelSessionAware;
> -import org.apache.sshd.server.Command;
> import org.apache.sshd.server.Environment;
> import org.apache.sshd.server.ExitCallback;
> import org.apache.sshd.server.channel.ChannelDataReceiver;
> import org.apache.sshd.server.channel.ChannelSession;
> +import org.apache.sshd.server.command.AsyncCommand;
> +import org.apache.sshd.server.command.Command;
> import org.apache.sshd.server.shell.ShellFactory;
>
> /**
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/sshd-core/src/test/java/org/apache/sshd/util/
> test/CommandExecutionHelper.java
> ----------------------------------------------------------------------
> diff --git a/sshd-core/src/test/java/org/apache/sshd/util/test/CommandExecutionHelper.java
> b/sshd-core/src/test/java/org/apache/sshd/util/test/
> CommandExecutionHelper.java
> index c44a2ad..c199a38 100644
> --- a/sshd-core/src/test/java/org/apache/sshd/util/test/
> CommandExecutionHelper.java
> +++ b/sshd-core/src/test/java/org/apache/sshd/util/test/
> CommandExecutionHelper.java
> @@ -26,7 +26,7 @@ import java.io.InterruptedIOException;
> import java.io.OutputStream;
> import java.nio.charset.StandardCharsets;
>
> -import org.apache.sshd.server.AbstractCommandSupport;
> +import org.apache.sshd.server.command.AbstractCommandSupport;
>
> /**
> * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD
> Project</a>
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/sshd-core/src/test/java/org/apache/sshd/util/
> test/EchoShellFactory.java
> ----------------------------------------------------------------------
> diff --git a/sshd-core/src/test/java/org/apache/sshd/util/test/EchoShellFactory.java
> b/sshd-core/src/test/java/org/apache/sshd/util/test/EchoShellFactory.java
> index fe97a2f..a9ec9d3 100644
> --- a/sshd-core/src/test/java/org/apache/sshd/util/test/
> EchoShellFactory.java
> +++ b/sshd-core/src/test/java/org/apache/sshd/util/test/
> EchoShellFactory.java
> @@ -18,7 +18,7 @@
> */
> package org.apache.sshd.util.test;
>
> -import org.apache.sshd.server.Command;
> +import org.apache.sshd.server.command.Command;
> import org.apache.sshd.server.shell.ShellFactory;
>
> /**
>
> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/
> f1a8077b/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 d4dacfa..7315610 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
> @@ -29,8 +29,8 @@ import java.util.concurrent.ExecutorService;
>
> import org.apache.sshd.common.channel.ChannelOutputStream;
> import org.apache.sshd.common.file.FileSystemAware;
> -import org.apache.sshd.server.AbstractCommandSupport;
> 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;
>
>
>
--
------------------------
Guillaume Nodet