Как собрать и отправить файл с S3 на внешний SFTP с помощью Lambda + Java?

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

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

Если бы у вас был какой-то совет или, может быть, какой-нибудь простой пример реализации, который хотя бы близок к этому, было бы неплохо!

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
6 615
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Сначала вам нужно настроить корзину S3 для отправки новых событий объекта в вашу функцию Lambda.

В вашей лямбда-функции вы бы вытащили путь к объекту S3 из объекта события. Затем вам нужно использовать AWS SDK для Java , чтобы загрузить файл с S3 в папку /tmp функции Lambda. Затем ваша функция выполняет все необходимые изменения в файле в папке /tmp. Наконец, используйте библиотеку SFTP для Java, чтобы отправить файл из папки /tmp на SFTP-сервер.

Ответ принят как подходящий

Вот полный пример получения файла с S3 и его сохранения на SFTP.

Я добавил следующие библиотеки, чтобы этот модуль Java работал:

  • Лямбда-ядро

  • Гугл Гсон

  • SDK для AWS S3

  • СШЖ

    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;
            }
        }
    }
    

Большое спасибо, что научил меня дружище!

Thai Rodrigues 15.12.2020 15:40

Другие вопросы по теме