Bu örnekte, bir Golang uygulamasından olayları başlatacağız ve bunları bir Lambda fonksiyonunda işleyeceğiz. Golang uygulaması, önceden tanımlanmış bir Event Bus'a bir Event Bus olayı göndermek için EventBridge hizmetini kullanır. Diğer uçta, Event Rule onu yakalar ve işlenmek üzere Lambda fonksiyonuna iletir.


Not




Lambda fonksiyonu yaratma


Bu, olayın işlenmesinden sorumludur.


package main

import (
"context"
"encoding/json"
"fmt"

"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
)

type Image struct {
Name string `json:"name"`
URL string `json:"url"`
}

func main() {
lambda.Start(upload)
}

func upload(_ context.Context, event events.CloudWatchEvent) error {
fmt.Printf("SOURCE: %+v\n", event.Source)
fmt.Printf("ACTION: %+v\n", event.DetailType)

var img Image
if err := json.Unmarshal(event.Detail, &img); err != nil {
return err
}

fmt.Printf("IMAGE: %+v\n", img)

return nil
}

$ aws --profile localstack --endpoint-url http://localhost:4566 lambda delete-function --function-name hello-lambda

$ GOOS=linux CGO_ENABLED=0 go build -ldflags "-s -w" -o lambda main.go

$ zip lambda.zip lambda

$ aws --profile localstack --endpoint-url http://localhost:4566 lambda create-function --function-name hello-lambda --handler lambda --runtime go1.x --role create-role --zip-file fileb://lambda.zip

$ aws --profile localstack --endpoint-url http://localhost:4566 lambda list-functions
{
"Functions": [
{
"FunctionName": "hello-lambda",
"FunctionArn": "arn:aws:lambda:eu-west-1:000000000000:function:hello-lambda",
"Runtime": "go1.x",
"Role": "create-role",
"Handler": "lambda",
"CodeSize": 2379616,
"Description": "",
"Timeout": 3,
"LastModified": "2022-01-01T20:42:09.707+0000",
"CodeSha256": "UxruqiDEUheisbAIAMkjbIXnpsMao1UomjsWIwic7XM=",
"Version": "$LATEST",
"VpcConfig": {},
"TracingConfig": {
"Mode": "PassThrough"
},
"RevisionId": "f81daa29-8212-44d7-b04c-1504805a5eea",
"State": "Active",
"LastUpdateStatus": "Successful",
"PackageType": "Zip"
}
]
}

Event Bus yaratma


Bu olayları gönderecek.


$ aws --profile localstack --endpoint-url http://localhost:4566 events create-event-bus --name hello-event-bus

$ aws --profile localstack --endpoint-url http://localhost:4566 events list-event-buses
{
"EventBuses": [
{
"Name": "default",
"Arn": "arn:aws:events:eu-west-1:000000000000:event-bus/default"
},
{
"Name": "hello-event-bus",
"Arn": "arn:aws:events:eu-west-1:000000000000:event-bus/hello-event-bus"
}
]
}

Event Rule yaratma


Bu olayları yakalayıp ve Lambda'ya iletecek.


$ aws --profile localstack --endpoint-url http://localhost:4566 events put-rule --name hello-event-rule --event-bus-name hello-event-bus --event-pattern "{}"

$ aws --profile localstack --endpoint-url http://localhost:4566 events list-rules
{
"Rules": [
{
"Name": "hello-event-rule",
"Arn": "arn:aws:events:eu-west-1:000000000000:rule/hello-event-bus/hello-event-rule",
"EventPattern": "{}",
"State": "ENABLED",
"EventBusName": "hello-event-bus"
}
]
}

Event Target yaratma


Bu, Lambda fonksiyonunu event rule ile ilişkilendirir.


$ aws --profile localstack --endpoint-url http://localhost:4566 events put-targets --rule hello-event-rule --targets "Id"="1","Arn"="arn:aws:lambda:eu-west-1:000000000000:function:hello-lambda"

$ aws --profile localstack --endpoint-url http://localhost:4566 events list-targets-by-rule --rule hello-event-rule
{
"Targets": [
{
"Id": "1",
"Arn": "arn:aws:lambda:eu-west-1:000000000000:function:hello-lambda"
}
]
}

Go uygulaması


package main

import (
"context"
"encoding/json"
"fmt"
"log"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/eventbridge"
)

type Image struct {
Name string `json:"name"`
URL string `json:"url"`
}

func main() {
ctx := context.Background()

ses, err := session.NewSessionWithOptions(session.Options{
Profile: "localstack",
Config: aws.Config{
Region: aws.String("eu-west-1"),
Endpoint: aws.String("http://localhost:4566"),
},
})
if err != nil {
log.Fatalln(err)
}

evb := eventbridge.New(ses)

img := Image{
Name: "image.png",
URL: "https://www.example.com/image.png",
}

data, err := json.Marshal(img)
if err != nil {
log.Fatalln(err)
}

entries := []*eventbridge.PutEventsRequestEntry{{
Detail: aws.String(string(data)),
DetailType: aws.String("upload"),
EventBusName: aws.String("hello-event-bus"),
Source: aws.String("example.com"),
}}

out, err := evb.PutEventsWithContext(ctx, &eventbridge.PutEventsInput{Entries: entries})
if err != nil {
log.Fatalln(err)
}

fmt.Println(out.GoString())
}

Test


$ go run main.go
{
Entries: [{
EventId: "123f7bbf-7a02-45f7-99c2-84ee7f56d25d"
}],
FailedEntryCount: 0
}

Loglar


localstack    | 2022-01-01T21:28:53.262:DEBUG:localstack.services.awslambda.lambda_executors: Lambda arn:aws:lambda:eu-west-1:000000000000:function:hello-lambda result / log output:
localstack | null
localstack | > START RequestId: c59d91e9-3b36-1d3e-1422-1526d364b9e4 Version: $LATEST
localstack | > SOURCE: example.com
localstack | > ACTION: upload
localstack | > IMAGE: {Name:image.png URL:https://www.example.com/image.png}
localstack | > END RequestId: c59d91e9-3b36-1d3e-1422-1526d364b9e4
localstack | > REPORT RequestId: c59d91e9-3b36-1d3e-1422-1526d364b9e4 Init Duration: 271.71 ms Duration: 14.91 ms Billed Duration: 15 ms Memory Size: 1536 MB Max Memory Used: 19 MB

Çoklu Lambda fonksiyonu


Tek bir Event Bus ile birden fazla Lambda fonksiyonu kullanmak için, bir yerine iki Lambda fonksiyonu, iki Event Rule ve iki Event Target oluşturacaksınız. Event Rule tanımlamasında ek olarak --event-pattern ayarlı olacak. Daha sonra Golang kodunuzdaki DetailType özelliği, olayın hangi Lambda fonksiyonu gönderileceğini ayırt etmeye yardımcı olacaktır. Burada merhaba-* yerine farklı bir ad kullanacağım.


Lambda fonksiyonu


$ aws ... lambda create-function --function-name image-lambda-0 ...

$ aws ... lambda create-function --function-name image-lambda-1 ...

Event Rule


$ aws ... events put-rule --name image-event-rule-0 ... --event-pattern "{\"source\":[\"inanzzz.com\"],\"detail-type\":[\"image-upload\"]}"

$ aws ... events put-rule --name image-event-rule-1 ... --event-pattern "{\"source\":[\"inanzzz.com\"],\"detail-type\":[\"image-download\"]}"

Event Target


$ aws ... events put-targets --rule image-event-rule-0 --targets "Id"="1","Arn"="arn:aws:lambda:eu-west-1:000000000000:function:image-lambda-0"

$ aws ... events put-targets --rule image-event-rule-1 --targets "Id"="2","Arn"="arn:aws:lambda:eu-west-1:000000000000:function:image-lambda-1"

Golang


...
entries := []*eventbridge.PutEventsRequestEntry{{
Detail: aws.String(string(data)),
// DetailType: aws.String("image-upload"), // Goes to Lambda 0
// DetailType: aws.String("image-download"), // Goes to Lambda 1
Source: aws.String("inanzzz.com"),
EventBusName: aws.String("image-event-bus"),
}}
...