У меня есть файлы, которые будут ежедневно помещаться в корзину S3, и мне нужно создать лямбда-функцию для пересылки этого файла на внешний SFTP. (Используя Java)
Моя проблема в том, что я не уверен, как установить это соединение с S3 из моей лямбды, чтобы собрать файл (в конечном итоге отредактировать его, например, для переименования), а затем перенаправить на SFTP. Можно ли вызвать ее, как мы, если нам нужно вызвать другую лямбда-функцию? Пример. Или мне придется подключаться, как если бы я был вне среды AWS?
Если бы у вас был какой-то совет или, может быть, какой-нибудь простой пример реализации, который хотя бы близок к этому, было бы неплохо!




Сначала вам нужно настроить корзину S3 для отправки новых событий объекта в вашу функцию Lambda.
В вашей лямбда-функции вы бы вытащили путь к объекту S3 из объекта события. Затем вам нужно использовать AWS SDK для Java , чтобы загрузить файл с S3 в папку /tmp функции Lambda. Затем ваша функция выполняет все необходимые изменения в файле в папке /tmp. Наконец, используйте библиотеку SFTP для Java, чтобы отправить файл из папки /tmp на SFTP-сервер.
Вот полный пример получения файла с S3 и его сохранения на SFTP.
Я добавил следующие библиотеки, чтобы этот модуль Java работал:
import com.amazonaws.regions.Regions;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.LambdaLogger;
import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.S3Object;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.sftp.SFTPClient;
import net.schmizz.sshj.xfer.FileSystemFile;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
public class S3ToSFTPTest implements RequestStreamHandler {
private LambdaLogger logger;
@Override
public void handleRequest(InputStream input, OutputStream output, Context context) throws IOException {
logger = context.getLogger();
AmazonS3 s3Client = AmazonS3ClientBuilder.standard().withRegion(Regions.US_EAST_1).build();
// s3 client
if (s3Client == null) {
logger.log("S3 Client is null - can't continue!");
sendResponse(context, new S3ToSFTPTestResponse(false), output);
return;
}
String bucketName = "==== S3 BUCKET NAME === = ";
// s3 bucket - make sure it exist
if (!s3Client.doesBucketExistV2(bucketName)) {
logger.log("S3 Bucket does not exists - can't continue!");
sendResponse(context, new S3ToSFTPTestResponse(false), output);
return;
}
String fileName = "==== S3 FILE NAME === = ";
File localFile = null;
try {
localFile = File.createTempFile(fileName, "");
// get S3Object
S3Object s3Object = s3Client.getObject(bucketName, fileName);
// get stream from S3Object
InputStream inputStream = s3Object.getObjectContent();
// write S3Object stream into a temp file
Files.copy(inputStream, localFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
} catch (Exception e) {
logger.log("Failed to get file from S3: " + e.toString());
}
if (localFile == null) {
sendResponse(context, new S3ToSFTPTestResponse(false), output);
return;
}
// now, you have the file stored locally
// modify it as you need to
// .....
// finally, send the file to SFTP
boolean fileSaved = saveFilesToSFTP(context, localFile);
logger.log("fileSaved: " + fileSaved);
sendResponse(context, new S3ToSFTPTestResponse(true), output);
}
public boolean saveFilesToSFTP(Context context, File... files) {
// this is for test only - In real application, I would suggest that
// do NOT store these information in the code.
// You should use service like Secrets Manager or Parameter Store
final String sftpHostname = "==== SFTP Hostname === = ";
final String sftpUsername = "==== SFTP Username === = ";
final String sftpPassword = "==== SFTP Password === = ";
String remoteFolderPath = "/root/S3Files/";
try {
SSHClient ssh = new SSHClient();
ssh.addHostKeyVerifier((hostname1, port, key) -> true);
ssh.connect(sftpHostname);
logger.log("SSHClient Connected!");
try {
ssh.authPassword(sftpUsername, sftpPassword);
logger.log("SSHClient Authenticated!");
try (SFTPClient sftp = ssh.newSFTPClient()) {
for(File file : files) {
sftp.put(new FileSystemFile(file), remoteFolderPath);
}
} catch (Exception e) {
logger.log("failed to get SFTPClient: " + e.toString());
return false;
}
} finally {
ssh.disconnect();
}
} catch (Exception e) {
logger.log("SFTP connection failed: " + e.toString());
return false;
}
return true;
}
public void sendResponse(Context context, S3ToSFTPTestResponse response, OutputStream output) {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String responseStr = gson.toJson(response);
logger.log("response:\n" + responseStr);
try {
OutputStreamWriter writer = new OutputStreamWriter(output, StandardCharsets.UTF_8);
writer.write(responseStr);
writer.close();
} catch (Exception e) {
logger.log("failed to send response: " + e.toString());
}
}
public static class S3ToSFTPTestResponse implements Serializable {
private boolean success;
public S3ToSFTPTestResponse() {
}
public S3ToSFTPTestResponse(boolean success) {
this.success = success;
}
public boolean isSuccess() {
return success;
}
}
}
Большое спасибо, что научил меня дружище!