GH-3572: Migrate SFTP from jsch to sshd-sftp (#3892)

* GH-3572: Migrate SFTP from `jsch` to `sshd-sftp`

Fixes https://github.com/spring-projects/spring-integration/issues/3572

* Rework SFTP module from the JSch API to more modern `sshd-sftp`
* Migrate generics of most API from `ChannelSftp.LsEntry` to the `SftpClient.DirEntry`
* Rework `DefaultSftpSessionFactory` to deal with an `SshClient` and create `SftpClient`
wrapped to the `SftpSession`
* Implement a `ResourceKnownHostsServerKeyVerifier` to load `known-hosts` from any possible resource
* Implement an expected `SftpSession.list()` with just file name to take or pattern matching
* Remove some unused tests and their config
* Remove tests for custom `UserInfo` since we don't provide any custom out-of-the-box
* Test a new `ResourceKnownHostsServerKeyVerifier` against default `known-hosts` file

* * Some tests improvements

* * Improve generics handling for `FileUtils`
This commit is contained in:
Artem Bilan
2022-09-27 13:10:11 -04:00
committed by GitHub
parent 69176632c0
commit 4aa2f91bd9
61 changed files with 1048 additions and 2232 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 the original author or authors.
* Copyright 2016-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -290,7 +290,7 @@ public abstract class RemoteFileInboundChannelAdapterSpec<F, S extends RemoteFil
* @return the spec.
* @since 5.2.9
*/
public S remoteComparator(Comparator<F> remoteComparator) {
public S remoteComparator(Comparator<? extends F> remoteComparator) {
this.synchronizer.setComparator(remoteComparator);
return _this();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2021 the original author or authors.
* Copyright 2016-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -62,11 +62,11 @@ import org.springframework.util.ObjectUtils;
public abstract class AbstractRemoteFileStreamingMessageSource<F>
extends AbstractFetchLimitingMessageSource<InputStream> implements ManageableLifecycle {
private final RemoteFileTemplate<F> remoteFileTemplate;
private final RemoteFileTemplate<? extends F> remoteFileTemplate;
private final BlockingQueue<AbstractFileInfo<F>> toBeReceived = new LinkedBlockingQueue<>();
private final Comparator<F> comparator;
private final Comparator<? extends F> comparator;
private final AtomicBoolean running = new AtomicBoolean();
@@ -86,8 +86,8 @@ public abstract class AbstractRemoteFileStreamingMessageSource<F>
*/
private FileListFilter<F> filter;
protected AbstractRemoteFileStreamingMessageSource(RemoteFileTemplate<F> template,
@Nullable Comparator<F> comparator) {
protected AbstractRemoteFileStreamingMessageSource(RemoteFileTemplate<? extends F> template,
@Nullable Comparator<? extends F> comparator) {
Assert.notNull(template, "'template' must not be null");
this.remoteFileTemplate = template;
@@ -143,7 +143,7 @@ public abstract class AbstractRemoteFileStreamingMessageSource<F>
this.fileInfoJson = fileInfoJson;
}
protected RemoteFileTemplate<F> getRemoteFileTemplate() {
protected RemoteFileTemplate<? extends F> getRemoteFileTemplate() {
return this.remoteFileTemplate;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -123,7 +123,7 @@ public abstract class AbstractInboundFileSynchronizer<F>
private BeanFactory beanFactory;
@Nullable
private Comparator<F> comparator;
private Comparator<? extends F> comparator;
private MetadataStore remoteFileMetadataStore = new SimpleMetadataStore();
@@ -141,7 +141,7 @@ public abstract class AbstractInboundFileSynchronizer<F>
}
@Nullable
protected Comparator<F> getComparator() {
protected Comparator<? extends F> getComparator() {
return this.comparator;
}
@@ -151,7 +151,7 @@ public abstract class AbstractInboundFileSynchronizer<F>
* @param comparator the comparator.
* @since 5.1
*/
public void setComparator(@Nullable Comparator<F> comparator) {
public void setComparator(@Nullable Comparator<? extends F> comparator) {
this.comparator = comparator;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2019 the original author or authors.
* Copyright 2017-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,6 +29,7 @@ import org.springframework.util.ObjectUtils;
* Utilities for operations on Files.
*
* @author Gary Russell
* @author Artem Bilan
*
* @since 5.0
*
@@ -47,8 +48,8 @@ public final class FileUtils {
* @since 5.0.7
*/
@SuppressWarnings("unchecked")
public static <F> F[] purgeUnwantedElements(F[] fileArray, Predicate<F> predicate,
@Nullable Comparator<F> comparator) {
public static <F> F[] purgeUnwantedElements(F[] fileArray, Predicate<? extends F> predicate,
@Nullable Comparator<? extends F> comparator) {
if (ObjectUtils.isEmpty(fileArray)) {
return fileArray;
@@ -56,13 +57,13 @@ public final class FileUtils {
else {
if (comparator == null) {
return Arrays.stream(fileArray)
.filter(predicate.negate())
.filter((Predicate<? super F>) predicate.negate())
.toArray(size -> (F[]) Array.newInstance(fileArray[0].getClass(), size));
}
else {
return Arrays.stream(fileArray)
.filter(predicate.negate())
.sorted(comparator)
.filter((Predicate<? super F>) predicate.negate())
.sorted((Comparator<? super F>) comparator)
.toArray(size -> (F[]) Array.newInstance(fileArray[0].getClass(), size));
}
}