1

S3イベントペイロードを持つSNSイベントを使用してラムダ関数を呼び出そうとしています(S3プット - > SNSトピックにパブリッシュされたイベントをトリガする - >ラムダ関数)が、実際のS3イベント情報にアクセスするには、JsonNodeとしてアクセスすることしかできず、より良い(例えば、逆直列化)必要があることがわかります。Lambda関数がSNS経由でヌルS3イベントオブジェクトを受信しました

私は本当にため、私はここで見つけるのコメントに、私は私のラムダ関数はS3EventNotificationを受け入れるかもしれないと思った:強く型付けされたS3 EventNotification項目を表し

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

ヘルパークラスはへ を送りましたSQS、SNS、またはラムダ。

したがって、S3EventNotificationをPOJOとして受け取るにはどうすればよいですか?私はまた、次の試してみました

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

public class LambdaFunction implements RequestHandler<S3EventNotification, Object>{ 

    @Override 
    public Object handleRequest(S3EventNotification input, Context context) { 
     System.out.println(JsonUtil.MAPPER.writeValueAsString(input));  
     return 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にデシリアライズしようとすると、フィールドに違いがあります。

{ 
    "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に応じています:私は本当にこれは以下を返し

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

...手動JsonNodeを歩いする必要がありますする必要はありません。 77およびaws-java-sdk-sns-1.11.77を参照してください。

答えて

1

ラムダがSNSイベントを消費するため、S3Eventの代わりにSNSEventを処理する必要があります。以下のコードは私のために働く。

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

あなたの最初のlambada関数が結論につながりますが、実際には私は2日前に間違っていました。上記のコードは私のために働く。 –

関連する問題