1

我試圖使用攜帶S3事件負載的SNS事件調用Lambda函數(即S3 Put - >觸發發佈到SNS主題的事件 - >傳遞給訂閱Lambda函數),但似乎我能夠獲得實際的S3事件信息的唯一方法是以JsonNode的身份訪問它,並且我知道必須有更好的(例如反序列化)。通過SNS接收空S3事件對象的Lambda函數

我真的以爲我可以有我的lambda函數接受S3EventNotification,由於意見,我發現這裏:

https://github.com/aws/aws-sdk-java/blob/master/aws-java-sdk-s3/src/main/java/com/amazonaws/services/s3/event/S3EventNotification.java

代表一個強類型S3項目通知項目發送 給助手類SQS,SNS或Lambda。

那麼,我該如何接收S3EventNotification作爲POJO?

以下是我已經嘗試了各種方式:

public class LambdaFunction implements RequestHandler<S3EventNotification, Object>{ 

    @Override 
    public Object handleRequest(S3EventNotification input, Context context) { 
     System.out.println(JsonUtil.MAPPER.writeValueAsString(input));  
     return null; 
    } 
} 

,導致:

{ 
    "Records": [ 
     { 
      "awsRegion": null, 
      "eventName": null, 
      "eventSource": null, 
      "eventTime": null, 
      "eventVersion": null, 
      "requestParameters": null, 
      "responseElements": null, 
      "s3": null, 
      "userIdentity": null 
     } 
    ] 
} 

我也曾嘗試以下(注:JsonUtil.MAPPER剛剛返回傑克遜ObjectMapper):

public class LambdaFunction { 
    public Object handleRequest(S3EventNotification records, Context context) throws IOException { 
     System.out.println(JsonUtil.MAPPER.writeValueAsString(records));   
     return null; 
    } 
} 

該返回與以前相同:

{ 
    "Records": [ 
    { 
     "awsRegion": null, 
     "eventName": null, 
     "eventSource": null, 
     "eventTime": null, 
     "eventVersion": null, 
     "requestParameters": null, 
     "responseElements": null, 
     "s3": null, 
     "userIdentity": null 
    } 
    ] 
} 

我可以通過簡單地接收SNSEvent訪問S3事件有效載荷,但是當我嘗試將msg有效載荷反序列化到S3EventRecord或S3EventNotification時,字段中存在差異。我真的不希望有手動走在JsonNode ...

public class LambdaFunction { 
    public Object handleRequest(SNSEvent input, Context context) throws IOException { 
    System.out.println("Records: " + JsonUtil.MAPPER.writeValueAsString(input)); 

    for (SNSEvent.SNSRecord record : input.getRecords()) { 
     System.out.println("Record Direct: " + record.getSNS().getMessage()); 
     JsonNode node = JsonUtil.MAPPER.readTree(record.getSNS().getMessage()); 
     JsonNode recordNode = ((ArrayNode) node.get("Records")).get(0); 
     System.out.println(recordNode.toString()); 
     S3EventNotification s3events = JsonUtil.MAPPER.readValue(record.getSNS().getMessage(), new TypeReference<S3EventNotification>() {}); 
     System.out.println(s3events == null); 

    } 
    return null; 
} 

這將返回以下:

{ 
    "eventVersion": "2.0", 
    "eventSource": "aws:s3", 
    "awsRegion": "us-east-1", 
    "eventTime": "2017-03-04T05:34:25.149Z", 
    "eventName": "ObjectCreated:Put", 
    "userIdentity": { 
    "principalId": "AWS:XXXXXXXXXXXXX" 
    }, 
    "requestParameters": { 
    "sourceIPAddress": "<<IP ADDRESS>>" 
    }, 
    "responseElements": { 
    "x-amz-request-id": "XXXXXXXX", 
    "x-amz-id-2": "XXXXXXXXXXXXX=" 
    }, 
    "s3": { 
    "s3SchemaVersion": "1.0", 
    "configurationId": "NotifyNewRawArticle", 
    "bucket": { 
     "name": "MYBUCKET", 
     "ownerIdentity": { 
     "principalId": "XXXXXXXXXXXXXXX" 
     }, 
     "arn": "arn:aws:s3:::MYBUCKET" 
    }, 
    "object": { 
     "key": "news\/test", 
     "size": 0, 
     "eTag": "d41d8cd98f00b204e9800998ecf8427e", 
     "sequencer": "0058BA51E113A948C3" 
    } 
    } 
} 

Unrecognized field "sequencer" (class com.amazonaws.services.s3.event.S3EventNotification$S3ObjectEntity), not marked as ignorable (4 known properties: "size", "versionId", "eTag", "key"]) 

我根據AWS-java的SDK-s3-1.11。 77和aws-java-sdk-sns-1.11.77。

回答

1

您應該處理SNSEvent而不是S3Event,因爲lambda消耗了您的SNS事件。下面的代碼適用於我。

public Object handleRequest(SNSEvent request, Context context) { 
    request.getRecords().forEach(snsRecord -> { 
     System.out.println("Record Direct: " +snsRecord.getSNS().getMessage()); 
     S3EventNotification s3eventNotifcation=S3Event.parseJson(snsRecord.getSNS().getMessage()); 
     System.out.println(s3eventNotifcation.toJson()); 
     } 
    ); 
} 
+1

從打印出包含序列化S3Event對象的SNSMessage中可以明顯看出。無論如何,我試圖將它反序列化爲一個POJO,並且因爲它應該與S3Event匹配,所以我認爲它應該可以工作,但這不是出於我上面概述的原因。 – Brooks

+0

你的第一個拉巴達功能導致了結論,實際上我剛剛在2天前弄錯了。上面的代碼適用於我。 –