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/04/25 05:01:29 UTC
[8/8] mina-sshd git commit: [SSHD-818] Split SCP code (client +
server) to its own module
[SSHD-818] Split SCP code (client + server) to its own module
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/af415e5f
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/af415e5f
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/af415e5f
Branch: refs/heads/master
Commit: af415e5fec5fadf1c397371313cec20d3b4428f4
Parents: cb8982a
Author: Goldstein Lyor <ly...@c-b4.com>
Authored: Mon Apr 23 16:32:34 2018 +0300
Committer: Goldstein Lyor <ly...@c-b4.com>
Committed: Wed Apr 25 08:01:09 2018 +0300
----------------------------------------------------------------------
README.md | 146 ++-
assembly/pom.xml | 5 +
pom.xml | 1 +
sshd-cli/pom.xml | 5 +
.../apache/sshd/cli/client/ScpCommandMain.java | 57 +-
.../apache/sshd/cli/server/SshServerMain.java | 1 -
sshd-contrib/pom.xml | 5 +
...SimpleAccessControlScpEventListenerTest.java | 4 +-
.../sshd/client/ClientFactoryManager.java | 2 -
.../java/org/apache/sshd/client/SshClient.java | 12 -
.../sshd/client/scp/AbstractScpClient.java | 278 ----
.../sshd/client/scp/CloseableScpClient.java | 32 -
.../sshd/client/scp/DefaultScpClient.java | 159 ---
.../client/scp/DefaultScpStreamResolver.java | 88 --
.../org/apache/sshd/client/scp/ScpClient.java | 174 ---
.../sshd/client/scp/ScpClientCreator.java | 97 --
.../client/session/AbstractClientSession.java | 31 -
.../sshd/client/session/ClientSession.java | 6 +-
.../client/simple/AbstractSimpleClient.java | 106 --
.../apache/sshd/client/simple/SimpleClient.java | 1 -
.../sshd/client/simple/SimpleScpClient.java | 159 ---
...AbstractScpTransferEventListenerAdapter.java | 74 --
.../apache/sshd/common/scp/ScpException.java | 56 -
.../apache/sshd/common/scp/ScpFileOpener.java | 284 -----
.../sshd/common/scp/ScpFileOpenerHolder.java | 37 -
.../org/apache/sshd/common/scp/ScpHelper.java | 837 ------------
.../org/apache/sshd/common/scp/ScpLocation.java | 227 ----
.../sshd/common/scp/ScpReceiveLineHandler.java | 36 -
.../common/scp/ScpSourceStreamResolver.java | 73 --
.../common/scp/ScpTargetStreamResolver.java | 67 -
.../apache/sshd/common/scp/ScpTimestamp.java | 69 -
.../common/scp/ScpTransferEventListener.java | 105 --
.../scp/helpers/DefaultScpFileOpener.java | 75 --
.../LocalFileScpSourceStreamResolver.java | 97 --
.../LocalFileScpTargetStreamResolver.java | 159 ---
.../common/util/io/functors/IOFunction.java | 86 ++
.../org/apache/sshd/server/scp/ScpCommand.java | 350 -----
.../sshd/server/scp/ScpCommandFactory.java | 272 ----
.../apache/sshd/server/scp/UnknownCommand.java | 138 --
.../sshd/server/shell/UnknownCommand.java | 138 ++
.../server/shell/UnknownCommandFactory.java | 39 +
.../org/apache/sshd/client/scp/ScpTest.java | 1197 -----------------
.../simple/BaseSimpleClientTestSupport.java | 70 -
.../sshd/client/simple/SimpleScpClientTest.java | 119 --
.../client/simple/SimpleSessionClientTest.java | 1 +
.../server/command/ScpCommandFactoryTest.java | 114 --
.../sshd/util/test/UnknownCommandFactory.java | 40 -
.../java/org/apache/sshd/util/test/Utils.java | 1 +
.../simple/BaseSimpleClientTestSupport.java | 71 ++
.../sshd/git/AbstractGitCommandFactory.java | 2 +-
sshd-scp/pom.xml | 201 +++
.../sshd/client/scp/AbstractScpClient.java | 278 ++++
.../client/scp/AbstractScpClientCreator.java | 63 +
.../sshd/client/scp/CloseableScpClient.java | 32 +
.../sshd/client/scp/DefaultScpClient.java | 159 +++
.../client/scp/DefaultScpClientCreator.java | 42 +
.../client/scp/DefaultScpStreamResolver.java | 88 ++
.../org/apache/sshd/client/scp/ScpClient.java | 174 +++
.../sshd/client/scp/ScpClientCreator.java | 106 ++
.../apache/sshd/client/scp/SimpleScpClient.java | 178 +++
.../sshd/client/scp/SimpleScpClientImpl.java | 153 +++
...AbstractScpTransferEventListenerAdapter.java | 74 ++
.../apache/sshd/common/scp/ScpException.java | 56 +
.../apache/sshd/common/scp/ScpFileOpener.java | 284 +++++
.../sshd/common/scp/ScpFileOpenerHolder.java | 37 +
.../org/apache/sshd/common/scp/ScpHelper.java | 837 ++++++++++++
.../org/apache/sshd/common/scp/ScpLocation.java | 227 ++++
.../sshd/common/scp/ScpReceiveLineHandler.java | 36 +
.../common/scp/ScpSourceStreamResolver.java | 73 ++
.../common/scp/ScpTargetStreamResolver.java | 67 +
.../apache/sshd/common/scp/ScpTimestamp.java | 69 +
.../common/scp/ScpTransferEventListener.java | 105 ++
.../scp/helpers/DefaultScpFileOpener.java | 75 ++
.../LocalFileScpSourceStreamResolver.java | 97 ++
.../LocalFileScpTargetStreamResolver.java | 159 +++
.../org/apache/sshd/server/scp/ScpCommand.java | 350 +++++
.../sshd/server/scp/ScpCommandFactory.java | 272 ++++
.../org/apache/sshd/client/scp/ScpTest.java | 1203 ++++++++++++++++++
.../sshd/client/scp/SimpleScpClientTest.java | 121 ++
.../sshd/server/scp/ScpCommandFactoryTest.java | 113 ++
.../sshd/client/simple/SimpleSftpClient.java | 179 ---
.../client/simple/SimpleSftpClientImpl.java | 171 ---
.../client/subsystem/sftp/SimpleSftpClient.java | 179 +++
.../sftp/impl/SimpleSftpClientImpl.java | 192 +++
.../java/org/apache/sshd/client/ClientTest.java | 426 -------
.../simple/BaseSimpleClientTestSupport.java | 70 -
.../client/simple/SimpleSftpClientTest.java | 129 --
.../sftp/AbstractSftpClientTestSupport.java | 2 -
.../sshd/client/subsystem/sftp/ClientTest.java | 424 ++++++
.../subsystem/sftp/SftpFileSystemTest.java | 2 -
.../subsystem/sftp/SimpleSftpClientTest.java | 128 ++
.../sftp/ApacheSshdSftpSessionFactoryTest.java | 2 -
92 files changed, 7168 insertions(+), 6668 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/af415e5f/README.md
----------------------------------------------------------------------
diff --git a/README.md b/README.md
index f512a3f..5a1e249 100644
--- a/README.md
+++ b/README.md
@@ -533,17 +533,80 @@ it will be **closed** automatically when the stream using it is closed.
## SCP
-Besides the `ScpTransferEventListener`, the SCP module also uses a `ScpFileOpener` instance in order to access
-the local files - client or server-side. The default implementation simply opens an [InputStream](https://docs.oracle.com/javase/8/docs/api/java/io/InputStream.html)
+Both client-side and server-side SCP are supported. Starting from version 2.0, the SCP related code is located in the `sshd-scp` module, so you need
+to add this additional dependency to your maven project:
+
+```xml
+
+ <dependency>
+ <groupId>org.apache.sshd</groupId>
+ <artifactId>sshd-sscp</artifactId>
+ <version>...same as sshd-core...</version>
+ </dependency>
+
+```
+
+### Client-side SCP
+
+In order to obtain an `ScpClient` one needs to use an `ScpClientCreator`:
+
+```java
+
+ClientSession session = ... obtain an instance ...
+ScpClientCreator creator = ... obtain an instance ...
+ScpClient client = creator.createScpClient(session);
+
+```
+
+A default `ScpClientCreator` instance is provided as part of the module - see `ScpClientCreator.instance()`
+
+#### ScpFileOpener(s)
+
+As part of the `ScpClientCreator`, the SCP module also uses a `ScpFileOpener` instance in order to access
+the local files. The default implementation simply opens an [InputStream](https://docs.oracle.com/javase/8/docs/api/java/io/InputStream.html)
or [OutputStream](https://docs.oracle.com/javase/8/docs/api/java/io/OutputStream.html) on the requested local path. However,
-the user may replace it and intercept the calls - e.g., for logging, for wrapping/filtering the streams, etc... **Note:**
-due to SCP protocol limitations one cannot change the **size** of the input/output since it is passed as part of the command
+the user may replace it and intercept the calls - e.g., for logging, for wrapping/filtering the streams, etc... The user may
+attach a default opener that will be automatically attached to **all** clients created unless specifically overridden:
+
+```java
+
+ClientSession session = ... obtain an instance ...
+ScpClientCreator creator = ... obtain an instance ...
+creator.setScpFileOpener(new MySuperDuperOpener());
+
+ScpClient client1 = creator.createScpClient(session); // <<== automatically uses MySuperDuperOpener
+ScpClient client2 = creator.createScpClient(session, new SomeOtherOpener()); // <<== uses SomeOtherOpener instead of MySuperDuperOpener
+
+```
+
+**Note:** due to SCP protocol limitations one cannot change the **size** of the input/output since it is passed as part of the command
**before** the file opener is invoked - so there are a few limitations on what one can do within this interface implementation.
+#### ScpTransferEventListener(s)
+
+The `ScpClientCreator` can also be used to attach a default `ScpTransferEventListener` that will be attached to
+**all** created SCP client instances through that creator - unless specifically overridden:
+
+```java
+
+ClientSession session = ... obtain an instance ...
+ScpClientCreator creator = ... obtain an instance ...
+creator.setScpTransferEventListener(new MySuperDuperListener());
+
+ScpClient client1 = creator.createScpClient(session); // <<== automatically uses MySuperDuperListener
+ScpClient client2 = creator.createScpClient(session, new SomeOtherListener()); // <<== uses SomeOtherListener instead of MySuperDuperListener
+
+```
+
+### Server-side SCP
+
+The `ScpCommandFactory` allows users to attach an `ScpFileOpener` and/or `ScpTransferEventListener` having the same behavior as the client - i.e.,
+monitoring and intervention on the accessed local files.
## SFTP
-Both client-side and server-side SFTP are supported. Starting from SSHD 1.8.0, the SFTP related code is located in the `sshd-sftp`, so you need to add this additional dependency to your maven project:
+Both client-side and server-side SFTP are supported. Starting from version 2.0, the SFTP related code is located in the `sshd-sftp`, so you need to add
+this additional dependency to your maven project:
```xml
@@ -567,19 +630,48 @@ On the server side, the following code needs to be added:
```
+### `SftpEventListener`
+
+(See above more details...) - users may register an `SftpEventListener` (or more...) in the `SftpSubsystemFactory` in
+order to monitor and even intervene in the susbsytem's functionality.
+
### Client-side SFTP
+In order to obtain an `SftpClient` instance one needs to use an `SftpClientFactory`:
+
+
```java
- SftpClient client = SftpClientFactory.instance().createSftpClient(session);
+ ClientSession session = ...obtain session...
+ SftpClientFactory factory = ...obtain factory...
+ SftpClient client = factory.createSftpClient(session);
```
-### `SftpEventListener`
+A default client factory implementations is provided in the module - see `SftpClientFactory.instance()`
+
+
+### Using a custom `SftpClientFactory`
+
+The code creates `SftpClient`-s and `SftpFileSystem`-s using a default built-in `SftpClientFactory` instance (see
+`DefaultSftpClientFactory`). Users may choose to use a custom factory in order to provide their own
+implementations - e.g., in order to override some default behavior - e.g.:
+
+```java
+
+ SshClient client = ... setup client...
+
+ try (ClientSession session = client.connect(user, host, port).verify(timeout).getSession()) {
+ session.addPasswordIdentity(password);
+ session.auth.verify(timeout);
-See above...
-In addition to the `SftpEventListener` there are a few more SFTP-related special interfaces and modules.
+ // User-specific factory
+ try (SftpClient sftp = MySpecialSessionSftpClientFactory.INSTANCE.createSftpClient(session)) {
+ ... instance created through SpecialSessionSftpClientFactory ...
+ }
+ }
+```
### Version selection via `SftpVersionSelector`
@@ -603,7 +695,8 @@ range.
session.addPasswordIdentity(password);
session.auth.verify(timeout);
- try (SftpClient sftp = SftpClientFactory.instance().createSftpClient(session, myVersionSelector)) {
+ SftpClientFactory factory = SftpClientFactory.instance();
+ try (SftpClient sftp = factory.createSftpClient(session, myVersionSelector)) {
... do SFTP related stuff...
}
}
@@ -615,30 +708,6 @@ the version, and all we can do at the server is require a **specific** version v
configuration key. For more advanced restrictions one needs to sub-class `SftpSubSystem` and provide a non-default
`SftpSubsystemFactory` that uses the sub-classed code.
-
-### Using a custom `SftpClientFactory`
-
-The code creates `SftpClient`-s and `SftpFileSystem`-s using a default built-in `SftpClientFactory` instance (see
-`DefaultSftpClientFactory`). Users may choose to use a custom factory in order to provide their own
-implementations - e.g., in order to override some default behavior - e.g.:
-
-```java
-
- SshClient client = ... setup client...
-
- try (ClientSession session = client.connect(user, host, port).verify(timeout).getSession()) {
- session.addPasswordIdentity(password);
- session.auth.verify(timeout);
-
- // User-specific factory
- try (SftpClient sftp = MySpecialSessionSftpClientFactory.INSTANCE.createSftpClient(session)) {
- ... instance created through SpecialSessionSftpClientFactory ...
- }
- }
-
-```
-
-
### Using `SftpFileSystemProvider` to create an `SftpFileSystem`
@@ -796,7 +865,8 @@ UTF-8 is used. **Note:** the value can be a charset name or a `java.nio.charset.
PropertyResolverUtils.updateProperty(session, SftpClient.NAME_DECODING_CHARSET, "ISO-8859-4");
session.authenticate(...);
- try (SftpClient sftp = SftpClientFactory.instance().createSftpClient(session)) {
+ SftpClientFactory factory = SftpClientFactory.instance();
+ try (SftpClient sftp = factory.createSftpClient(session)) {
for (DirEntry entry : sftp.readDir(...some path...)) {
...handle entry assuming ISO-8859-4 (inherited from the session) encoded names...
}
@@ -848,7 +918,8 @@ On the client side, all the supported extensions are classes that implement `Sft
session.addPasswordIdentity(password);
session.auth().verify(timeout);
- try (SftpClient sftp = SftpClientFactory.instance().createSftpClient(session)) {
+ SftpClientFactory factory = SftpClientFactory.instance();
+ try (SftpClient sftp = factory.createSftpClient(session)) {
Map<String, byte[]> extensions = sftp.getServerExtensions();
// Key=extension name, value=registered parser instance
Map<String, ?> data = ParserUtils.parse(extensions);
@@ -880,7 +951,8 @@ One can skip all the conditional code if a specific known extension is required:
session.addPasswordIdentity(password);
session.auth().verify(timeout);
- try (SftpClient sftp = SftpClientFactory.instance().createSftpClient(session)) {
+ SftpClientFactory factory = SftpClientFactory.instance();
+ try (SftpClient sftp = factory.createSftpClient(session)) {
// Returns null if extension is not supported by remote server
SpaceAvailableExtension space = sftp.getExtension(SpaceAvailableExtension.class);
if (space != null) {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/af415e5f/assembly/pom.xml
----------------------------------------------------------------------
diff --git a/assembly/pom.xml b/assembly/pom.xml
index 53db1ba..7b103e1 100644
--- a/assembly/pom.xml
+++ b/assembly/pom.xml
@@ -43,6 +43,11 @@
</dependency>
<dependency>
<groupId>org.apache.sshd</groupId>
+ <artifactId>sshd-scp</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sshd</groupId>
<artifactId>sshd-sftp</artifactId>
<version>${project.version}</version>
</dependency>
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/af415e5f/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index b88a195..f161f1f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1006,6 +1006,7 @@
<modules>
<module>sshd-core</module>
+ <module>sshd-scp</module>
<module>sshd-sftp</module>
<module>sshd-mina</module>
<module>sshd-netty</module>
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/af415e5f/sshd-cli/pom.xml
----------------------------------------------------------------------
diff --git a/sshd-cli/pom.xml b/sshd-cli/pom.xml
index 0f9bb98..0925da8 100644
--- a/sshd-cli/pom.xml
+++ b/sshd-cli/pom.xml
@@ -44,6 +44,11 @@
</dependency>
<dependency>
<groupId>org.apache.sshd</groupId>
+ <artifactId>sshd-scp</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sshd</groupId>
<artifactId>sshd-sftp</artifactId>
<version>${project.version}</version>
</dependency>
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/af415e5f/sshd-cli/src/main/java/org/apache/sshd/cli/client/ScpCommandMain.java
----------------------------------------------------------------------
diff --git a/sshd-cli/src/main/java/org/apache/sshd/cli/client/ScpCommandMain.java b/sshd-cli/src/main/java/org/apache/sshd/cli/client/ScpCommandMain.java
index 8a9e4a9..3f233ef 100644
--- a/sshd-cli/src/main/java/org/apache/sshd/cli/client/ScpCommandMain.java
+++ b/sshd-cli/src/main/java/org/apache/sshd/cli/client/ScpCommandMain.java
@@ -35,11 +35,13 @@ import java.util.logging.Level;
import org.apache.sshd.client.scp.ScpClient;
import org.apache.sshd.client.scp.ScpClient.Option;
+import org.apache.sshd.client.scp.ScpClientCreator;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.common.scp.ScpLocation;
import org.apache.sshd.common.scp.ScpTransferEventListener;
import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.io.NoCloseInputStream;
+import org.apache.sshd.common.util.threads.ThreadUtils;
/**
* TODO Add javadoc
@@ -70,13 +72,14 @@ public class ScpCommandMain extends SshClientCliSupport {
String argName = args[index];
// handled by 'setupClientSession'
if (isArgumentedOption(SCP_PORT_OPTION, argName)) {
- if ((index + 1) >= numArgs) {
+ index++;
+ if (index >= numArgs) {
error = showError(stderr, "option requires an argument: " + argName);
break;
}
effective.add(argName);
- effective.add(args[++index]);
+ effective.add(args[index]);
} else if ("-r".equals(argName) || "-p".equals(argName)
|| "-q".equals(argName) || "-C".equals(argName)
|| "-v".equals(argName) || "-vv".equals(argName) || "-vvv".equals(argName)) {
@@ -85,13 +88,14 @@ public class ScpCommandMain extends SshClientCliSupport {
error = showError(stderr, "Unknown option: " + argName);
break;
} else {
- if ((index + 1) >= numArgs) {
+ index++;
+ if (index >= numArgs) {
error = showError(stderr, "Not enough arguments");
break;
}
ScpLocation source = new ScpLocation(argName);
- ScpLocation target = new ScpLocation(args[++index]);
+ ScpLocation target = new ScpLocation(args[index]);
if (index < (numArgs - 1)) {
error = showError(stderr, "Unexpected extra arguments");
break;
@@ -117,6 +121,42 @@ public class ScpCommandMain extends SshClientCliSupport {
return effective.toArray(new String[effective.size()]);
}
+ public static ScpClientCreator resolveScpClientCreator(PrintStream stderr, String... args) {
+ String className = null;
+ for (int index = 0, numArgs = GenericUtils.length(args); index < numArgs; index++) {
+ String argName = args[index];
+ if ("-creator".equals(argName)) {
+ index++;
+ if (index >= numArgs) {
+ showError(stderr, "option requires an argument: " + argName);
+ return null;
+ }
+
+ className = args[index];
+ }
+ }
+
+ if (GenericUtils.isEmpty(className)) {
+ className = System.getProperty(ScpClientCreator.class.getName());
+ }
+
+ if (GenericUtils.isEmpty(className)) {
+ return ScpClientCreator.instance();
+ }
+
+ try {
+ ClassLoader cl = ThreadUtils.resolveDefaultClassLoader(ScpClientCreator.class);
+ Class<?> clazz = cl.loadClass(className);
+ return ScpClientCreator.class.cast(clazz.newInstance());
+ } catch (Exception e) {
+ stderr.append("Failed (").append(e.getClass().getSimpleName()).append(')')
+ .append(" to instantiate ").append(className)
+ .append(": ").println(e.getMessage());
+ stderr.flush();
+ return null;
+ }
+ }
+
public static void main(String[] args) throws Exception {
PrintStream stdout = System.out;
PrintStream stderr = System.err;
@@ -134,11 +174,12 @@ public class ScpCommandMain extends SshClientCliSupport {
}
}
- ClientSession session = (logStream == null) || GenericUtils.isEmpty(args)
+ ScpClientCreator creator = resolveScpClientCreator(stderr, args);
+ ClientSession session = ((logStream == null) || (creator == null) || GenericUtils.isEmpty(args))
? null : setupClientSession(SCP_PORT_OPTION, stdin, stdout, stderr, args);
if (session == null) {
stderr.println("usage: scp [" + SCP_PORT_OPTION + " port] [-i identity] [-io nio2|mina|netty]"
- + " [-v[v][v]] [-E logoutput] [-r] [-p] [-q] [-o option=value]"
+ + " [-v[v][v]] [-E logoutput] [-r] [-p] [-q] [-o option=value] [-o creator=class name]"
+ " [-c cipherlist] [-m maclist] [-w password] [-C] <source> <target>");
stderr.println();
stderr.println("Where <source> or <target> are either 'user@host:file' or a local file path");
@@ -163,7 +204,7 @@ public class ScpCommandMain extends SshClientCliSupport {
}
if (!quiet) {
- session.setScpTransferEventListener(new ScpTransferEventListener() {
+ creator.setScpTransferEventListener(new ScpTransferEventListener() {
@Override
public void startFolderEvent(FileOperation op, Path file, Set<PosixFilePermission> perms) {
logEvent("startFolderEvent", op, file, -1L, perms, null);
@@ -200,7 +241,7 @@ public class ScpCommandMain extends SshClientCliSupport {
});
}
- ScpClient client = session.createScpClient();
+ ScpClient client = creator.createScpClient(session);
ScpLocation source = new ScpLocation(args[numArgs - 2]);
ScpLocation target = new ScpLocation(args[numArgs - 1]);
if (source.isLocal()) {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/af415e5f/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 cba9d24..05c1069 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
@@ -56,7 +56,6 @@ public class SshServerMain extends SshServerCliSupport {
public static void main(String[] args) throws Exception {
int port = 8000;
- String provider;
boolean error = false;
String hostKeyType = AbstractGeneratorHostKeyProvider.DEFAULT_ALGORITHM;
int hostKeySize = 0;
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/af415e5f/sshd-contrib/pom.xml
----------------------------------------------------------------------
diff --git a/sshd-contrib/pom.xml b/sshd-contrib/pom.xml
index e904686..f0ff459 100644
--- a/sshd-contrib/pom.xml
+++ b/sshd-contrib/pom.xml
@@ -53,6 +53,11 @@
</dependency>
<dependency>
<groupId>org.apache.sshd</groupId>
+ <artifactId>sshd-scp</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sshd</groupId>
<artifactId>sshd-sftp</artifactId>
<version>${project.version}</version>
</dependency>
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/af415e5f/sshd-contrib/src/test/java/org/apache/sshd/server/scp/SimpleAccessControlScpEventListenerTest.java
----------------------------------------------------------------------
diff --git a/sshd-contrib/src/test/java/org/apache/sshd/server/scp/SimpleAccessControlScpEventListenerTest.java b/sshd-contrib/src/test/java/org/apache/sshd/server/scp/SimpleAccessControlScpEventListenerTest.java
index 70bcd44..4312dda 100644
--- a/sshd-contrib/src/test/java/org/apache/sshd/server/scp/SimpleAccessControlScpEventListenerTest.java
+++ b/sshd-contrib/src/test/java/org/apache/sshd/server/scp/SimpleAccessControlScpEventListenerTest.java
@@ -28,6 +28,7 @@ import java.util.concurrent.TimeUnit;
import org.apache.sshd.client.SshClient;
import org.apache.sshd.client.scp.ScpClient;
+import org.apache.sshd.client.scp.ScpClientCreator;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.common.file.FileSystemFactory;
import org.apache.sshd.common.file.virtualfs.VirtualFileSystemFactory;
@@ -89,7 +90,8 @@ public class SimpleAccessControlScpEventListenerTest extends BaseTestSupport {
session.addPasswordIdentity(getCurrentTestName());
session.auth().verify(5L, TimeUnit.SECONDS);
- ScpClient scp = session.createScpClient();
+ ScpClientCreator creator = ScpClientCreator.instance();
+ ScpClient scp = creator.createScpClient(session);
Path targetPath = detectTargetFolder();
Path parentPath = targetPath.getParent();
Path scpRoot = Utils.resolve(targetPath, ScpHelper.SCP_COMMAND_PREFIX, getClass().getSimpleName(), getCurrentTestName());
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/af415e5f/sshd-core/src/main/java/org/apache/sshd/client/ClientFactoryManager.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/ClientFactoryManager.java b/sshd-core/src/main/java/org/apache/sshd/client/ClientFactoryManager.java
index 31b2a22..26ca4bd 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/ClientFactoryManager.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/ClientFactoryManager.java
@@ -23,7 +23,6 @@ import org.apache.sshd.client.config.keys.ClientIdentityLoader;
import org.apache.sshd.client.session.ClientProxyConnectorHolder;
import org.apache.sshd.common.FactoryManager;
import org.apache.sshd.common.config.keys.FilePasswordProvider;
-import org.apache.sshd.common.scp.ScpFileOpenerHolder;
/**
* The <code>ClientFactoryManager</code> enable the retrieval of additional
@@ -33,7 +32,6 @@ import org.apache.sshd.common.scp.ScpFileOpenerHolder;
*/
public interface ClientFactoryManager
extends FactoryManager,
- ScpFileOpenerHolder,
ClientProxyConnectorHolder,
ClientAuthenticationManager {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/af415e5f/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java b/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
index 1d034c1..e387bb6 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
@@ -74,7 +74,6 @@ import org.apache.sshd.common.io.IoConnectFuture;
import org.apache.sshd.common.io.IoConnector;
import org.apache.sshd.common.io.IoSession;
import org.apache.sshd.common.keyprovider.KeyPairProvider;
-import org.apache.sshd.common.scp.ScpFileOpener;
import org.apache.sshd.common.session.helpers.AbstractSession;
import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.ValidateUtils;
@@ -162,7 +161,6 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
private ClientIdentityLoader clientIdentityLoader;
private FilePasswordProvider filePasswordProvider;
private PasswordIdentityProvider passwordIdentityProvider;
- private ScpFileOpener scpOpener;
private final List<Object> identities = new CopyOnWriteArrayList<>();
private final AuthenticationIdentitiesProvider identitiesProvider;
@@ -191,16 +189,6 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
}
@Override
- public ScpFileOpener getScpFileOpener() {
- return scpOpener;
- }
-
- @Override
- public void setScpFileOpener(ScpFileOpener opener) {
- scpOpener = opener;
- }
-
- @Override
public ServerKeyVerifier getServerKeyVerifier() {
return serverKeyVerifier;
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/af415e5f/sshd-core/src/main/java/org/apache/sshd/client/scp/AbstractScpClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/scp/AbstractScpClient.java b/sshd-core/src/main/java/org/apache/sshd/client/scp/AbstractScpClient.java
deleted file mode 100644
index 81c20db..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/client/scp/AbstractScpClient.java
+++ /dev/null
@@ -1,278 +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.client.scp;
-
-import java.io.IOException;
-import java.nio.file.FileSystem;
-import java.nio.file.Files;
-import java.nio.file.LinkOption;
-import java.nio.file.Path;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.sshd.client.channel.ChannelExec;
-import org.apache.sshd.client.channel.ClientChannel;
-import org.apache.sshd.client.channel.ClientChannelEvent;
-import org.apache.sshd.client.session.ClientSession;
-import org.apache.sshd.common.FactoryManager;
-import org.apache.sshd.common.SshException;
-import org.apache.sshd.common.file.FileSystemFactory;
-import org.apache.sshd.common.scp.ScpException;
-import org.apache.sshd.common.scp.ScpHelper;
-import org.apache.sshd.common.util.GenericUtils;
-import org.apache.sshd.common.util.ValidateUtils;
-import org.apache.sshd.common.util.io.IoUtils;
-import org.apache.sshd.common.util.logging.AbstractLoggingBean;
-
-/**
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public abstract class AbstractScpClient extends AbstractLoggingBean implements ScpClient {
- public static final Set<ClientChannelEvent> COMMAND_WAIT_EVENTS =
- Collections.unmodifiableSet(EnumSet.of(ClientChannelEvent.EXIT_STATUS, ClientChannelEvent.CLOSED));
-
- protected AbstractScpClient() {
- super();
- }
-
- @Override
- public final ClientSession getSession() {
- return getClientSession();
- }
-
- @Override
- public void download(String[] remote, String local, Collection<Option> options) throws IOException {
- local = ValidateUtils.checkNotNullAndNotEmpty(local, "Invalid argument local: %s", local);
- remote = ValidateUtils.checkNotNullAndNotEmpty(remote, "Invalid argument remote: %s", (Object) remote);
-
- if (remote.length > 1) {
- options = addTargetIsDirectory(options);
- }
-
- for (String r : remote) {
- download(r, local, options);
- }
- }
-
- @Override
- public void download(String[] remote, Path local, Collection<Option> options) throws IOException {
- remote = ValidateUtils.checkNotNullAndNotEmpty(remote, "Invalid argument remote: %s", (Object) remote);
-
- if (remote.length > 1) {
- options = addTargetIsDirectory(options);
- }
-
- for (String r : remote) {
- download(r, local, options);
- }
- }
-
- @Override
- public void download(String remote, Path local, Collection<Option> options) throws IOException {
- local = ValidateUtils.checkNotNull(local, "Invalid argument local: %s", local);
- remote = ValidateUtils.checkNotNullAndNotEmpty(remote, "Invalid argument remote: %s", remote);
-
- LinkOption[] opts = IoUtils.getLinkOptions(true);
- if (Files.isDirectory(local, opts)) {
- options = addTargetIsDirectory(options);
- }
-
- if (options.contains(Option.TargetIsDirectory)) {
- Boolean status = IoUtils.checkFileExists(local, opts);
- if (status == null) {
- throw new SshException("Target directory " + local.toString() + " is probably inaccesible");
- }
-
- if (!status) {
- throw new SshException("Target directory " + local.toString() + " does not exist");
- }
-
- if (!Files.isDirectory(local, opts)) {
- throw new SshException("Target directory " + local.toString() + " is not a directory");
- }
- }
-
- download(remote, local.getFileSystem(), local, options);
- }
-
- @Override
- public void download(String remote, String local, Collection<Option> options) throws IOException {
- local = ValidateUtils.checkNotNullAndNotEmpty(local, "Invalid argument local: %s", local);
-
- ClientSession session = getClientSession();
- FactoryManager manager = session.getFactoryManager();
- FileSystemFactory factory = manager.getFileSystemFactory();
- FileSystem fs = factory.createFileSystem(session);
- try {
- download(remote, fs, fs.getPath(local), options);
- } finally {
- try {
- fs.close();
- } catch (UnsupportedOperationException e) {
- if (log.isDebugEnabled()) {
- log.debug("download({}) {} => {} - failed ({}) to close file system={}: {}",
- session, remote, local, e.getClass().getSimpleName(), fs, e.getMessage());
- }
- }
- }
- }
-
- protected abstract void download(String remote, FileSystem fs, Path local, Collection<Option> options) throws IOException;
-
- @Override
- public void upload(String[] local, String remote, Collection<Option> options) throws IOException {
- final Collection<String> paths = Arrays.asList(ValidateUtils.checkNotNullAndNotEmpty(local, "Invalid argument local: %s", (Object) local));
- runUpload(remote, options, paths, (helper, local1, sendOptions) ->
- helper.send(local1,
- sendOptions.contains(Option.Recursive),
- sendOptions.contains(Option.PreserveAttributes),
- ScpHelper.DEFAULT_SEND_BUFFER_SIZE));
- }
-
- @Override
- public void upload(Path[] local, String remote, Collection<Option> options) throws IOException {
- final Collection<Path> paths = Arrays.asList(ValidateUtils.checkNotNullAndNotEmpty(local, "Invalid argument local: %s", (Object) local));
- runUpload(remote, options, paths, (helper, local1, sendOptions) ->
- helper.sendPaths(local1,
- sendOptions.contains(Option.Recursive),
- sendOptions.contains(Option.PreserveAttributes),
- ScpHelper.DEFAULT_SEND_BUFFER_SIZE));
- }
-
- protected abstract <T> void runUpload(String remote, Collection<Option> options, Collection<T> local, AbstractScpClient.ScpOperationExecutor<T> executor) throws IOException;
-
- /**
- * Invoked by the various <code>upload/download</code> methods after having successfully
- * completed the remote copy command and (optionally) having received an exit status
- * from the remote server. If no exit status received within {@link FactoryManager#CHANNEL_CLOSE_TIMEOUT}
- * the no further action is taken. Otherwise, the exit status is examined to ensure it
- * is either OK or WARNING - if not, an {@link ScpException} is thrown
- *
- * @param cmd The attempted remote copy command
- * @param channel The {@link ClientChannel} through which the command was sent - <B>Note:</B>
- * then channel may be in the process of being closed
- * @throws IOException If failed the command
- * @see #handleCommandExitStatus(String, Integer)
- */
- protected void handleCommandExitStatus(String cmd, ClientChannel channel) throws IOException {
- // give a chance for the exit status to be received
- long timeout = channel.getLongProperty(SCP_EXEC_CHANNEL_EXIT_STATUS_TIMEOUT, DEFAULT_EXEC_CHANNEL_EXIT_STATUS_TIMEOUT);
- if (timeout <= 0L) {
- handleCommandExitStatus(cmd, (Integer) null);
- return;
- }
-
- long waitStart = System.nanoTime();
- Collection<ClientChannelEvent> events = channel.waitFor(COMMAND_WAIT_EVENTS, timeout);
- long waitEnd = System.nanoTime();
- if (log.isDebugEnabled()) {
- log.debug("handleCommandExitStatus({}) cmd='{}', waited={} nanos, events={}",
- getClientSession(), cmd, waitEnd - waitStart, events);
- }
-
- /*
- * There are sometimes race conditions in the order in which channels are closed and exit-status
- * sent by the remote peer (if at all), thus there is no guarantee that we will have an exit
- * status here
- */
- handleCommandExitStatus(cmd, channel.getExitStatus());
- }
-
- /**
- * Invoked by the various <code>upload/download</code> methods after having successfully
- * completed the remote copy command and (optionally) having received an exit status
- * from the remote server
- *
- * @param cmd The attempted remote copy command
- * @param exitStatus The exit status - if {@code null} then no status was reported
- * @throws IOException If failed the command
- */
- protected void handleCommandExitStatus(String cmd, Integer exitStatus) throws IOException {
- if (log.isDebugEnabled()) {
- log.debug("handleCommandExitStatus({}) cmd='{}', exit-status={}", getClientSession(), cmd, ScpHelper.getExitStatusName(exitStatus));
- }
-
- if (exitStatus == null) {
- return;
- }
-
- int statusCode = exitStatus;
- switch (statusCode) {
- case ScpHelper.OK: // do nothing
- break;
- case ScpHelper.WARNING:
- log.warn("handleCommandExitStatus({}) cmd='{}' may have terminated with some problems", getClientSession(), cmd);
- break;
- default:
- throw new ScpException("Failed to run command='" + cmd + "': " + ScpHelper.getExitStatusName(exitStatus), exitStatus);
- }
- }
-
- protected Collection<Option> addTargetIsDirectory(Collection<Option> options) {
- if (GenericUtils.isEmpty(options) || (!options.contains(Option.TargetIsDirectory))) {
- // create a copy in case the original collection is un-modifiable
- options = GenericUtils.isEmpty(options) ? EnumSet.noneOf(Option.class) : GenericUtils.of(options);
- options.add(Option.TargetIsDirectory);
- }
-
- return options;
- }
-
- protected ChannelExec openCommandChannel(ClientSession session, String cmd) throws IOException {
- long waitTimeout = session.getLongProperty(SCP_EXEC_CHANNEL_OPEN_TIMEOUT, DEFAULT_EXEC_CHANNEL_OPEN_TIMEOUT);
- ChannelExec channel = session.createExecChannel(cmd);
-
- long startTime = System.nanoTime();
- try {
- channel.open().verify(waitTimeout);
- long endTime = System.nanoTime();
- long nanosWait = endTime - startTime;
- if (log.isTraceEnabled()) {
- log.trace("openCommandChannel(" + session + ")[" + cmd + "]"
- + " completed after " + nanosWait
- + " nanos out of " + TimeUnit.MILLISECONDS.toNanos(waitTimeout));
- }
-
- return channel;
- } catch (IOException | RuntimeException e) {
- long endTime = System.nanoTime();
- long nanosWait = endTime - startTime;
- if (log.isTraceEnabled()) {
- log.trace("openCommandChannel(" + session + ")[" + cmd + "]"
- + " failed (" + e.getClass().getSimpleName() + ")"
- + " to complete after " + nanosWait
- + " nanos out of " + TimeUnit.MILLISECONDS.toNanos(waitTimeout)
- + ": " + e.getMessage());
- }
-
- channel.close(false);
- throw e;
- }
- }
-
- @FunctionalInterface
- public interface ScpOperationExecutor<T> {
- void execute(ScpHelper helper, Collection<T> local, Collection<Option> options) throws IOException;
- }
-}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/af415e5f/sshd-core/src/main/java/org/apache/sshd/client/scp/CloseableScpClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/scp/CloseableScpClient.java b/sshd-core/src/main/java/org/apache/sshd/client/scp/CloseableScpClient.java
deleted file mode 100644
index 40afaf7..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/client/scp/CloseableScpClient.java
+++ /dev/null
@@ -1,32 +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.client.scp;
-
-import java.nio.channels.Channel;
-
-/**
- * An {@link ScpClient} wrapper that also closes the underlying session
- * when closed
- *
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public interface CloseableScpClient extends ScpClient, Channel {
- // Marker interface
-}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/af415e5f/sshd-core/src/main/java/org/apache/sshd/client/scp/DefaultScpClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/scp/DefaultScpClient.java b/sshd-core/src/main/java/org/apache/sshd/client/scp/DefaultScpClient.java
deleted file mode 100644
index 16d0cb2..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/client/scp/DefaultScpClient.java
+++ /dev/null
@@ -1,159 +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.client.scp;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.file.FileSystem;
-import java.nio.file.Path;
-import java.nio.file.attribute.PosixFilePermission;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.Objects;
-
-import org.apache.sshd.client.channel.ChannelExec;
-import org.apache.sshd.client.session.ClientSession;
-import org.apache.sshd.common.FactoryManager;
-import org.apache.sshd.common.file.FileSystemFactory;
-import org.apache.sshd.common.file.util.MockFileSystem;
-import org.apache.sshd.common.file.util.MockPath;
-import org.apache.sshd.common.scp.ScpFileOpener;
-import org.apache.sshd.common.scp.ScpHelper;
-import org.apache.sshd.common.scp.ScpTimestamp;
-import org.apache.sshd.common.scp.ScpTransferEventListener;
-import org.apache.sshd.common.scp.helpers.DefaultScpFileOpener;
-import org.apache.sshd.common.util.ValidateUtils;
-
-/**
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public class DefaultScpClient extends AbstractScpClient {
- protected final ScpFileOpener opener;
- protected final ScpTransferEventListener listener;
- private final ClientSession clientSession;
-
- public DefaultScpClient(
- ClientSession clientSession, ScpFileOpener fileOpener, ScpTransferEventListener eventListener) {
- this.clientSession = Objects.requireNonNull(clientSession, "No client session");
- this.opener = (fileOpener == null) ? DefaultScpFileOpener.INSTANCE : fileOpener;
- this.listener = (eventListener == null) ? ScpTransferEventListener.EMPTY : eventListener;
- }
-
- @Override
- public ClientSession getClientSession() {
- return clientSession;
- }
-
- @Override
- public void download(String remote, OutputStream local) throws IOException {
- String cmd = ScpClient.createReceiveCommand(remote, Collections.emptyList());
- ClientSession session = getClientSession();
- ChannelExec channel = openCommandChannel(session, cmd);
- try (InputStream invOut = channel.getInvertedOut();
- OutputStream invIn = channel.getInvertedIn()) {
- // NOTE: we use a mock file system since we expect no invocations for it
- ScpHelper helper = new ScpHelper(session, invOut, invIn, new MockFileSystem(remote), opener, listener);
- helper.receiveFileStream(local, ScpHelper.DEFAULT_RECEIVE_BUFFER_SIZE);
- handleCommandExitStatus(cmd, channel);
- } finally {
- channel.close(false);
- }
- }
-
- @Override
- protected void download(String remote, FileSystem fs, Path local, Collection<Option> options) throws IOException {
- String cmd = ScpClient.createReceiveCommand(remote, options);
- ClientSession session = getClientSession();
- ChannelExec channel = openCommandChannel(session, cmd);
- try (InputStream invOut = channel.getInvertedOut();
- OutputStream invIn = channel.getInvertedIn()) {
- ScpHelper helper = new ScpHelper(session, invOut, invIn, fs, opener, listener);
- helper.receive(local,
- options.contains(Option.Recursive),
- options.contains(Option.TargetIsDirectory),
- options.contains(Option.PreserveAttributes),
- ScpHelper.DEFAULT_RECEIVE_BUFFER_SIZE);
- handleCommandExitStatus(cmd, channel);
- } finally {
- channel.close(false);
- }
- }
-
- @Override
- public void upload(InputStream local, String remote, long size, Collection<PosixFilePermission> perms, ScpTimestamp time) throws IOException {
- int namePos = ValidateUtils.checkNotNullAndNotEmpty(remote, "No remote location specified").lastIndexOf('/');
- String name = (namePos < 0)
- ? remote
- : ValidateUtils.checkNotNullAndNotEmpty(remote.substring(namePos + 1), "No name value in remote=%s", remote);
- Collection<Option> options = (time != null) ? EnumSet.of(Option.PreserveAttributes) : Collections.emptySet();
- String cmd = ScpClient.createSendCommand(remote, options);
- ClientSession session = getClientSession();
- ChannelExec channel = openCommandChannel(session, cmd);
- try (InputStream invOut = channel.getInvertedOut();
- OutputStream invIn = channel.getInvertedIn()) {
- // NOTE: we use a mock file system since we expect no invocations for it
- ScpHelper helper = new ScpHelper(session, invOut, invIn, new MockFileSystem(remote), opener, listener);
- Path mockPath = new MockPath(remote);
- helper.sendStream(new DefaultScpStreamResolver(name, mockPath, perms, time, size, local, cmd),
- options.contains(Option.PreserveAttributes), ScpHelper.DEFAULT_SEND_BUFFER_SIZE);
- handleCommandExitStatus(cmd, channel);
- } finally {
- channel.close(false);
- }
- }
-
- @Override
- protected <T> void runUpload(String remote, Collection<Option> options, Collection<T> local, AbstractScpClient.ScpOperationExecutor<T> executor) throws IOException {
- local = ValidateUtils.checkNotNullAndNotEmpty(local, "Invalid argument local: %s", local);
- remote = ValidateUtils.checkNotNullAndNotEmpty(remote, "Invalid argument remote: %s", remote);
- if (local.size() > 1) {
- options = addTargetIsDirectory(options);
- }
-
- String cmd = ScpClient.createSendCommand(remote, options);
- ClientSession session = getClientSession();
- ChannelExec channel = openCommandChannel(session, cmd);
- try {
- FactoryManager manager = session.getFactoryManager();
- FileSystemFactory factory = manager.getFileSystemFactory();
- FileSystem fs = factory.createFileSystem(session);
-
- try (InputStream invOut = channel.getInvertedOut();
- OutputStream invIn = channel.getInvertedIn()) {
- ScpHelper helper = new ScpHelper(session, invOut, invIn, fs, opener, listener);
- executor.execute(helper, local, options);
- } finally {
- try {
- fs.close();
- } catch (UnsupportedOperationException e) {
- if (log.isDebugEnabled()) {
- log.debug("runUpload({}) {} => {} - failed ({}) to close file system={}: {}",
- session, remote, local, e.getClass().getSimpleName(), fs, e.getMessage());
- }
- }
- }
- handleCommandExitStatus(cmd, channel);
- } finally {
- channel.close(false);
- }
- }
-}
-
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/af415e5f/sshd-core/src/main/java/org/apache/sshd/client/scp/DefaultScpStreamResolver.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/scp/DefaultScpStreamResolver.java b/sshd-core/src/main/java/org/apache/sshd/client/scp/DefaultScpStreamResolver.java
deleted file mode 100644
index e6362b8..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/client/scp/DefaultScpStreamResolver.java
+++ /dev/null
@@ -1,88 +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.client.scp;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.file.OpenOption;
-import java.nio.file.Path;
-import java.nio.file.attribute.PosixFilePermission;
-import java.util.Collection;
-
-import org.apache.sshd.common.scp.ScpSourceStreamResolver;
-import org.apache.sshd.common.scp.ScpTimestamp;
-import org.apache.sshd.common.session.Session;
-
-/**
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public class DefaultScpStreamResolver implements ScpSourceStreamResolver {
- private final String name;
- private final Path mockPath;
- private final Collection<PosixFilePermission> perms;
- private final ScpTimestamp time;
- private final long size;
- private final java.io.InputStream local;
- private final String cmd;
-
- public DefaultScpStreamResolver(String name, Path mockPath, Collection<PosixFilePermission> perms, ScpTimestamp time, long size, InputStream local, String cmd) {
- this.name = name;
- this.mockPath = mockPath;
- this.perms = perms;
- this.time = time;
- this.size = size;
- this.local = local;
- this.cmd = cmd;
- }
-
- @Override
- public String getFileName() throws java.io.IOException {
- return name;
- }
-
- @Override
- public Path getEventListenerFilePath() {
- return mockPath;
- }
-
- @Override
- public Collection<PosixFilePermission> getPermissions() throws IOException {
- return perms;
- }
-
- @Override
- public ScpTimestamp getTimestamp() throws IOException {
- return time;
- }
-
- @Override
- public long getSize() throws IOException {
- return size;
- }
-
- @Override
- public InputStream resolveSourceStream(Session session, OpenOption... options) throws IOException {
- return local;
- }
-
- @Override
- public String toString() {
- return cmd;
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/af415e5f/sshd-core/src/main/java/org/apache/sshd/client/scp/ScpClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/scp/ScpClient.java b/sshd-core/src/main/java/org/apache/sshd/client/scp/ScpClient.java
deleted file mode 100644
index b2a6091..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/client/scp/ScpClient.java
+++ /dev/null
@@ -1,174 +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.client.scp;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.file.Path;
-import java.nio.file.attribute.PosixFilePermission;
-import java.util.Collection;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.sshd.client.session.ClientSession;
-import org.apache.sshd.client.session.ClientSessionHolder;
-import org.apache.sshd.common.scp.ScpHelper;
-import org.apache.sshd.common.scp.ScpTimestamp;
-import org.apache.sshd.common.session.SessionHolder;
-import org.apache.sshd.common.util.GenericUtils;
-import org.apache.sshd.common.util.ValidateUtils;
-
-/**
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public interface ScpClient extends SessionHolder<ClientSession>, ClientSessionHolder {
- enum Option {
- Recursive,
- PreserveAttributes,
- TargetIsDirectory
- }
-
- /**
- * Configurable value of the {@link org.apache.sshd.common.FactoryManager}
- * for controlling the wait timeout for opening a channel for an SCP command
- * in milliseconds. If not specified, then {@link #DEFAULT_EXEC_CHANNEL_OPEN_TIMEOUT}
- * value is used
- */
- String SCP_EXEC_CHANNEL_OPEN_TIMEOUT = "scp-exec-channel-open-timeout";
- long DEFAULT_EXEC_CHANNEL_OPEN_TIMEOUT = TimeUnit.SECONDS.toMillis(30L);
-
- /**
- * Configurable value of the {@link org.apache.sshd.common.FactoryManager}
- * for controlling the wait timeout for waiting on a channel exit status'
- * for an SCP command in milliseconds. If not specified, then
- * {@link #DEFAULT_EXEC_CHANNEL_EXIT_STATUS_TIMEOUT}
- * value is used. If non-positive, then no wait is performed and the command
- * is assumed to have completed successfully.
- */
- String SCP_EXEC_CHANNEL_EXIT_STATUS_TIMEOUT = "scp-exec-channel-exit-status-timeout";
- long DEFAULT_EXEC_CHANNEL_EXIT_STATUS_TIMEOUT = TimeUnit.SECONDS.toMillis(5L);
-
- default void download(String remote, String local, Option... options) throws IOException {
- download(remote, local, GenericUtils.of(options));
- }
-
- void download(String remote, String local, Collection<Option> options) throws IOException;
-
- default void download(String remote, Path local, Option... options) throws IOException {
- download(remote, local, GenericUtils.of(options));
- }
-
- void download(String remote, Path local, Collection<Option> options) throws IOException;
-
- // NOTE: the remote location MUST be a file or an exception is generated
- void download(String remote, OutputStream local) throws IOException;
-
- default byte[] downloadBytes(String remote) throws IOException {
- try (ByteArrayOutputStream local = new ByteArrayOutputStream()) {
- download(remote, local);
- return local.toByteArray();
- }
- }
-
- default void download(String[] remote, String local, Option... options) throws IOException {
- download(remote, local, GenericUtils.of(options));
- }
-
- default void download(String[] remote, Path local, Option... options) throws IOException {
- download(remote, local, GenericUtils.of(options));
- }
-
- void download(String[] remote, String local, Collection<Option> options) throws IOException;
-
- void download(String[] remote, Path local, Collection<Option> options) throws IOException;
-
- default void upload(String local, String remote, Option... options) throws IOException {
- upload(local, remote, GenericUtils.of(options));
- }
-
- default void upload(String local, String remote, Collection<Option> options) throws IOException {
- upload(new String[]{ValidateUtils.checkNotNullAndNotEmpty(local, "Invalid argument local: %s", local)}, remote, options);
- }
-
- default void upload(Path local, String remote, Option... options) throws IOException {
- upload(local, remote, GenericUtils.of(options));
- }
-
- default void upload(Path local, String remote, Collection<Option> options) throws IOException {
- upload(new Path[]{ValidateUtils.checkNotNull(local, "Invalid local argument: %s", local)}, remote, GenericUtils.of(options));
- }
-
- default void upload(String[] local, String remote, Option... options) throws IOException {
- upload(local, remote, GenericUtils.of(options));
- }
-
- void upload(String[] local, String remote, Collection<Option> options) throws IOException;
-
- default void upload(Path[] local, String remote, Option... options) throws IOException {
- upload(local, remote, GenericUtils.of(options));
- }
-
- void upload(Path[] local, String remote, Collection<Option> options) throws IOException;
-
- // NOTE: due to SCP command limitations, the amount of data to be uploaded must be known a-priori
- // To upload a dynamic amount of data use SFTP
- default void upload(byte[] data, String remote, Collection<PosixFilePermission> perms, ScpTimestamp time) throws IOException {
- upload(data, 0, data.length, remote, perms, time);
- }
-
- default void upload(byte[] data, int offset, int len, String remote, Collection<PosixFilePermission> perms, ScpTimestamp time) throws IOException {
- try (InputStream local = new ByteArrayInputStream(data, offset, len)) {
- upload(local, remote, len, perms, time);
- }
- }
-
- void upload(InputStream local, String remote, long size, Collection<PosixFilePermission> perms, ScpTimestamp time) throws IOException;
-
- static String createSendCommand(String remote, Collection<Option> options) {
- StringBuilder sb = new StringBuilder(remote.length() + Long.SIZE).append(ScpHelper.SCP_COMMAND_PREFIX);
- if (options.contains(Option.Recursive)) {
- sb.append(" -r");
- }
- if (options.contains(Option.TargetIsDirectory)) {
- sb.append(" -d");
- }
- if (options.contains(Option.PreserveAttributes)) {
- sb.append(" -p");
- }
-
- sb.append(" -t").append(" --").append(" ").append(remote);
- return sb.toString();
- }
-
- static String createReceiveCommand(String remote, Collection<Option> options) {
- ValidateUtils.checkNotNullAndNotEmpty(remote, "No remote location specified");
- StringBuilder sb = new StringBuilder(remote.length() + Long.SIZE).append(ScpHelper.SCP_COMMAND_PREFIX);
- if (options.contains(Option.Recursive)) {
- sb.append(" -r");
- }
- if (options.contains(Option.PreserveAttributes)) {
- sb.append(" -p");
- }
-
- sb.append(" -f").append(" --").append(' ').append(remote);
- return sb.toString();
- }
-}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/af415e5f/sshd-core/src/main/java/org/apache/sshd/client/scp/ScpClientCreator.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/scp/ScpClientCreator.java b/sshd-core/src/main/java/org/apache/sshd/client/scp/ScpClientCreator.java
deleted file mode 100644
index 8ae54a4..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/client/scp/ScpClientCreator.java
+++ /dev/null
@@ -1,97 +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.client.scp;
-
-import org.apache.sshd.common.scp.ScpFileOpener;
-import org.apache.sshd.common.scp.ScpFileOpenerHolder;
-import org.apache.sshd.common.scp.ScpTransferEventListener;
-
-/**
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public interface ScpClientCreator extends ScpFileOpenerHolder {
- /**
- * Create an SCP client from this session.
- *
- * @return An {@link ScpClient} instance. <B>Note:</B> uses the currently
- * registered {@link ScpTransferEventListener} and {@link ScpFileOpener} if any
- * @see #setScpFileOpener(ScpFileOpener)
- * @see #setScpTransferEventListener(ScpTransferEventListener)
- */
- default ScpClient createScpClient() {
- return createScpClient(getScpFileOpener(), getScpTransferEventListener());
- }
-
- /**
- * Create an SCP client from this session.
- *
- * @param listener A {@link ScpTransferEventListener} that can be used
- * to receive information about the SCP operations - may be {@code null}
- * to indicate no more events are required. <B>Note:</B> this listener
- * is used <U>instead</U> of any listener set via {@link #setScpTransferEventListener(ScpTransferEventListener)}
- * @return An {@link ScpClient} instance
- */
- default ScpClient createScpClient(ScpTransferEventListener listener) {
- return createScpClient(getScpFileOpener(), listener);
- }
-
- /**
- * Create an SCP client from this session.
- *
- * @param opener The {@link ScpFileOpener} to use to control how local files
- * are read/written. If {@code null} then a default opener is used.
- * <B>Note:</B> this opener is used <U>instead</U> of any instance
- * set via {@link #setScpFileOpener(ScpFileOpener)}
- * @return An {@link ScpClient} instance
- */
- default ScpClient createScpClient(ScpFileOpener opener) {
- return createScpClient(opener, getScpTransferEventListener());
- }
-
- /**
- * Create an SCP client from this session.
- *
- * @param opener The {@link ScpFileOpener} to use to control how local files
- * are read/written. If {@code null} then a default opener is used.
- * <B>Note:</B> this opener is used <U>instead</U> of any instance
- * set via {@link #setScpFileOpener(ScpFileOpener)}
- * @param listener A {@link ScpTransferEventListener} that can be used
- * to receive information about the SCP operations - may be {@code null}
- * to indicate no more events are required. <B>Note:</B> this listener
- * is used <U>instead</U> of any listener set via
- * {@link #setScpTransferEventListener(ScpTransferEventListener)}
- * @return An {@link ScpClient} instance
- */
- ScpClient createScpClient(ScpFileOpener opener, ScpTransferEventListener listener);
-
- /**
- * @return The last {@link ScpTransferEventListener} set via
- * {@link #setScpTransferEventListener(ScpTransferEventListener)}
- */
- ScpTransferEventListener getScpTransferEventListener();
-
- /**
- * @param listener A default {@link ScpTransferEventListener} that can be used
- * to receive information about the SCP operations - may be {@code null}
- * to indicate no more events are required
- * @see #createScpClient(ScpTransferEventListener)
- */
- void setScpTransferEventListener(ScpTransferEventListener listener);
-}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/af415e5f/sshd-core/src/main/java/org/apache/sshd/client/session/AbstractClientSession.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/session/AbstractClientSession.java b/sshd-core/src/main/java/org/apache/sshd/client/session/AbstractClientSession.java
index d57a799..1cb309a 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/session/AbstractClientSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/session/AbstractClientSession.java
@@ -40,8 +40,6 @@ import org.apache.sshd.client.channel.ChannelShell;
import org.apache.sshd.client.channel.ChannelSubsystem;
import org.apache.sshd.client.channel.ClientChannel;
import org.apache.sshd.client.keyverifier.ServerKeyVerifier;
-import org.apache.sshd.client.scp.DefaultScpClient;
-import org.apache.sshd.client.scp.ScpClient;
import org.apache.sshd.common.FactoryManager;
import org.apache.sshd.common.NamedFactory;
import org.apache.sshd.common.NamedResource;
@@ -59,8 +57,6 @@ import org.apache.sshd.common.io.IoSession;
import org.apache.sshd.common.io.IoWriteFuture;
import org.apache.sshd.common.kex.KexProposalOption;
import org.apache.sshd.common.kex.KexState;
-import org.apache.sshd.common.scp.ScpFileOpener;
-import org.apache.sshd.common.scp.ScpTransferEventListener;
import org.apache.sshd.common.session.ConnectionService;
import org.apache.sshd.common.session.Session;
import org.apache.sshd.common.session.helpers.AbstractConnectionService;
@@ -82,8 +78,6 @@ public abstract class AbstractClientSession extends AbstractSession implements C
private UserInteraction userInteraction;
private PasswordIdentityProvider passwordIdentityProvider;
private List<NamedFactory<UserAuth>> userAuthFactories;
- private ScpTransferEventListener scpListener;
- private ScpFileOpener scpOpener;
private SocketAddress connectAddress;
private ClientProxyConnector proxyConnector;
@@ -301,31 +295,6 @@ public abstract class AbstractClientSession extends AbstractSession implements C
}
@Override
- public ScpFileOpener getScpFileOpener() {
- return resolveEffectiveProvider(ScpFileOpener.class, scpOpener, getFactoryManager().getScpFileOpener());
- }
-
- @Override
- public void setScpFileOpener(ScpFileOpener opener) {
- scpOpener = opener;
- }
-
- @Override
- public ScpTransferEventListener getScpTransferEventListener() {
- return scpListener;
- }
-
- @Override
- public void setScpTransferEventListener(ScpTransferEventListener listener) {
- scpListener = listener;
- }
-
- @Override
- public ScpClient createScpClient(ScpFileOpener opener, ScpTransferEventListener listener) {
- return new DefaultScpClient(this, opener, listener);
- }
-
- @Override
public SshdSocketAddress startLocalPortForwarding(SshdSocketAddress local, SshdSocketAddress remote) throws IOException {
ForwardingFilter filter = getForwardingFilter();
return filter.startLocalPortForwarding(local, remote);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/af415e5f/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSession.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSession.java b/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSession.java
index 96caf2e..1d68a20 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSession.java
@@ -42,7 +42,6 @@ import org.apache.sshd.client.channel.ChannelSubsystem;
import org.apache.sshd.client.channel.ClientChannel;
import org.apache.sshd.client.channel.ClientChannelEvent;
import org.apache.sshd.client.future.AuthFuture;
-import org.apache.sshd.client.scp.ScpClientCreator;
import org.apache.sshd.client.session.forward.DynamicPortForwardingTracker;
import org.apache.sshd.client.session.forward.ExplicitPortForwardingTracker;
import org.apache.sshd.common.forward.PortForwardingManager;
@@ -81,9 +80,8 @@ import org.apache.sshd.common.util.net.SshdSocketAddress;
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
public interface ClientSession
- extends Session, ScpClientCreator,
- ClientProxyConnectorHolder, ClientAuthenticationManager,
- PortForwardingManager {
+ extends Session, ClientProxyConnectorHolder,
+ ClientAuthenticationManager, PortForwardingManager {
enum ClientSessionEvent {
TIMEOUT,
CLOSED,
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/af415e5f/sshd-core/src/main/java/org/apache/sshd/client/simple/AbstractSimpleClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/simple/AbstractSimpleClient.java b/sshd-core/src/main/java/org/apache/sshd/client/simple/AbstractSimpleClient.java
index 247be60..dc5ef87 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/simple/AbstractSimpleClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/simple/AbstractSimpleClient.java
@@ -19,19 +19,6 @@
package org.apache.sshd.client.simple;
-import java.io.IOException;
-import java.lang.reflect.Proxy;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.security.KeyPair;
-import java.util.Objects;
-
-import org.apache.sshd.client.scp.CloseableScpClient;
-import org.apache.sshd.client.scp.ScpClient;
-import org.apache.sshd.client.session.ClientSession;
-import org.apache.sshd.common.util.GenericUtils;
-import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.logging.AbstractLoggingBean;
/**
@@ -41,97 +28,4 @@ public abstract class AbstractSimpleClient extends AbstractLoggingBean implement
protected AbstractSimpleClient() {
super();
}
-
- @Override
- public CloseableScpClient scpLogin(String host, String username, String password) throws IOException {
- return scpLogin(host, DEFAULT_PORT, username, password);
- }
-
- @Override
- public CloseableScpClient scpLogin(String host, int port, String username, String password) throws IOException {
- return scpLogin(InetAddress.getByName(ValidateUtils.checkNotNullAndNotEmpty(host, "No host")), port, username, password);
- }
-
- @Override
- public CloseableScpClient scpLogin(String host, String username, KeyPair identity) throws IOException {
- return scpLogin(host, DEFAULT_PORT, username, identity);
- }
-
- @Override
- public CloseableScpClient scpLogin(String host, int port, String username, KeyPair identity) throws IOException {
- return scpLogin(InetAddress.getByName(ValidateUtils.checkNotNullAndNotEmpty(host, "No host")), port, username, identity);
- }
-
- @Override
- public CloseableScpClient scpLogin(InetAddress host, String username, String password) throws IOException {
- return scpLogin(host, DEFAULT_PORT, username, password);
- }
-
- @Override
- public CloseableScpClient scpLogin(InetAddress host, int port, String username, String password) throws IOException {
- return scpLogin(new InetSocketAddress(Objects.requireNonNull(host, "No host address"), port), username, password);
- }
-
- @Override
- public CloseableScpClient scpLogin(InetAddress host, String username, KeyPair identity) throws IOException {
- return scpLogin(host, DEFAULT_PORT, username, identity);
- }
-
- @Override
- public CloseableScpClient scpLogin(InetAddress host, int port, String username, KeyPair identity) throws IOException {
- return scpLogin(new InetSocketAddress(Objects.requireNonNull(host, "No host address"), port), username, identity);
- }
-
- @Override
- public CloseableScpClient scpLogin(SocketAddress target, String username, String password) throws IOException {
- return createScpClient(sessionLogin(target, username, password));
- }
-
- @Override
- public CloseableScpClient scpLogin(SocketAddress target, String username, KeyPair identity) throws IOException {
- return createScpClient(sessionLogin(target, username, identity));
- }
-
- protected CloseableScpClient createScpClient(ClientSession session) throws IOException {
- try {
- ScpClient client = Objects.requireNonNull(session, "No client session").createScpClient();
- ClassLoader loader = getClass().getClassLoader();
- Class<?>[] interfaces = {CloseableScpClient.class};
- return (CloseableScpClient) Proxy.newProxyInstance(loader, interfaces, (proxy, method, args) -> {
- String name = method.getName();
- try {
- // The Channel implementation is provided by the session
- if (("close".equals(name) || "isOpen".equals(name)) && GenericUtils.isEmpty(args)) {
- return method.invoke(session, args);
- } else {
- return method.invoke(client, args);
- }
- } catch (Throwable t) {
- if (log.isTraceEnabled()) {
- log.trace("invoke(CloseableScpClient#{}) failed ({}) to execute: {}",
- name, t.getClass().getSimpleName(), t.getMessage());
- }
- throw t;
- }
- });
- } catch (Exception e) {
- log.warn("createScpClient({}) failed ({}) to create proxy: {}",
- session, e.getClass().getSimpleName(), e.getMessage());
- try {
- session.close();
- } catch (Exception t) {
- if (log.isDebugEnabled()) {
- log.debug("createScpClient({}) failed ({}) to close session: {}",
- session, t.getClass().getSimpleName(), t.getMessage());
- }
-
- if (log.isTraceEnabled()) {
- log.trace("createScpClient(" + session + ") session close failure details", t);
- }
- e.addSuppressed(t);
- }
-
- throw GenericUtils.toIOException(e);
- }
- }
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/af415e5f/sshd-core/src/main/java/org/apache/sshd/client/simple/SimpleClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/simple/SimpleClient.java b/sshd-core/src/main/java/org/apache/sshd/client/simple/SimpleClient.java
index 6fff133..174f600 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/simple/SimpleClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/simple/SimpleClient.java
@@ -31,7 +31,6 @@ import java.nio.channels.Channel;
public interface SimpleClient
extends SimpleClientConfigurator,
SimpleSessionClient,
- SimpleScpClient,
Channel {
// marker interface
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/af415e5f/sshd-core/src/main/java/org/apache/sshd/client/simple/SimpleScpClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/simple/SimpleScpClient.java b/sshd-core/src/main/java/org/apache/sshd/client/simple/SimpleScpClient.java
deleted file mode 100644
index eeeb7a2..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/client/simple/SimpleScpClient.java
+++ /dev/null
@@ -1,159 +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.client.simple;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.SocketAddress;
-import java.nio.channels.Channel;
-import java.security.KeyPair;
-
-import org.apache.sshd.client.scp.CloseableScpClient;
-
-/**
- * A simplified <U>synchronous</U> API for obtaining SCP sessions.
- *
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public interface SimpleScpClient extends SimpleClientConfigurator, Channel {
- /**
- * Creates an SCP session on the default port and logs in using the provided credentials
- *
- * @param host The target host name or address
- * @param username Username
- * @param password Password
- * @return Created {@link CloseableScpClient} - <B>Note:</B> closing the client also closes its
- * underlying session
- * @throws IOException If failed to login or authenticate
- */
- CloseableScpClient scpLogin(String host, String username, String password) throws IOException;
-
- /**
- * Creates an SCP session using the provided credentials
- *
- * @param host The target host name or address
- * @param port The target port
- * @param username Username
- * @param password Password
- * @return Created {@link CloseableScpClient} - <B>Note:</B> closing the client also closes its
- * underlying session
- * @throws IOException If failed to login or authenticate
- */
- CloseableScpClient scpLogin(String host, int port, String username, String password) throws IOException;
-
- /**
- * Creates an SCP session on the default port and logs in using the provided credentials
- *
- * @param host The target host name or address
- * @param username Username
- * @param identity The {@link KeyPair} identity
- * @return Created {@link CloseableScpClient} - <B>Note:</B> closing the client also closes its
- * underlying session
- * @throws IOException If failed to login or authenticate
- */
- CloseableScpClient scpLogin(String host, String username, KeyPair identity) throws IOException;
-
- /**
- * Creates an SCP session using the provided credentials
- *
- * @param host The target host name or address
- * @param port The target port
- * @param username Username
- * @param identity The {@link KeyPair} identity
- * @return Created {@link CloseableScpClient} - <B>Note:</B> closing the client also closes its
- * underlying session
- * @throws IOException If failed to login or authenticate
- */
- CloseableScpClient scpLogin(String host, int port, String username, KeyPair identity) throws IOException;
-
- /**
- * Creates an SCP session on the default port and logs in using the provided credentials
- *
- * @param host The target host {@link InetAddress}
- * @param username Username
- * @param password Password
- * @return Created {@link CloseableScpClient} - <B>Note:</B> closing the client also closes its
- * underlying session
- * @throws IOException If failed to login or authenticate
- */
- CloseableScpClient scpLogin(InetAddress host, String username, String password) throws IOException;
-
- /**
- * Creates an SCP session using the provided credentials
- *
- * @param host The target host {@link InetAddress}
- * @param port The target port
- * @param username Username
- * @param password Password
- * @return Created {@link CloseableScpClient} - <B>Note:</B> closing the client also closes its
- * underlying session
- * @throws IOException If failed to login or authenticate
- */
- CloseableScpClient scpLogin(InetAddress host, int port, String username, String password) throws IOException;
-
- /**
- * Creates an SCP session on the default port and logs in using the provided credentials
- *
- * @param host The target host {@link InetAddress}
- * @param username Username
- * @param identity The {@link KeyPair} identity
- * @return Created {@link CloseableScpClient} - <B>Note:</B> closing the client also closes its
- * underlying session
- * @throws IOException If failed to login or authenticate
- */
- CloseableScpClient scpLogin(InetAddress host, String username, KeyPair identity) throws IOException;
-
- /**
- * Creates an SCP session using the provided credentials
- *
- * @param host The target host {@link InetAddress}
- * @param port The target port
- * @param username Username
- * @param identity The {@link KeyPair} identity
- * @return Created {@link CloseableScpClient} - <B>Note:</B> closing the client also closes its
- * underlying session
- * @throws IOException If failed to login or authenticate
- */
- CloseableScpClient scpLogin(InetAddress host, int port, String username, KeyPair identity) throws IOException;
-
- /**
- * Creates an SCP session using the provided credentials
- *
- * @param target The target {@link SocketAddress}
- * @param username Username
- * @param password Password
- * @return Created {@link CloseableScpClient} - <B>Note:</B> closing the client also closes its
- * underlying session
- * @throws IOException If failed to login or authenticate
- */
- CloseableScpClient scpLogin(SocketAddress target, String username, String password) throws IOException;
-
- /**
- * Creates an SCP session using the provided credentials
- *
- * @param target The target {@link SocketAddress}
- * @param username Username
- * @param identity The {@link KeyPair} identity
- * @return Created {@link CloseableScpClient} - <B>Note:</B> closing the client also closes its
- * underlying session
- * @throws IOException If failed to login or authenticate
- */
- CloseableScpClient scpLogin(SocketAddress target, String username, KeyPair identity) throws IOException;
-}