AWS SNS发布到订阅的Lambda函数会记录空字段
试图将其发布到AWS论坛,但似乎我的帐户“尚未准备好”,无论如何。
我已经设置了一个AWS Lambda函数(用Java编写),它接受POJO以允许JSON的自动反序列化。 我正在使用的测试JSON位于下方,它代表一旦所有内容都正常运行,将从消息的最终来源发送的JSON字符串。
{"sender":"Joe", "id":1, "event":"started", "ticks":2, "time":"20150623T214256Z", "version":"1.0"}
当我通过从Lambda“测试”控制台发布来测试它时,它非常完美。
我现在试图通过将Lambda函数订阅到一个主题来挂钩SNS,并且我正在从SNS控制台进行测试。 我已经尝试发送与“原始数据”(没有显示任何结果)和使用“JSON生成器”数据选项生成的JSON一样的上述相同的确切消息,我遇到了一个问题,它似乎在SNS将消息发送到Lambda函数,实例化POJO,但调用默认构造函数或使用全空值调用参数化构造函数。 无论哪种方式,当Lambda函数通过在POJO中调用重写的toString()方法记录消息时,它将为所有变量输出null,而不会显示任何错误消息。 同样,SNS主题配置为登录到Cloudwatch,并且它也不报告任何错误。 它获得HTTP状态202。
这是新生成的JSON消息。
{
"default": "{"sender":"Joe", "id":1, "event":"started", "ticks":2, "time":"20150623T214256Z", "version":"1.0"}",
"lambda": "{"sender":"Joe", "id":1, "event":"started", "ticks":2, "time":"20150623T214256Z", "version":"1.0"}",
}
以下是日志消息。
Lambda的日志:
START RequestId: 238a0546-627d-11e5-b228-817bf2a1219a
Received the following :: We have the following Message{sender=null, id=null, event=null, ticks=null, time=null, version=null}
END RequestId: 238a0546-627d-11e5-b228-817bf2a1219a
REPORT RequestId: 238a0546-627d-11e5-b228-817bf2a1219a Duration: 26.23 ms Billed Duration: 100 ms Memory Size: 1536 MB Max Memory Used: 69 MB
SNS日志:
{ "status": "SUCCESS", "notification": { "timestamp": "2015-09-24 05:28:51.079", "topicArn": "arn:aws:sns:us-east-1:256842276575:App", "messageId": "3f5c0fa1-8a50-5ce3-b7c9-41dc060212c8", "messageMD5Sum": "65a5cb6d53616bd385f72177fe98ecc2" }, "delivery": { "statusCode": 202, "dwellTimeMs": 92, "attempts": 1, "providerResponse": "{"lambdaRequestId":"238a0546-627d-11e5-b228-817bf2a1219a"}", "destination": "arn:aws:lambda:us-east-1:256842276575:function:App-Lambda-Trigger" } }
以下是适用的Lambda函数代码:
package com.mycompany;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.LambdaLogger;
public class LambdaHandler {
public void Handler(Message msg, Context context) {
LambdaLogger logger = context.getLogger();
logger.log("Received the following :: " + msg.toString());
}
}
。
public class Message {
private String sender;
private Integer id;
private String event;
private Integer ticks;
private String time;
private Double version;
public Message(String sender, Integer id, String event, Integer ticks, String time, Double version) {
this.sender = sender;
this.id = id;
this.event = event;
this.ticks = ticks;
this.time = time;
this.version = version;
}
... getters/setters ...
public Message() {
}
@Override
public String toString() {
return "We have the following Message{" + "sender=" + getSender() + ", id=" + id + ", event=" + event + ", ticks=" + ticks + ", time=" + time + ", version=" + version + '}';
}
在做了一些挖掘并查看了一些javascript示例(我似乎无法找到任何订阅SNS的函数的Java示例)之后,似乎它们都收到“事件”。 我在AWS的Github存储库上找到了一个Java类SNSEvent(https://github.com/aws/aws-lambda-java-libs/blob/master/aws-lambda-java-events/src/main/java/ com / amazonaws / services / lambda / runtime / events / SNSEvent.java),但它不在官方的Javadoc中。 我没有能够找到文档Java Lambda函数设置来接收反序列化的POJO(我不能相信这些都不常见),我找不到任何指定什么对象类型由SNS主题到Lambda函数,如果事实上我不应该指望POJO类型。
有人可以澄清,我应该有什么样的对象类型,我的Lambda函数期望得到? 有人可以提供一些示例代码?
任何帮助,将不胜感激。
编辑1
我修改我的函数接受SNSEvent和上下文对象,每个建议和我的函数抛出以下异常:
Error loading method handler on class com.app.LambdaHandler: class java.lang.NoClassDefFoundError java.lang.NoClassDefFoundError: com/amazonaws/services/lambda/runtime/events/SNSEvent
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
at java.lang.Class.privateGetPublicMethods(Class.java:2902)
at java.lang.Class.getMethods(Class.java:1615) Caused by: java.lang.ClassNotFoundException: com.amazonaws.services.lambda.runtime.events.SNSEvent
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
就好像运行时环境不能识别SNSEvent?
我认为你应该改变两件事:
Message
提取自定义数据,然后分别解析。 在Actions> Configure sample event下查看Lambda中的SNS事件模板。 以下是使用AWS Lambda Java支持库处理Java中的SNS事件的示例Lambda函数。
package example;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.LambdaLogger;
import com.amazonaws.services.lambda.runtime.events.SNSEvent;
public class SNSEventHandler {
public String handleSNSEvent(SNSEvent event, Context context) {
LambdaLogger logger = context.getLogger();
for (SNSEvent.SNSRecord record : event.getRecords()) {
SNSEvent.SNS sns = record.getSNS();
logger.log("handleSNSEvent received SNS message " + sns.getMessage());
}
return "handleSNSEvent finished";
}
}
SNSEvent数据模型表明多个事件可能同时到达处理程序,因此该示例显示对它们进行迭代而不是仅假设一个事件。 我还没有在实践中看到过,但我的使用量一直很低。
链接地址: http://www.djcxy.com/p/32243.html上一篇: AWS SNS publishing to a subscribed Lambda function logs null fields