2016-05-17 55 views
3

所以我試圖創建一個Java SFTP服務器,它充當Apache S3存儲桶的前端。您通過SFTP進行連接並管理存儲桶中的S3文件,就像它們是SFTP服務器上的文件一樣。爲什麼s3fs不能像Apache MINA SSHD一樣使用普通文件系統?

我已經使用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; 
    } 
} 

我只是MINA

設置以此爲 FileSystemFactory
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/Command Line連接到此服務器,但它會自動連接到ImageTransfer存儲桶(而不是my_bucket)。我可以導航到其他存儲桶,甚至是子存儲桶,但無法顯示內容,所有內容都看起來像一個空目錄。

這可以通過FileSystemI'm using做,我可以列出目錄的內容,像這樣

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 

回答

1

的問題是雙重的。

首先,Apache的MINA SSHD requirespermission屬性存在對於其使用的所有FileSystem,這是奇怪的,這是一個POSIX特定屬性,這樣明顯Amazon-S3-FileSystem-NIO2沒有提供它。

其次,Apache的MINA SSHD調用(並且要求)在S3FileSystemProvider未實現的方法得到的一個FileChannel

public FileChannel newFileChannel(Path path, 
            Set<? extends OpenOption> options, 
            FileAttribute<?>... attrs) 

哈克解決方案只是硬編碼POSIX讀/寫權限到S3屬性返回,並創建一個S3FileChannel,只需調用現有的S3SeekableByteChannel上的方法。
這是我現在可以提出的最佳解決方案。

0

我們分叉了Amazon-S3-FileSystem-NIO2並實現了缺失的事情,以便S3 FileSystem可以與Apache Mina SFTP協同工作。

你可以找到回購here並使用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); 
} 
相關問題