I'm trying to invoke a lambda function (written in Go) with the Go SDK from another app but run into issues with the payload, but not when I test the lambda function via the console with the same output.
here is the function that invokes lambda:
type RedisPair struct {
RedisKey string `json:"redis_key"`
RedisValue string `json:"redis_value"`
}
type RedisBatch struct {
RedisPairs []RedisPair
GroupId string `json:"group_id"`
}
func lambdawrite (redisbatch RedisBatch) {
//fmt.Println("invoking lambda")
fmt.Println("Batch type: ", reflect.TypeOf(redisbatch))
payload, err := json.Marshal(redisbatch)
fmt.Println("Payload type: ", reflect.TypeOf(payload))
if err != nil {
fmt.Println("Error marshalling MyGetItemsFunction request")
}
svc := lambda.New(session.New())
input := &lambda.InvokeInput{
ClientContext: aws.String("MyApp"),
FunctionName: aws.String("arn:aws:lambda:us-region:arnnum:function:testrpredis"),
InvocationType: aws.String("RequestResponse"),
LogType: aws.String("Tail"),
Payload: payload,
Qualifier: aws.String("$LATEST"),
}
result, err := svc.Invoke(input)
if err != nil {
if aerr, ok := err.(awserr.Error); ok {
//error stuff...
}
} else {
// Print the error, cast err to awserr.Error to get the Code and
// Message from an error.
fmt.Println("error 2")
fmt.Println(err.Error())
}
return
}
//fmt.Println("good")
fmt.Println(result)
}
and here is the lambda function itself:
package main
import (
"github.com/go-redis/redis"
"github.com/aws/aws-lambda-go/lambda"
"log"
"os"
"time"
)
type Event struct {
RedisPairs []RedisPair
GroupId string `json:"group_id"`
}
type Response struct {
Message string `json:"message"`
Ok bool `json:"ok"`
}
type RedisPair struct {
RedisKey string `json:"redis_key"`
RedisValue string `json:"redis_value"`
}
func redis_pipeline(batch Event) (Response, error) {
clientrds := redis.NewClient(&redis.Options{
Addr: os.Getenv("REDIS_HOST") + ":6379",
DialTimeout: 10 * time.Second,
ReadTimeout: 30 * time.Second,
WriteTimeout: 30 * time.Second,
PoolSize: 100,
PoolTimeout: 30 * time.Second,
})
clientrds.FlushDB()
log.Print("start pipe")
pipe := clientrds.Pipeline()
var response Response
log.Print("starting range lop")
for b := range batch.RedisPairs {
//fmt.Println("adding", batch.RedisPairs[b].RedisKey, batch.RedisPairs[b].RedisValue)
pipe.Set(batch.RedisPairs[b].RedisKey, batch.RedisPairs[b].RedisValue, 0)
}
//fmt.Println(uuid, "...time now start: ", time.Now(), ", start time: ", startTime)
log.Print("write to redis")
_, err := pipe.Exec()
if err != nil {
log.Print("points error")
response = Response{
Message: err.Error(),
Ok: false,
}
} else {
log.Print("points written")
response = Response{
Message: "Points wrttien!",
Ok: true,
}
}
log.Print("close pipe")
pipe.Close()
return response, err
}
func main() {
log.Print("start main v2")
lambda.Start(redis_pipeline)
}
when I invoke lambda via the first function, the lambda logs show this every time I invoke the function:
invalid character ')' after top-level value: SyntaxError
null
If I output RedisBatch
struct to a file in the first function, and use that output to manually test the lambda function via the aws console, it works successfully then. the output looks like this too:
{
"RedisPairs": [
{
"redis_key": "kafka9",
"redis_value": "{\"metric_value_number\":1,\"path\":\"/sdp/sw/logstashjmx/jmxcfgs\",\"cluster\":\"card01\",\"@timestamp\":\"2018-05-17T08:32:50.035Z\",\"@version\":\"1\",\"host\":\"localhost\",\"metric_path\":\"dsdpecard01kfk05.kafka.log:type=Log,name=NumLogSegments,topic=private.topic.lsrp.created.v1,partition=4.Value\",\"type\":null,\"region\":\"us-east-1\"}
"
},
{
"redis_key": "kafka10",
"redis_value": "{\"metric_value_number\":1,\"path\":\"/sdp/sw/logstashjmx/jmxcfgs\",\"cluster\":\"card01\",\"@timestamp\":\"2018-05-17T08:32:50.045Z\",\"@version\":\"1\",\"host\":\"localhost\",\"metric_path\":\"dsdpecard01kfk05.kafka.log:type=Log,name=NumLogSegments,topic=credit-topic.v1,partition=6.Value\",\"type\":null,\"region\":\"us-east-1\"}
"
},
{
"redis_key": "kafka1",
"redis_value": "{\"metric_value_number\":0,\"path\":\"/sdp/sw/logstashjmx/jmxcfgs\",\"cluster\":\"card01\",\"@timestamp\":\"2018-05-17T08:32:50.063Z\",\"@version\":\"1\",\"host\":\"localhost\",\"metric_path\":\"dsdpecard01kfk05.kafka.log:type=Log,name=LogEndOffset,topic=credit.test1122.created.v1,partition=3.Value\",\"type\":null,\"region\":\"us-east-1\"}
"
},
{
"redis_key": "kafka2",
"redis_value": "{\"metric_value_number\":0,\"path\":\"/sdp/sw/logstashjmx/jmxcfgs\",\"cluster\":\"card01\",\"@timestamp\":\"2018-05-17T08:32:50.074Z\",\"@version\":\"1\",\"host\":\"localhost\",\"metric_path\":\"dsdpecard01kfk05.kafka.log:type=Log,name=LogEndOffset,topic=connect-offsets-east,partition=9.Value\",\"type\":null,\"region\":\"us-east-1\"}
"
},
{
"redis_key": "kafka3",
"redis_value": "{\"metric_value_number\":0,\"path\":\"/sdp/sw/logstashjmx/jmxcfgs\",\"cluster\":\"card01\",\"@timestamp\":\"2018-05-17T08:32:50.085Z\",\"@version\":\"1\",\"host\":\"localhost\",\"metric_path\":\"dsdpecard01kfk05.kafka.log:type=Log,name=Size,topic=credit-uxtest2.created.v1,partition=9.Value\",\"type\":null,\"region\":\"us-east-1\"}
"
},
{
"redis_key": "kafka5",
"redis_value": "{\"metric_value_number\":60,\"path\":\"/sdp/sw/logstashjmx/jmxcfgs\",\"cluster\":\"card01\",\"@timestamp\":\"2018-05-17T08:32:50.097Z\",\"@version\":\"1\",\"host\":\"localhost\",\"metric_path\":\"dsdpecard01kfk05.kafka.log:type=Log,name=LogEndOffset,topic=rte.enrichment.rules,partition=7.Value\",\"type\":null,\"region\":\"us-east-1\"}
"
}
],
"group_id": "testehb4"
}
why does it work when I manually output the data and test it, but not when I invoke the function programmatically?
-----EDIT------
just realized this works with the Event
invocation type but not RequestResponse
type. Whats the difference in how you send the payload between the two? can't seem to find the right docs for it or an example...