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 <lgoldst...@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 <l...@c-b4.com> > Authored: Tue May 15 10:41:24 2018 +0300 > Committer: Goldstein Lyor <l...@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