package rabbitmq import ( "context" "encoding/json" "time" amqp "github.com/rabbitmq/amqp091-go" "github.com/rwadurian/mpc-system/services/account/application/ports" ) const ( exchangeName = "account.events" exchangeType = "topic" ) // EventPublisherAdapter implements EventPublisher using RabbitMQ type EventPublisherAdapter struct { conn *amqp.Connection channel *amqp.Channel } // NewEventPublisherAdapter creates a new EventPublisherAdapter func NewEventPublisherAdapter(conn *amqp.Connection) (*EventPublisherAdapter, error) { channel, err := conn.Channel() if err != nil { return nil, err } // Declare exchange err = channel.ExchangeDeclare( exchangeName, exchangeType, true, // durable false, // auto-deleted false, // internal false, // no-wait nil, // arguments ) if err != nil { channel.Close() return nil, err } return &EventPublisherAdapter{ conn: conn, channel: channel, }, nil } // Publish publishes an account event func (p *EventPublisherAdapter) Publish(ctx context.Context, event ports.AccountEvent) error { body, err := json.Marshal(event) if err != nil { return err } routingKey := string(event.Type) return p.channel.PublishWithContext(ctx, exchangeName, routingKey, false, // mandatory false, // immediate amqp.Publishing{ ContentType: "application/json", DeliveryMode: amqp.Persistent, Timestamp: time.Now().UTC(), Body: body, }, ) } // Close closes the publisher func (p *EventPublisherAdapter) Close() error { if p.channel != nil { return p.channel.Close() } return nil }