initial commit
This commit is contained in:
commit
866e9908a8
20 changed files with 999 additions and 0 deletions
infrastructure/rabbitmq
89
infrastructure/rabbitmq/publisher.go
Normal file
89
infrastructure/rabbitmq/publisher.go
Normal file
|
@ -0,0 +1,89 @@
|
|||
package rabbitmq
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/wagslane/go-rabbitmq"
|
||||
|
||||
"code.icb4dc0.de/prskr/pg_v_man/core/domain"
|
||||
"code.icb4dc0.de/prskr/pg_v_man/core/ports"
|
||||
"code.icb4dc0.de/prskr/pg_v_man/infrastructure/config"
|
||||
)
|
||||
|
||||
var _ ports.ReplicationEventConsumer = (*PublishingEventConsumer)(nil)
|
||||
|
||||
func NewPublishingEventConsumer(ctx context.Context, cfg config.RabbitMQ) (consumer *PublishingEventConsumer, err error) {
|
||||
var dialer net.Dialer
|
||||
conn, err := rabbitmq.NewConn(cfg.ConnectionString, rabbitmq.WithConnectionOptionsLogging, func(options *rabbitmq.ConnectionOptions) {
|
||||
options.Config.Dial = func(network, addr string) (net.Conn, error) {
|
||||
return dialer.DialContext(ctx, network, addr)
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not create RabbitMQ connection: %w", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
err = errors.Join(err, conn.Close())
|
||||
}
|
||||
}()
|
||||
|
||||
publisherOptions := []func(*rabbitmq.PublisherOptions){
|
||||
rabbitmq.WithPublisherOptionsLogging,
|
||||
rabbitmq.WithPublisherOptionsExchangeName(cfg.Exchange.Name),
|
||||
rabbitmq.WithPublisherOptionsExchangeKind(cfg.Exchange.Kind),
|
||||
rabbitmq.WithPublisherOptionsExchangeDeclare,
|
||||
}
|
||||
|
||||
if cfg.Exchange.Durable {
|
||||
publisherOptions = append(publisherOptions, rabbitmq.WithPublisherOptionsExchangeDurable)
|
||||
}
|
||||
|
||||
publisher, err := rabbitmq.NewPublisher(
|
||||
conn,
|
||||
publisherOptions...,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not create RabbitMQ publisher: %w", err)
|
||||
}
|
||||
|
||||
return &PublishingEventConsumer{Conn: conn, Publisher: publisher, Cfg: cfg}, nil
|
||||
}
|
||||
|
||||
type PublishingEventConsumer struct {
|
||||
Conn *rabbitmq.Conn
|
||||
Publisher *rabbitmq.Publisher
|
||||
Cfg config.RabbitMQ
|
||||
}
|
||||
|
||||
func (p PublishingEventConsumer) OnDataChange(ctx context.Context, ev domain.ReplicationEvent) error {
|
||||
data, err := json.Marshal(ev)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not marshal event: %w", err)
|
||||
}
|
||||
return p.Publisher.PublishWithContext(
|
||||
ctx, data, []string{p.Cfg.RoutingKey, strings.Join([]string{ev.DBName, ev.Namespace, ev.Relation}, ".")},
|
||||
rabbitmq.WithPublishOptionsContentType("application/json"),
|
||||
rabbitmq.WithPublishOptionsExchange(p.Cfg.Exchange.Name),
|
||||
rabbitmq.WithPublishOptionsCorrelationID(strconv.Itoa(int(ev.TransactionId))),
|
||||
rabbitmq.WithPublishOptionsType(ev.EventType.String()),
|
||||
rabbitmq.WithPublishOptionsHeaders(rabbitmq.Table{
|
||||
"db": ev.DBName,
|
||||
"namespace": ev.Namespace,
|
||||
"relation": ev.Relation,
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
func (p PublishingEventConsumer) Close() error {
|
||||
p.Publisher.Close()
|
||||
|
||||
return p.Conn.Close()
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue