Merge pull request #1068 from hapifhir/do-ftpclient-enhancement

Sets FTPClient file transfers as binary and ensures stream closure
This commit is contained in:
Grahame Grieve 2023-01-14 08:46:40 +11:00 committed by GitHub
commit c37455a41e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 12 deletions

View File

@ -1,5 +1,6 @@
package org.hl7.fhir.utilities; package org.hl7.fhir.utilities;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPReply; import org.apache.commons.net.ftp.FTPReply;
@ -52,15 +53,16 @@ public class FTPClient {
else { else {
clientImpl.connect(server); clientImpl.connect(server);
} }
//clientImpl.setFileTransferMode(FTP.BINARY_FILE_TYPE);
clientImpl.login(user, password); clientImpl.login(user, password);
clientImpl.getSystemType();
int reply = clientImpl.getReplyCode(); int reply = clientImpl.getReplyCode();
if(!FTPReply.isPositiveCompletion(reply)) { if(!FTPReply.isPositiveCompletion(reply)) {
clientImpl.disconnect(); clientImpl.disconnect();
throw new IOException("FTP server refused connection."); throw new IOException("FTP server refused connection. Reply code: " + reply);
} }
} }
@ -85,8 +87,20 @@ public class FTPClient {
*/ */
public void upload(String source, String path) throws IOException { public void upload(String source, String path) throws IOException {
String resolvedPath = resolveRemotePath(path); String resolvedPath = resolveRemotePath(path);
FileInputStream localStream = new FileInputStream(new File(source)); FileInputStream localStream = new FileInputStream(source);
clientImpl.setFileType(FTP.BINARY_FILE_TYPE);
clientImpl.storeFile( resolvedPath, localStream); clientImpl.storeFile( resolvedPath, localStream);
localStream.close();
int reply = clientImpl.getReplyCode();
if(!FTPReply.isPositiveCompletion(reply)) {
throw new IOException("Error uploading file. Reply code: " + reply);
}
}
public void disconnect() throws IOException {
clientImpl.disconnect();
} }
} }

View File

@ -1,6 +1,7 @@
package org.hl7.fhir.utilities; package org.hl7.fhir.utilities;
import org.apache.commons.io.IOUtils;
import org.hl7.fhir.utilities.tests.ResourceLoaderTests; import org.hl7.fhir.utilities.tests.ResourceLoaderTests;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterAll;
@ -11,12 +12,14 @@ import org.mockftpserver.fake.FakeFtpServer;
import org.mockftpserver.fake.UserAccount; import org.mockftpserver.fake.UserAccount;
import org.mockftpserver.fake.filesystem.*; import org.mockftpserver.fake.filesystem.*;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertTrue;
@TestInstance(TestInstance.Lifecycle.PER_CLASS) @TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class FTPClientTest implements ResourceLoaderTests { public class FTPClientTest implements ResourceLoaderTests {
@ -30,6 +33,7 @@ public class FTPClientTest implements ResourceLoaderTests {
public static final String DUMMY_FILE_TO_UPLOAD = "dummyFileToUpload"; public static final String DUMMY_FILE_TO_UPLOAD = "dummyFileToUpload";
public static final int FAKE_FTP_PORT = 8021; public static final int FAKE_FTP_PORT = 8021;
public static final String DUMMY_FILE_CONTENT = "Dummy file content\nMore content\n";
FakeFtpServer fakeFtpServer; FakeFtpServer fakeFtpServer;
@ -47,6 +51,8 @@ public class FTPClientTest implements ResourceLoaderTests {
Path dummyFileToUploadPath; Path dummyFileToUploadPath;
Path dummyUploadedFilePath; Path dummyUploadedFilePath;
String dummyFileContent;
@BeforeAll @BeforeAll
public void setup() throws IOException { public void setup() throws IOException {
setupDummyFileToUpload(); setupDummyFileToUpload();
@ -55,7 +61,14 @@ public class FTPClientTest implements ResourceLoaderTests {
} }
private void setupDummyFileToUpload() throws IOException { private void setupDummyFileToUpload() throws IOException {
dummyFileContent = createDummyFileContent();
dummyFileToUploadPath = Files.createTempFile("dummyFtpFileToUpload", "dummy"); dummyFileToUploadPath = Files.createTempFile("dummyFtpFileToUpload", "dummy");
Files.write(dummyFileToUploadPath, DUMMY_FILE_CONTENT.getBytes(StandardCharsets.UTF_8));
}
private String createDummyFileContent() {
return DUMMY_FILE_CONTENT;
} }
public void setupFakeFtpServer() throws IOException { public void setupFakeFtpServer() throws IOException {
@ -74,6 +87,7 @@ public class FTPClientTest implements ResourceLoaderTests {
fileSystem.add(new FileEntry(dummyFileToDeletePath.toFile().getAbsolutePath())); fileSystem.add(new FileEntry(dummyFileToDeletePath.toFile().getAbsolutePath()));
//fileSystem.add(new FileEntry("c:\\data\\run.exe")); //fileSystem.add(new FileEntry("c:\\data\\run.exe"));
fakeFtpServer.setFileSystem(fileSystem); fakeFtpServer.setFileSystem(fileSystem);
fakeFtpServer.start(); fakeFtpServer.start();
} }
@ -102,17 +116,11 @@ public class FTPClientTest implements ResourceLoaderTests {
FTPClient client = connectToFTPClient(); FTPClient client = connectToFTPClient();
String deleteFilePath = dummyFileToDeletePath.toFile().getAbsolutePath(); String deleteFilePath = dummyFileToDeletePath.toFile().getAbsolutePath();
assertTrue(fakeFtpServer.getFileSystem().exists(deleteFilePath)); assertTrue(fakeFtpServer.getFileSystem().exists(deleteFilePath));
client.delete( RELATIVE_PATH_2 + "/" + DUMMY_FILE_TO_DELETE); client.delete( RELATIVE_PATH_2 + "/" + DUMMY_FILE_TO_DELETE);
assertFalse(fakeFtpServer.getFileSystem().exists(deleteFilePath)); assertFalse(fakeFtpServer.getFileSystem().exists(deleteFilePath));
} }
@NotNull @NotNull
@ -135,6 +143,10 @@ public class FTPClientTest implements ResourceLoaderTests {
assertTrue(fakeFtpServer.getFileSystem().exists(uploadFilePath)); assertTrue(fakeFtpServer.getFileSystem().exists(uploadFilePath));
FileEntry fileEntry= (FileEntry)fakeFtpServer.getFileSystem().getEntry(uploadFilePath);
InputStream inputStream = fileEntry.createInputStream();
byte[] bytes = IOUtils.toByteArray(inputStream);
String actualContent = new String(bytes, StandardCharsets.UTF_8);
assertEquals(DUMMY_FILE_CONTENT,actualContent);
} }
} }