为什么s3fs不能像普通文件系统一样与Apache MINA SSHD一起工作?

3
我正在尝试创建一个Java SFTP服务器,作为Apache S3存储桶的前端。您可以通过SFTP连接,并像在SFTP服务器上处理文件一样管理存储桶中的S3文件。
我使用了Apache MINA(v1.2.0)作为SFTP服务器,使用SftpSubsystemFactory和默认的FileSystemFactory(提供本地文件系统)工作正常。 我选择了Amazon-S3-FileSystem-NIO2(v1.3.0)作为FileSystem,它使用Apache AWS SDK,似乎是目前最好的选择。
public class S3FileSystemFactory implements FileSystemFactory {
    private URI uri = URI.create("localhost");

    public S3FileSystemFactory(URI uri){
        this.uri = uri;
    }

    public FileSystem createFileSystem(Session session) throws IOException {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        FileSystem s3FileSystem = FileSystems.newFileSystem(uri, new HashMap<String, Object>(), classLoader);
        return s3FileSystem;
    }
}

我只是将这个FileSystemFactory设置为MINA的文件系统工厂。

SshServer sshd = SshServer.setUpDefaultServer();
sshd.setKeyPairProvider(buildHostKeyProviderFromFile(hostKeyType));
sshd.setPasswordAuthenticator(createPasswordAuthenticator());
sshd.setPublickeyAuthenticator(AcceptAllPublickeyAuthenticator.INSTANCE);
sshd.setSubsystemFactories(createSubsystemFactories());
sshd.setFileSystemFactory(createFileSystemFactory());

URI uri = URI.create("s3:///s3.amazonaws.com/my_bucket"); 
FileSystemFactory s3FileSystemFactory = new S3FileSystemFactory(uri);
sshd.setFileSystemFactory(s3FileSystemFactory);

我可以使用FileZilla/命令行连接到这个服务器,但它会自动连接到“ImageTransfer”存储桶(而不是“my_bucket”)。我可以浏览其他存储桶,甚至子存储桶,但无法显示内容,一切看起来都像一个空目录。
通过文件系统,我可以列出目录内容,如下所示。
    Path p = s3FileSystem.getPath("/my_bucket");
    String contents = "";
    try (DirectoryStream<Path> stream = Files.newDirectoryStream(p, "*")) {
        for (Path file : stream) {
            contents += "\n \t - " + file.getFileName();
        }
    } catch (IOException | DirectoryIteratorException x) {}

我一直在查看s3fs、MINA和AWS代码(因为文档非常有限),但无法确定问题的源头。有人可以解释我做错了什么吗?
日志记录:
打开所有库的日志记录后,我只发现了一个问题。
"HEAD
application/x-www-form-urlencoded; charset=utf-8
Fri, 20 May 2016 09:58:07 GMT
/MYURL/."
2016-05-20 10:58:07.240 DEBUG 13323 --- [system-thread-1] c.a.http.impl.client.SdkHttpClient       : Stale connection check
2016-05-20 10:58:07.243 DEBUG 13323 --- [system-thread-1] c.a.http.impl.client.SdkHttpClient       : Attempt 1 to execute request
2016-05-20 10:58:07.434 DEBUG 13323 --- [system-thread-1] c.a.http.impl.client.SdkHttpClient       : Connection can be kept alive indefinitely
2016-05-20 10:58:07.435 DEBUG 13323 --- [system-thread-1] com.amazonaws.request                    : Received error response: com.amazonaws.services.s3.model.AmazonS3Exception: Not Found (Service: null; Status Code: 404; Error Code: 404 Not Found; Request ID: MYREQID), S3 Extended Request ID: MYEXTREQID
2个回答

3
问题是双重的。
首先,Apache MINA SSHD 要求任何它使用的 FileSystem 都必须有 permission 属性,这很奇怪,因为那是一个 POSIX 特定的属性,所以显然 Amazon-S3-FileSystem-NIO2 没有提供它。
其次,Apache MINA SSHD 在 S3FileSystemProvider 中调用(并要求)一个未实现的方法来获取 FileChannel
public FileChannel newFileChannel(Path path,
                                  Set<? extends OpenOption> options,
                                  FileAttribute<?>... attrs)

一个hacky的解决方案就是将POSIX读写权限硬编码到返回的S3属性中,并创建一个S3FileChannel,它只是调用现有的S3SeekableByteChannel上的方法。
这是我目前能想到的最好的解决方案。

1
我们分叉了Amazon-S3-FileSystem-NIO2并实现了缺失的部分,使得S3文件系统可以与Apache Mina SFTP配合使用。
您可以在这里找到仓库,并使用maven在本地构建它。
我们在MINA中使用它的方式如下:
public FileSystemFactory createFileSystemFactory(String bucketName) throws IOException, URISyntaxException {
    FileSystem fileSystem = FileSystems.newFileSystem(new URI("s3:///"), env, Thread.currentThread().getContextClassLoader());
    String bucketPath = fileSystem.getPath("/" + bucketName);

    return new VirtualFileSystemFactory(bucketPath);
}

我发现了您的分支。它是否有一个问题追踪器?它的许可证是什么(在某些地方,它说它在MIT下,在其他地方--Apahe 2.0)?可能添加一个 LICENSE.md 文件并澄清是个好主意。这个项目还在积极开发中吗? - carlspring

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接