загрузить файл S3 в Lambda с Node.js версии 8.10 - PullRequest
0 голосов
/ 25 сентября 2018

Я пытался (и не смог) загрузить файл из корзины S3, используя s3.getObject в Node версии 8.10.

Я нашел отличный пост с ответом, который почти работал здесь , но синтаксис не совсем работает в 8.10, и как бы я ни перестраивал код, я не могу его получитьна работу.

var AWS = require('aws-sdk')
var s3 = new AWS.S3();

var fileData = null;

exports.handler = (event, context, callback) => {
    console.log('I am in the main procedure');
    var params = {
        Bucket: "change_for_your_bucket",
        Key:  "change_to_your_json_file"
    };

    fetchDataFromS3(params);
    console.log('I am in the main procedure, the function above should be waiting but it is not');
    waitForFileLoadBeforeDoingSomething(event, context, callback);

    const s = JSON.stringify(fileData.Body.toString('utf-8'));
    console.log(`this is the file: ${s}`);
    console.log('I have the file!(dg.2)');    

};

function fetchDataFromS3(params)
{
    console.log('-------------- fetchDataFromS3:Start -------------------------');
    // gets the object from s3 => promise
    const uploadPromise = s3.getObject(params).promise();

    // returns the body of the s3 object
    uploadPromise
            .then(function(data) {
                console.log("successfully downloaded data");
                fileData = data.Body.toString();

            })
            .catch(function download(err) {console.log(err,err.stack); throw err;});


    console.log('-------------- fetchDataFromS3:Done -------------------------');
}



function waitForFileLoadBeforeDoingSomething(event, context, callback){
    if(!fileData){
        console.log('No file available to me as yet, lets sleep for a bit');
        setTimeout(function(){
            waitForFileLoadBeforeDoingSomething(event, context, callback);
        }, 300);
    } 
}

вывод выглядит следующим образом.

Function Logs:
START RequestId: cb16f155-c0d7-11e8-ad01-f5991c5adaaf Version: $LATEST
2018-09-25T15:29:29.759Z    cb16f155-c0d7-11e8-ad01-f5991c5adaaf    I am in the main procedure
2018-09-25T15:29:29.759Z    cb16f155-c0d7-11e8-ad01-f5991c5adaaf    -------------- fetchDataFromS3:Start -------------------------
2018-09-25T15:29:29.811Z    cb16f155-c0d7-11e8-ad01-f5991c5adaaf    -------------- fetchDataFromS3:Done -------------------------
2018-09-25T15:29:29.811Z    cb16f155-c0d7-11e8-ad01-f5991c5adaaf    I am in the main procedure, the function above should be waiting but it is not
2018-09-25T15:29:29.811Z    cb16f155-c0d7-11e8-ad01-f5991c5adaaf    No file available to me as yet, lets sleep for a bit
2018-09-25T15:29:29.812Z    cb16f155-c0d7-11e8-ad01-f5991c5adaaf    TypeError: Cannot read property 'Body' of null
    at exports.handler (/var/task/dg3.js:17:39)

Вы видите, что я не попал в строку "успешно загруженные данные" и не могу работатьесли я допустил ошибку, и функция все еще работает асинхронно, или если у меня неправильный синтаксис обещания.

1 Ответ

0 голосов
/ 25 сентября 2018

Прежде всего, вы должны изменить метод точки входа.Как вы упомянули, прежде чем пытаться использовать среду выполнения узла 8.10, затем следующая часть кода:

exports.handler = (event, context, callback) => {}

Вам нужно изменить на:

export async function <function_name>(event) {}

ref: https://aws.amazon.com/blogs/compute/node-js-8-10-runtime-now-available-in-aws-lambda/

Тогда ваш путь к этой функции должен быть:

<module_name>.<function_name>

Кроме того, вам не нужна следующая часть кода:

function waitForFileLoadBeforeDoingSomething(event, context, callback){
    if(!fileData){
        console.log('No file available to me as yet, lets sleep for a bit');
        setTimeout(function(){
            waitForFileLoadBeforeDoingSomething(event, context, callback);
        }, 300);
    } 
}

Тогда избавьтесь от varдекларация.Не связывайтесь с областью.Просто используйте:

const AWS = require('aws-sdk');

Следующим шагом является создание экземпляра S3:

const S3 = new AWS.S3({region: process.env.AWS_REGION, apiVersion: '2006-03-01'});
// with region of your AWS account and current API verstion;

Объявите параметры для вашего метода выборки:

const params = 
{
  Bucket: 'STRING_VALUE', // a path to your Bucket
  Key: 'STRING_VALUE' // a key (literally a path to your file)
}

ref: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getObject-property

И вам не нужно структурировать ваше событие, потому что оно уже структурировано:

const s = JSON.stringify(fileData.Body.toString('utf-8'));

И, наконец:

try
{
    const result = await S3.getObject(params).promise();
    // if successful then:
    console.log(`Check the result: ${result}`);
}
catch (ex) // if an error occured
{
     console.error(ex);
}

Кроме того, убедитесь, чтовремя выполнения 5 минут (это только для целей отладки после того, как вы можете отрегулировать) и увеличение памяти лямбды (также для целей тестирования).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...