I'm using AWS API Gateway as a restful API endpoint where I then pass the the records to a Kinesis stream and then onto Lambda. However there seems to be some data not reaching the Lambda function.
I have been searching far and wide for an example or something close to what i am looking for but have had no luck.
A device message would look something like the following and there can be more than one message, hence why it is in an array.
[{
"deviceId": "00000000001",
"deviceType": "device",
"receivedTs": 1539234374000,
"readingList": [{
"channelId": 13,
"type": "temperature",
"value": 25.3,
"unit": "°C"
},{
"channelId": 12,
"type": "humidity",
"value": 3.65,
"unit": "V",
"label": "primary-battery"
}]
}]
The outgoing mapping template i have currently is below:
{
"StreamName": "my-stream",
"Records": [
#foreach($elem in $input.path('$'))
#set($event = "{
""deviceId"": $elem.deviceId
""deviceType"": $elem.deviceType,
""receivedTs"": $elem.receivedTs,
""readingList"": [
#foreach($reading in $elem.readingList)
{
""channelId"": $reading.channelId,
""type"": ""$reading.type"",
""value"": $reading.value,
""unit"": ""$reading.unit"",
""label"": ""$reading.label""
}]
#if($foreach.hasNext),#end
#end
}")
{
"Data": "$util.base64Encode($event)",
"PartitionKey": "$elem.deviceType"
}#if($foreach.hasNext),#end
#end
]
}
Below is what my CloudWatch logs show from the processing within the lambda function. Some data is being shown but the readingList array of objects is not being filled out correctly, it just comes out as empty. I have a feeling that it is something to do with the foreach loop in the mapping template but i can't seem to figure out what.
Beginning to process all 1 records...
Event Name: aws:kinesis:record
Getting record contents.
Record contents: {
"deviceId": "00000000001",
"deviceType": "device",
"receivedTs": "1539234374000",
"readingList": [{
"channelId": "",
"type": "",
"value": "",
"unit": "",
"label": ""
}]
}
There is nothing special about the lambda function. For testing, it just writes the message content to console using the example code supplied by AWS.
If anyone has any ideas or some helpful links, that would be greatly appreciated. Thank you for your time.
Well i got it working. It was to do with the template.
{
"StreamName": "my-stream",
"Records": [
#foreach($elem in $input.path('$'))
#set($event = "{
""deviceId"": $elem.deviceId,
""deviceType"": $elem.deviceType,
""receivedTs"": $elem.receivedTs,
""readingList"": [
#foreach($reading in $elem.readingList)
{
""channelId"": $reading.channelId,
""type"": ""$reading.type"",
""value"": $reading.value,
""unit"": ""$reading.unit"",
""label"": ""$reading.label""
}
#if($foreach.hasNext),#end
#end
]
}")
{
"Data": "$util.base64Encode($event)",
"PartitionKey": "$elem.deviceType"
}#if($foreach.hasNext),#end
#end
]
}
Firstly i was missing a comma after the $elem.deviceId and the closing bracket for the readingList array goes after the #end for that foreach loop.
I must have been really over it to miss those silly mistakes.