По моему мнению, это не слишком хорошо задокументировано, но это не плохо, когда вы это выясните.
Первое, что я не использую предопределенные объекты Lambda. Я читаю все в строку и беру оттуда. Итак, основа моей функции Lamda:
public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
// copy InputStream to String, avoiding 3rd party libraries
ByteArrayOutputStream result = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) != -1) {
result.write(buffer, 0, length);
}
String jsonString = result.toString();
}
Когда вы "go direct" из SNS в Lambda, сообщение выглядит примерно так (некоторые поля удалены ради длины):
{
"Records": [
{
"EventSource": "aws:sns",
"EventVersion": "1.0",
"Sns": {
"Type": "Notification",
"Subject": "the message subject",
"Message": "{\"message\": \"this is the message\", \"value\": 100}",
"Timestamp": "2020-04-24T21:44:28.220Z",
"SignatureVersion": "1"
}
}
]
}
Я отправил тестовое сообщение в JSON с двумя простыми полями. Используя JsonPath , поле «сообщения» внутри всего читается следующим образом:
String snsMessage = JsonPath.read(jsonString, "$.Records[0].Sns.Message");
String realMessage = JsonPath.read(snsMessage, "$.message");
Но когда оно идет SNS -> SQS -> Lambda (или, действительно, любой путь SNS -> SQS ) сообщение SNS теперь в основном упаковано и экранировано в сообщении SQS:
{
"Records": [
{
"messageId": "ca8c53e5-8417-4479-a720-d4ecf970ca68",
"body": "{\n \"Type\" : \"Notification\",\n \"Subject\" : \"the message subject\",\n \"Message\" : \"{\\\"message\\\": \\\"this is the message\\\", \\\"value\\\": 100}\"\n}",
"attributes": {
"ApproximateReceiveCount": "1"
},
"md5OfBody": "6a4840230aca6a7bf7934bf191a529b8",
"eventSource": "aws:sqs"
}
]
}
Таким образом, в этом случае значение находится в Records[0].body
, но содержит другой объект JSON. Я признаю, что, вероятно, есть более простой способ, но из того, что я нашел, мне пришлось проанализировать 3 раза:
String sqsBody = <as read in lambda>;
String recordBody = JsonPath.read(sqsBody, "$.Records[0].body");
String internalMessage = JsonPath.read(recordBody, "$.Message");
// now read out of the sns message
String theSnsMessage = JsonPath.read(message, "$.message");