簡體   English   中英

使用AWS Lambda函數從SNS主題觸發器讀取和復制S3庫存數據

[英]Read and Copy S3 inventory data from SNS topic trigger with AWS lambda function

我是數據分析師,並且是AWS lambda函數的新手。 我有一個s3存儲桶,用於存儲來自數據倉庫的庫存數據,該數據是使用“ S3管理”選項卡下的“庫存”功能生成的。

因此,可以說庫存數據(報告)如下所示:

s3://my-bucket/allobjects/data/report-1.csv.gz
s3://my-bucket/allobjects/data/report-2.csv.gz
s3://my-bucket/allobjects/data/report-3.csv.gz

無論文件內容如何,​​我都有s3:// my-bucket / allobjects / data /的事件設置,該事件在GET或PUT之類的任何事件期間都會通知SNS主題。 (由於嚴格的管理,我無法更改此工作流程)

現在,我嘗試使用此SNS主題作為觸發器來創建Lambda函數,並簡單地將S3庫存功能生成的庫存報告文件移至

s3://my-bucket/allobjects/data/ 

並重新分區如下:

s3://my-object/allobjects/partitiondata/year=2019/month=01/day=29/report-1.csv.gz
s3://my-object/allobjects/partitiondata/year=2019/month=01/day=29/report-2.csv.gz
s3://my-object/allobjects/partitiondata/year=2019/month=01/day=29/report-3.csv.gz

如何使用lambda函數(可以使用node.js或python)讀取SNS主題來實現此目的? 任何幫助表示贊賞。

我嘗試了一些類似的方法,這些方法基於我在網上發現的一些通用代碼,但沒有幫助。

console.log('Loading function');

var AWS = require('aws-sdk');  
AWS.config.region = 'us-east-1';

exports.handler = function(event, context) {  
console.log("\n\nLoading handler\n\n");
var sns = new AWS.SNS();

sns.publish({
    Message: 'File(s) uploaded successfully',
    TopicArn: 'arn:aws:sns:_my_ARN'
}, function(err, data) {
    if (err) {
        console.log(err.stack);
        return;
    }
    console.log('push sent');
    console.log(data);
    context.done(null, 'Function Finished!');  
});
};

首選方法是讓Amazon S3事件直接觸發AWS Lambda函數。 但是由於您不能更改此端口,因此流程如下:

  • Amazon S3事件將向Amazon SNS主題發送消息。
  • AWS Lambda函數已訂閱SNS主題,因此將觸發它並從S3接收消息。
  • Lambda函數提取Bucket和Key,然后調用S3將copy_object()移到另一個位置。 (沒有移動命令。您將需要對象復制到新的存儲桶/密鑰。)

event字段的內容類似於:

{
    "Records": [
        {
            "EventSource": "aws:sns",
            "EventVersion": "1.0",
            "EventSubscriptionArn": "...",
            "Sns": {
                "Type": "Notification",
                "MessageId": "1c3189f0-ffd3-53fb-b60b-dd3beeecf151",
                "TopicArn": "...",
                "Subject": "Amazon S3 Notification",
                "Message": "{\"Records\":[{\"eventVersion\":\"2.1\",\"eventSource\":\"aws:s3\",\"awsRegion\":\"ap-southeast-2\",\"eventTime\":\"2019-01-30T02:42:07.129Z\",\"eventName\":\"ObjectCreated:Put\",\"userIdentity\":{\"principalId\":\"AWS:AIDAIZCFQCOMZZZDASS6Q\"},\"requestParameters\":{\"sourceIPAddress\":\"54.1.1.1\"},\"responseElements\":{\"x-amz-request-id\":\"...",\"x-amz-id-2\":\"..."},\"s3\":{\"s3SchemaVersion\":\"1.0\",\"configurationId\":\"...\",\"bucket\":{\"name\":\"stack-lake\",\"ownerIdentity\":{\"principalId\":\"...\"},\"arn\":\"arn:aws:s3:::stack-lake\"},\"object\":{\"key\":\"index.html\",\"size\":4378,\"eTag\":\"...\",\"sequencer\":\"...\"}}}]}",
                "Timestamp": "2019-01-30T02:42:07.212Z",
                "SignatureVersion": "1",
                "Signature": "...",
                "SigningCertUrl": "...",
                "UnsubscribeUrl": "...",
                "MessageAttributes": {}
            }
        }
    ]
}

因此,需要從Message提取上載對象的名稱。

您可以使用如下代碼:

import json

def lambda_handler(event, context):

    for record1 in event['Records']:
        message = json.loads(record1['Sns']['Message'])

        for record2 in message['Records']:

            bucket = record2['s3']['bucket']['name'])
            key = record2['s3']['object']['key'])

            # Do something here with bucket and key

    return {
        'statusCode': 200,
        'body': json.dumps(event)
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM