2024-09-10 17:26:46 +08:00
|
|
|
package rabbitmq_amqp
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
2024-11-21 17:34:08 +08:00
|
|
|
"fmt"
|
2024-09-10 17:26:46 +08:00
|
|
|
"github.com/Azure/go-amqp"
|
|
|
|
|
)
|
|
|
|
|
|
2024-11-21 17:34:08 +08:00
|
|
|
//func (c *ConnUrlHelper) UseSsl(value bool) {
|
2024-11-15 15:37:28 +08:00
|
|
|
// c.UseSsl = value
|
|
|
|
|
// if value {
|
|
|
|
|
// c.Scheme = "amqps"
|
|
|
|
|
// } else {
|
|
|
|
|
// c.Scheme = "amqp"
|
|
|
|
|
// }
|
|
|
|
|
//}
|
2024-09-10 17:26:46 +08:00
|
|
|
|
|
|
|
|
type AmqpConnection struct {
|
|
|
|
|
Connection *amqp.Conn
|
|
|
|
|
management IManagement
|
|
|
|
|
lifeCycle *LifeCycle
|
2024-11-21 17:34:08 +08:00
|
|
|
session *amqp.Session
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (a *AmqpConnection) Publisher(ctx context.Context, destinationAdd string, linkName string) (IPublisher, error) {
|
|
|
|
|
sender, err := a.session.NewSender(ctx, destinationAdd, createSenderLinkOptions(destinationAdd, linkName))
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return newPublisher(sender), nil
|
2024-09-10 17:26:46 +08:00
|
|
|
}
|
|
|
|
|
|
2024-11-15 15:37:28 +08:00
|
|
|
// Management returns the management interface for the connection.
|
|
|
|
|
// See IManagement interface.
|
2024-09-10 17:26:46 +08:00
|
|
|
func (a *AmqpConnection) Management() IManagement {
|
|
|
|
|
return a.management
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-21 17:34:08 +08:00
|
|
|
// Dial creates a new AmqpConnection
|
2024-11-15 15:37:28 +08:00
|
|
|
// with a new AmqpManagement and a new LifeCycle.
|
|
|
|
|
// Returns a pointer to the new AmqpConnection
|
2024-11-21 17:34:08 +08:00
|
|
|
func Dial(ctx context.Context, addr string, connOptions *amqp.ConnOptions) (IConnection, error) {
|
|
|
|
|
conn := &AmqpConnection{
|
2024-09-10 17:26:46 +08:00
|
|
|
management: NewAmqpManagement(),
|
|
|
|
|
lifeCycle: NewLifeCycle(),
|
|
|
|
|
}
|
2024-11-21 17:34:08 +08:00
|
|
|
err := conn.open(ctx, addr, connOptions)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
2024-11-15 15:37:28 +08:00
|
|
|
}
|
2024-11-21 17:34:08 +08:00
|
|
|
return conn, nil
|
2024-11-15 15:37:28 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Open opens a connection to the AMQP 1.0 server.
|
|
|
|
|
// using the provided connectionSettings and the AMQPLite library.
|
|
|
|
|
// Setups the connection and the management interface.
|
2024-11-21 17:34:08 +08:00
|
|
|
func (a *AmqpConnection) open(ctx context.Context, addr string, connOptions *amqp.ConnOptions) error {
|
|
|
|
|
|
|
|
|
|
if connOptions == nil {
|
|
|
|
|
connOptions = &amqp.ConnOptions{
|
|
|
|
|
// RabbitMQ requires SASL security layer
|
|
|
|
|
// to be enabled for AMQP 1.0 connections.
|
|
|
|
|
// So this is mandatory and default in case not defined.
|
|
|
|
|
SASLType: amqp.SASLTypeAnonymous(),
|
|
|
|
|
}
|
2024-09-11 20:42:05 +08:00
|
|
|
}
|
2024-09-10 17:26:46 +08:00
|
|
|
|
2024-11-21 17:34:08 +08:00
|
|
|
//connOptions.HostName is the way to set the virtual host
|
|
|
|
|
// so we need to pre-parse the URI to get the virtual host
|
|
|
|
|
// the PARSE is copied from go-amqp091 library
|
|
|
|
|
// the URI will be parsed is parsed again in the amqp lite library
|
|
|
|
|
uri, err := ParseURI(addr)
|
2024-09-10 17:26:46 +08:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2024-11-21 17:34:08 +08:00
|
|
|
connOptions.HostName = fmt.Sprintf("vhost:%s", uri.Vhost)
|
2024-09-10 17:26:46 +08:00
|
|
|
|
2024-11-21 17:34:08 +08:00
|
|
|
conn, err := amqp.Dial(ctx, addr, connOptions)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
a.Connection = conn
|
|
|
|
|
a.session, err = a.Connection.NewSession(ctx, nil)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2024-09-10 17:26:46 +08:00
|
|
|
err = a.Management().Open(ctx, a)
|
|
|
|
|
if err != nil {
|
2024-09-18 00:59:33 +08:00
|
|
|
// TODO close connection?
|
2024-09-10 17:26:46 +08:00
|
|
|
return err
|
|
|
|
|
}
|
2024-11-21 17:34:08 +08:00
|
|
|
|
|
|
|
|
a.lifeCycle.SetStatus(Open)
|
2024-09-10 17:26:46 +08:00
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (a *AmqpConnection) Close(ctx context.Context) error {
|
|
|
|
|
err := a.Management().Close(ctx)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
err = a.Connection.Close()
|
|
|
|
|
a.lifeCycle.SetStatus(Closed)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (a *AmqpConnection) NotifyStatusChange(channel chan *StatusChanged) {
|
|
|
|
|
a.lifeCycle.chStatusChanged = channel
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-15 15:37:28 +08:00
|
|
|
func (a *AmqpConnection) Status() int {
|
2024-09-10 17:26:46 +08:00
|
|
|
return a.lifeCycle.Status()
|
|
|
|
|
}
|