在JAVA中使用Lambda的AWS DynamoDB触发器

在JAVA中使用Lambda的AWS DynamoDB触发器,java,amazon-web-services,stream,amazon-dynamodb,aws-lambda,Java,Amazon Web Services,Stream,Amazon Dynamodb,Aws Lambda,我试图在dynamodb流事件上触发一个用Java编写的AWS lambda函数。Amazon也有类似的指南,在这里使用NodeJS NodeJS的测试输入(来自上面的链接)看起来像一个SNS事件,所以我尝试使用Java中相应的SNSEvent类作为我的handler方法的输入 import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.LambdaLogg

我试图在dynamodb流事件上触发一个用Java编写的AWS lambda函数。Amazon也有类似的指南,在这里使用NodeJS

NodeJS的测试输入(来自上面的链接)看起来像一个SNS事件,所以我尝试使用Java中相应的SNSEvent类作为我的handler方法的输入

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

}
import com.amazonaws.services.lambda.runtime.Context;
导入com.amazonaws.services.lambda.runtime.LambdaLogger;
导入com.amazonaws.services.lambda.runtime.events.SNSEvent;
导入com.amazonaws.services.lambda.runtime.events.SNSEvent.SNSRecord;
导入java.util.List;
公共类重组函数{
公共void处理程序(SNSEvent事件、上下文){
LambdaLogger logger=context.getLogger();
List records=event.getRecords();
if(记录!=null){
用于(SNS记录:记录){
if(记录!=null){
logger.log(“SNS记录:+record.getSNS().getMessage());
}
}
}
}
}
不幸的是,record.getSNS()返回NULL,导致NULL指针异常

有一个相关问题,但没有给出具体答案:

创建一个处理程序,该处理程序接受InputStream,读入InputStream的内容(仅为JSON),然后对其进行反序列化以获取所需的数据

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

这有点麻烦,但据我所知,AWS目前并没有为使用DynamoDB流提供更高级别的Java lambda接口。我有一个完整的示例,详细介绍了如何反序列化JSON流以获取数据的Java对象。

这对我来说很有效-case DynamoDB流事件:

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.
    }
}
import com.amazonaws.services.lambda.runtime.RequestHandler;
...
公共类DynamoStreamHandler实现RequestHandler{
@凌驾
公共Void handleRequest(对象o,上下文){
LinkedHashMap lhm=(LinkedHashMap)o;
等
}
}
看起来他们使用了一个定制的JSON映射器,它利用了
Map
List
对象。通过测试和打印出游日志,对其他事件类型验证这一点非常简单(但繁琐)。(叹气)


编辑:如果~5 MB的开销没有问题,您可以使用aws lambda java事件库v1.1.0提供的
DynamodbEvent.DynamodbStreamRecord
,如aws lambda文档中所述。

这段代码对我很有用。您可以使用它在Lambda函数中接收和处理DynamoDB事件-

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;
    }
}
公共类处理程序实现RequestHandler{
@凌驾
公共Void handleRequest(DynamodbEvent DynamodbEvent,上下文){
对于(DynamodbStreamRecord记录:dynamodbEvent.getRecords()){
if(记录==null){
继续;
}
//你的代码在这里
}
返回null;
}
}

同样,您可以使用
SNSEvent
SNSRecord
来处理Amazon SNS事件。

您的代码在CloudWatch日志中导致以下异常:

类未实现适当的处理程序接口

一旦我将代码更改为以下内容,我就可以很好地获得SNS消息

public class RecomFunction implements RequestHandler<SNSEvent, Void> {

    public Void handleRequest(SNSEvent event, Context context) {

        ...
        return null;
    }

}
public类重组函数实现RequestHandler{
公共无效HandlerRequest(SNSEvent事件、上下文){
...
返回null;
}
}

要从事件处理程序获取反序列化对象,请执行以下操作: 1) 在处理程序中,使用以下内容从输入流获取json:

private String getJsonFrom(InputStream stream) throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    int letter;
    while ((letter = stream.read()) != -1)
        baos.write(letter);

    return new String(baos.toByteArray());
}
2) 然后创建一个特定的反序列化程序,从json派生对象。”如果发生DynamoDB事件,则为“NewImage”。

还有一件事,您需要将aws lambda java事件包括到着色JAR中。但是,aws lambda java core可以设置为Provided现在看来
RequestHandler
已被弃用可能与DynamodbEvent重复?这对我很有效。还有一点需要说明的是,DynamodbEvent是以下gradle依赖项的一部分:编译组:“com.amazonaws”,名称:“aws lambda java events”,版本:“2.1.0”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“请参见此处定义的DynamodbEvent。