01/01/2022 - AWS, GO
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.
default
Event Bus'ı kullanabilirsiniz. Ancak, doğru olay yönlendirmesi için en azından Event Rule için uygun bir --event-pattern
girişi tanımlamanız gerekir. Aksi takdirde, tüm olaylar aynı Lambda fonksiyonuna gidebilir. Ben örnek olması amacıyla yinede tanımlama yapacağım.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"
}
]
}
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"
}
]
}
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"
}
]
}
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"
}
]
}
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())
}
$ go run main.go
{
Entries: [{
EventId: "123f7bbf-7a02-45f7-99c2-84ee7f56d25d"
}],
FailedEntryCount: 0
}
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
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.
$ aws ... lambda create-function --function-name image-lambda-0 ...
$ aws ... lambda create-function --function-name image-lambda-1 ...
$ 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\"]}"
$ 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"
...
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"),
}}
...