snapshot of https://github.com/ThreeDotsLabs/watermill.git (master, 2026-09-15; blobs > 131072B omitted)
Some checks failed
master / ci (push) Failing after 0s
Some checks failed
master / ci (push) Failing after 0s
This commit is contained in:
4
_examples/pubsubs/aws-sns/.validate_example.yml
Normal file
4
_examples/pubsubs/aws-sns/.validate_example.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
validation_cmd: "docker compose up"
|
||||
teardown_cmd: "docker compose down"
|
||||
timeout: 120
|
||||
expected_output: "A received message: [0-9a-f\\-]+, payload: Hello, world!"
|
||||
24
_examples/pubsubs/aws-sns/docker-compose.yml
Normal file
24
_examples/pubsubs/aws-sns/docker-compose.yml
Normal file
@@ -0,0 +1,24 @@
|
||||
services:
|
||||
server:
|
||||
image: golang:1.25
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- .:/app
|
||||
- $GOPATH/pkg/mod:/go/pkg/mod
|
||||
working_dir: /app
|
||||
command: go run main.go
|
||||
|
||||
localstack:
|
||||
image: localstack/localstack:3.8
|
||||
environment:
|
||||
- SERVICES=sqs,sns
|
||||
- AWS_DEFAULT_REGION=us-east-1
|
||||
- EDGE_PORT=4566
|
||||
ports:
|
||||
- "4566-4597:4566-4597"
|
||||
healthcheck:
|
||||
test: awslocal sqs list-queues && awslocal sns list-topics
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
start_period: 30s
|
||||
23
_examples/pubsubs/aws-sns/go.mod
Normal file
23
_examples/pubsubs/aws-sns/go.mod
Normal file
@@ -0,0 +1,23 @@
|
||||
module main
|
||||
|
||||
require (
|
||||
github.com/ThreeDotsLabs/watermill v1.5.1
|
||||
github.com/ThreeDotsLabs/watermill-aws v1.0.2
|
||||
github.com/aws/aws-sdk-go-v2 v1.41.7
|
||||
github.com/aws/aws-sdk-go-v2/service/sns v1.39.17
|
||||
github.com/aws/aws-sdk-go-v2/service/sqs v1.42.27
|
||||
github.com/aws/smithy-go v1.25.1
|
||||
github.com/samber/lo v1.53.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.23 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.23 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/lithammer/shortuuid/v3 v3.0.7 // indirect
|
||||
github.com/oklog/ulid v1.3.1 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
golang.org/x/text v0.37.0 // indirect
|
||||
)
|
||||
|
||||
go 1.25.0
|
||||
55
_examples/pubsubs/aws-sns/go.sum
Normal file
55
_examples/pubsubs/aws-sns/go.sum
Normal file
@@ -0,0 +1,55 @@
|
||||
github.com/ThreeDotsLabs/watermill v1.5.1 h1:t5xMivyf9tpmU3iozPqyrCZXHvoV1XQDfihas4sV0fY=
|
||||
github.com/ThreeDotsLabs/watermill v1.5.1/go.mod h1:Uop10dA3VeJWsSvis9qO3vbVY892LARrKAdki6WtXS4=
|
||||
github.com/ThreeDotsLabs/watermill-aws v1.0.2 h1:cwKp0O/HSb5aYEClx/8A0mb9cJGkSf0iFL/bDQtwUCE=
|
||||
github.com/ThreeDotsLabs/watermill-aws v1.0.2/go.mod h1:jlGFr7vhmzAESlU/PE5BCyuat3w/gr5zmwx1oNm1yh8=
|
||||
github.com/aws/aws-sdk-go-v2 v1.41.7 h1:DWpAJt66FmnnaRIOT/8ASTucrvuDPZASqhhLey6tLY8=
|
||||
github.com/aws/aws-sdk-go-v2 v1.41.7/go.mod h1:4LAfZOPHNVNQEckOACQx60Y8pSRjIkNZQz1w92xpMJc=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.31.2 h1:NOaSZpVGEH2Np/c1toSeW0jooNl+9ALmsUTZ8YvkJR0=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.31.2/go.mod h1:17ft42Yb2lF6OigqSYiDAiUcX4RIkEMY6XxEMJsrAes=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.18.6 h1:AmmvNEYrru7sYNJnp3pf57lGbiarX4T9qU/6AZ9SucU=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.18.6/go.mod h1:/jdQkh1iVPa01xndfECInp1v1Wnp70v3K4MvtlLGVEc=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.4 h1:lpdMwTzmuDLkgW7086jE94HweHCqG+uOJwHf3LZs7T0=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.4/go.mod h1:9xzb8/SV62W6gHQGC/8rrvgNXU6ZoYM3sAIJCIrXJxY=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.23 h1:GpT/TrnBYuE5gan2cZbTtvP+JlHsutdmlV2YfEyNde0=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.23/go.mod h1:xYWD6BS9ywC5bS3sz9Xh04whO/hzK2plt2Zkyrp4JuA=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.23 h1:bpd8vxhlQi2r1hiueOw02f/duEPTMK59Q4QMAoTTtTo=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.23/go.mod h1:15DfR2nw+CRHIk0tqNyifu3G1YdAOy68RftkhMDDwYk=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.0 h1:6+lZi2JeGKtCraAj1rpoZfKqnQ9SptseRZioejfUOLM=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.0/go.mod h1:eb3gfbVIxIoGgJsi9pGne19dhCBpK6opTYpQqAmdy44=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.4 h1:ueB2Te0NacDMnaC+68za9jLwkjzxGWm0KB5HTUHjLTI=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.4/go.mod h1:nLEfLnVMmLvyIG58/6gsSA03F1voKGaCfHV7+lR8S7s=
|
||||
github.com/aws/aws-sdk-go-v2/service/sns v1.39.17 h1:synXIPC/L4Cc489P0XDcrVJzHSLj7krKRpFLalbGM2k=
|
||||
github.com/aws/aws-sdk-go-v2/service/sns v1.39.17/go.mod h1:4ABZnI23uNK37waIjGwkubnCwGhepIt9x1GvASfljJA=
|
||||
github.com/aws/aws-sdk-go-v2/service/sqs v1.42.27 h1:QgaWXVmNDxv/U/3UIHfGb7ohvtFgerf/bYcYylj4i8E=
|
||||
github.com/aws/aws-sdk-go-v2/service/sqs v1.42.27/go.mod h1:8S6ExnLprS0oIeA8ZlHkJUJ0BMpKqnRPws/S0jegTqQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.28.2 h1:ve9dYBB8CfJGTFqcQ3ZLAAb/KXWgYlgu/2R2TZL2Ko0=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.28.2/go.mod h1:n9bTZFZcBa9hGGqVz3i/a6+NG0zmZgtkB9qVVFDqPA8=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.33.2 h1:pd9G9HQaM6UZAZh19pYOkpKSQkyQQ9ftnl/LttQOcGI=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.33.2/go.mod h1:eknndR9rU8UpE/OmFpqU78V1EcXPKFTTm5l/buZYgvM=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.38.0 h1:iV1Ko4Em/lkJIsoKyGfc0nQySi+v0Udxr6Igq+y9JZc=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.38.0/go.mod h1:bEPcjW7IbolPfK67G1nilqWyoxYMSPrDiIQ3RdIdKgo=
|
||||
github.com/aws/smithy-go v1.25.1 h1:J8ERsGSU7d+aCmdQur5Txg6bVoYelvQJgtZehD12GkI=
|
||||
github.com/aws/smithy-go v1.25.1/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/lithammer/shortuuid/v3 v3.0.7 h1:trX0KTHy4Pbwo/6ia8fscyHoGA+mf1jWbPJVuvyJQQ8=
|
||||
github.com/lithammer/shortuuid/v3 v3.0.7/go.mod h1:vMk8ke37EmiewwolSO1NLW8vP4ZaKlRuDIi8tWWmAts=
|
||||
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/samber/lo v1.53.0 h1:t975lj2py4kJPQ6haz1QMgtId2gtmfktACxIXArw3HM=
|
||||
github.com/samber/lo v1.53.0/go.mod h1:4+MXEGsJzbKGaUEQFKBq2xtfuznW9oz/WrgyzMzRoM0=
|
||||
github.com/stretchr/testify v1.11.0 h1:ib4sjIrwZKxE5u/Japgo/7SJV3PvgjGiRNAvTVGqQl8=
|
||||
github.com/stretchr/testify v1.11.0/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc=
|
||||
golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
133
_examples/pubsubs/aws-sns/main.go
Normal file
133
_examples/pubsubs/aws-sns/main.go
Normal file
@@ -0,0 +1,133 @@
|
||||
// Sources for https://watermill.io/learn/getting-started/
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
amazonsns "github.com/aws/aws-sdk-go-v2/service/sns"
|
||||
amazonsqs "github.com/aws/aws-sdk-go-v2/service/sqs"
|
||||
transport "github.com/aws/smithy-go/endpoints"
|
||||
"github.com/samber/lo"
|
||||
|
||||
"github.com/ThreeDotsLabs/watermill"
|
||||
"github.com/ThreeDotsLabs/watermill-aws/sns"
|
||||
"github.com/ThreeDotsLabs/watermill-aws/sqs"
|
||||
"github.com/ThreeDotsLabs/watermill/message"
|
||||
)
|
||||
|
||||
func main() {
|
||||
logger := watermill.NewStdLogger(false, false)
|
||||
|
||||
snsOpts := []func(*amazonsns.Options){
|
||||
amazonsns.WithEndpointResolverV2(sns.OverrideEndpointResolver{
|
||||
Endpoint: transport.Endpoint{
|
||||
URI: *lo.Must(url.Parse("http://localstack:4566")),
|
||||
},
|
||||
}),
|
||||
}
|
||||
|
||||
sqsOpts := []func(*amazonsqs.Options){
|
||||
amazonsqs.WithEndpointResolverV2(sqs.OverrideEndpointResolver{
|
||||
Endpoint: transport.Endpoint{
|
||||
URI: *lo.Must(url.Parse("http://localstack:4566")),
|
||||
},
|
||||
}),
|
||||
}
|
||||
|
||||
topicResolver, err := sns.NewGenerateArnTopicResolver("000000000000", "us-east-1")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
newSubscriber := func(name string) (message.Subscriber, error) {
|
||||
subscriberConfig := sns.SubscriberConfig{
|
||||
AWSConfig: aws.Config{
|
||||
Credentials: aws.AnonymousCredentials{},
|
||||
},
|
||||
OptFns: snsOpts,
|
||||
TopicResolver: topicResolver,
|
||||
GenerateSqsQueueName: func(ctx context.Context, snsTopic sns.TopicArn) (string, error) {
|
||||
topic, err := sns.ExtractTopicNameFromTopicArn(snsTopic)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%v-%v", topic, name), nil
|
||||
},
|
||||
}
|
||||
|
||||
sqsSubscriberConfig := sqs.SubscriberConfig{
|
||||
AWSConfig: aws.Config{
|
||||
Credentials: aws.AnonymousCredentials{},
|
||||
},
|
||||
OptFns: sqsOpts,
|
||||
}
|
||||
|
||||
return sns.NewSubscriber(subscriberConfig, sqsSubscriberConfig, logger)
|
||||
}
|
||||
|
||||
subA, err := newSubscriber("subA")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
subB, err := newSubscriber("subB")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
messagesA, err := subA.Subscribe(context.Background(), "example-topic")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
messagesB, err := subB.Subscribe(context.Background(), "example-topic")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
go process("A", messagesA)
|
||||
go process("B", messagesB)
|
||||
|
||||
publisherConfig := sns.PublisherConfig{
|
||||
AWSConfig: aws.Config{
|
||||
Credentials: aws.AnonymousCredentials{},
|
||||
},
|
||||
OptFns: snsOpts,
|
||||
TopicResolver: topicResolver,
|
||||
}
|
||||
|
||||
publisher, err := sns.NewPublisher(publisherConfig, logger)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
publishMessages(publisher)
|
||||
}
|
||||
|
||||
func publishMessages(publisher message.Publisher) {
|
||||
for {
|
||||
msg := message.NewMessage(watermill.NewUUID(), []byte("Hello, world!"))
|
||||
|
||||
if err := publisher.Publish("example-topic", msg); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
func process(prefix string, messages <-chan *message.Message) {
|
||||
for msg := range messages {
|
||||
log.Printf("%v received message: %s, payload: %s", prefix, msg.UUID, string(msg.Payload))
|
||||
|
||||
// we need to Acknowledge that we received and processed the message,
|
||||
// otherwise, it will be resent over and over again.
|
||||
msg.Ack()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user