4
votes

Has anyone successfully implemented a Java based request handler for S3 events?

My class:

package example;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.s3.model.S3Event;

public class Hello implements RequestHandler<S3Event, String> {
    public String handleRequest(S3Event event, Context context) {
        return "Success";
    }
}

Error message:

An error occurred during JSON parsing: java.lang.RuntimeException java.lang.RuntimeException: An error occurred during JSON parsing Caused by: java.io.UncheckedIOException: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of com.amazonaws.services.s3.model.S3Event out of START_OBJECT token at [Source: lambdainternal.util.NativeMemoryAsInputStream@6108b2d7; line: 1, column: 1] Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of com.amazonaws.services.s3.model.S3Event out of START_OBJECT token at [Source: lambdainternal.util.NativeMemoryAsInputStream@6108b2d7; line: 1, column: 1] at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148) at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:835) at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:831) at com.fasterxml.jackson.databind.deser.std.EnumDeserializer._deserializeOther(EnumDeserializer.java:137) at com.fasterxml.jackson.databind.deser.std.EnumDeserializer.deserialize(EnumDeserializer.java:89) at com.fasterxml.jackson.databind.deser.std.EnumDeserializer.deserialize(EnumDeserializer.java:18) at com.fasterxml.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:1441) at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:1047)

1
Do you have the Lambda function configured to be notified directly from the S3 bucket? If you have SNS configured "in the middle" that could be causing the error you are seeing since the JSON payloads would not match. - JaredHatfield

1 Answers

15
votes

The solution was to take S3EventNotification. Wish that was covered in the AWS documentation. I like the Lambda concept but there is not much for documentation or examples out there.

public void mergeGLAU(S3EventNotification notification, Context context) {
    try {
        for (S3EventNotificationRecord record : notification.getRecords()) {
            System.out.println(record.getEventSource());
            System.out.println(record.getEventName());
            System.out.println(record.getS3().getBucket().getName());
            System.out.println(record.getS3().getObject().getKey());
        }
    }
    catch (Exception e) {
        e.printStackTrace();
    }
}