2

I'm writing an AWS Lambda that will listen for DynamoDB Streams events and use those events to update an Elasticsearch index. My code is written using the Quarkus framework, and I've found guides and examples that show how to do this, so my code looks like this:

import javax.inject.Named;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.events.DynamodbEvent;

/**
 * The AWS Lambda used to update an Elasticsearch index when new records are
 * written to DynamoDB
 * 
 * @author XXX
 *
 */
@Named("dynamoDBSearchIndexEventHandler")
public class DynamoDBSearchIndexEventHandler implements RequestHandler<DynamodbEvent, Void> {

    /**
     * Logger for this class
     */
    private static final Logger logger = LoggerFactory.getLogger(DynamoDBSearchIndexEventHandler.class);

    /*
     * (non-Javadoc)
     *
     * @see
     * com.amazonaws.services.lambda.runtime.RequestHandler#handleRequest(java.lang.
     * Object, com.amazonaws.services.lambda.runtime.Context)
     */
    @Override
    public Void handleRequest(DynamodbEvent input, Context context) {
        if (logger.isDebugEnabled()) {
            logger.debug("handleRequest(DynamodbEvent, Context) - start"); //$NON-NLS-1$
        }

        if (logger.isDebugEnabled()) {
            logger.debug("handleRequest(DynamodbEvent, Context) - input={}", input); //$NON-NLS-1$
        }

        if (logger.isDebugEnabled()) {
            logger.debug("handleRequest(DynamodbEvent, Context) - end"); //$NON-NLS-1$
        }
        return null;
    }

}

When I write an item to my DynamoDB table I see that my Lambda is being called, however I get the following Exception:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `java.util.Date` from Floating-point value (token `JsonToken.VALUE_NUMBER_FLOAT`)

I have no idea why serialization is failing. If I modify my Lambda to take Map<String, AttributeValue> as the input instead of DynamodbEvent it works just fine. I'm able to see the Map populated with all of the expected values. However, I cannot get a DynamodbEvent that I can then subsequently use to iterate over its DynamodbStreamRecord objects for updating my index.

Any idea what could be the problem here?

2 Answers 2

0

I frequently have issues with the Java Lambda's and deserializing data. At this point I've given up and just use JsonPath:

public class S3EventLambdaHandler implements RequestStreamHandler {
    public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) {

        try {
            List<String> keys = JsonPath.read(inputStream, "$.Records[*].s3.object.key");

            for( String nextKey: keys )
                System.out.println(nextKey);
        }
        catch( IOException ioe ) {
            context.getLogger().log("caught IOException reading input stream");
        }
    }

This is handling an S3 event but the concepts should be the same.

Sign up to request clarification or add additional context in comments.

Comments

0

Turns out, this is a known issue with Quarkus. I used the ObjectMapperCustomizer provided in the issue record and everything is working fine now.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.