AWS DynamoDB trigger using Lambda in JAVA

10,900

Solution 1

This code worked for me. You can use it to receive and process DynamoDB events in a Lambda function -

public class Handler implements RequestHandler<DynamodbEvent, Void> {

    @Override
    public Void handleRequest(DynamodbEvent dynamodbEvent, Context context) {

        for (DynamodbStreamRecord record : dynamodbEvent.getRecords()) {

            if (record == null) {
                continue;
            }

            // Your code here
        }

        return null;
    }
}

Similarly, you can use SNSEvent and SNSRecord to handle Amazon SNS events.

Solution 2

This worked for me - case DynamoDB stream events:

import com.amazonaws.services.lambda.runtime.RequestHandler;
...

public class DynamoStreamHandler implements RequestHandler<Object, Void> {
    @Override
    public Void handleRequest(Object o, Context context) {

        LinkedHashMap lhm = (LinkedHashMap) o;
        ...etc.
    }
}

It seems they use a customized JSON mapper which utilizes Map and List objects. It's quite straightforward (but tedious) to verify this for other event types by testing and print-outing logs. (sigh)

EDIT: If ~5 MB overhead is ok, you can use DynamodbEvent.DynamodbStreamRecord provided by aws-lambda-java-events library v1.1.0 as described in AWS Lambda Walkthrough 3: Process Amazon DynamoDB Events (Java) in AWS Lambda Documentation.

Solution 3

Create a handler that takes an InputStream, read in the contents of the InputStream (which is just JSON) and then deserialize it to get the data that you need.

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import com.amazonaws.services.lambda.runtime.Context; 

public class MyHandler {    
    public void handler(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {           
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        int letter;        
        while((letter = inputStream.read()) != -1)
        {
            baos.write(letter);                     
        }        

        //Send the contents of baos to a JSON deserializer ...          
    }      
}

It's a bit cumbersome, but as far as I'm aware AWS doesn't currently provide a higher level Java lambda interface for consuming DynamoDB Streams. I have a full blown example here with details on how I deserialized the stream of JSON to get Java objects for the data.

Share:
10,900
Ioannis Tsiokos
Author by

Ioannis Tsiokos

Updated on June 18, 2022

Comments

  • Ioannis Tsiokos
    Ioannis Tsiokos almost 2 years

    I am trying to trigger an AWS lambda function written in Java, on dynamodb stream events. Amazon has a guide for the same, using NodeJS here http://docs.aws.amazon.com/lambda/latest/dg/wt-ddb-create-test-function.html

    The testing input for NodeJS (from the above link) looks like an SNS event, so I tried to use the corresponding SNSEvent class in Java as an input to my handler method.

    import com.amazonaws.services.lambda.runtime.Context;
    import com.amazonaws.services.lambda.runtime.LambdaLogger;
    import com.amazonaws.services.lambda.runtime.events.SNSEvent;
    import com.amazonaws.services.lambda.runtime.events.SNSEvent.SNSRecord;
    import java.util.List;
    
    public class RecomFunction {
    
        public void handler(SNSEvent event, Context context) {
    
            LambdaLogger logger = context.getLogger();
    
            List<SNSRecord> records = event.getRecords();
    
            if (records != null) {
                for (SNSRecord record : records) {
                    if (record != null) {
                        logger.log("SNS record: " + record.getSNS().getMessage());
                    }
                }
            }
        }
    
    }
    

    Unfortunately, record.getSNS() returns NULL resulting to a NullPointer exception

    There is a related question, however a specific answer was not given: Setup DynamoDB Trigger using Lambda

  • barryku
    barryku about 8 years
    One more thing, you will need to include aws-lambda-java-events to your shaded JAR. aws-lambda-java-core, however, can be set to <scope>provided</scope>
  • 8bitjunkie
    8bitjunkie over 7 years
    It appears that RequestHandler is now deprecated
  • ses
    ses almost 6 years
    what is DynamodbEvent?
  • romixch
    romixch almost 6 years
    This worked for me very well. It remains to say that DynamodbEvent is part of following gradle dependency: compile group: 'com.amazonaws', name: 'aws-lambda-java-events', version: '2.1.0'
  • RickHigh
    RickHigh almost 4 years
    'com.amazonaws:aws-lambda-java-core:1.2.1' 'com.amazonaws:aws-lambda-java-events:2.2.8' 'com.amazonaws:aws-lambda-java-events-sdk-transformer:1.0.0' 'com.amazonaws:aws-lambda-java-log4j:1.0.1' 'com.amazonaws:aws-lambda-java-log4j2:1.2.0' see github.com/aws/aws-lambda-java-libs DynamodbEvent is defined there.