github.com/wfusion/gofusion@v1.1.14/mq/amqp.go (about) 1 package mq 2 3 import ( 4 "context" 5 "fmt" 6 "strings" 7 8 "github.com/pkg/errors" 9 "github.com/wfusion/gofusion/common/utils" 10 "github.com/wfusion/gofusion/config" 11 12 "github.com/wfusion/gofusion/common/infra/watermill" 13 "github.com/wfusion/gofusion/common/infra/watermill/pubsub/amqp" 14 ) 15 16 func newAMQP(ctx context.Context, appName, name string, conf *Conf, logger watermill.LoggerAdapter) ( 17 pub Publisher, sub Subscriber) { 18 if conf.Producer { 19 pub = newAMQPPublisher(ctx, appName, name, conf, logger) 20 } 21 22 if conf.Consumer { 23 sub = newAMQPSubscriber(ctx, appName, name, conf, logger) 24 } 25 26 return 27 } 28 29 type _AMQPPublisher struct { 30 *abstractMQ 31 publisher *amqp.Publisher 32 } 33 34 func newAMQPPublisher(ctx context.Context, appName, name string, conf *Conf, logger watermill.LoggerAdapter) Publisher { 35 ep := parseAMQPEndpoint(conf) 36 37 var genFunc amqp.QueueNameGenerator 38 if utils.IsStrNotBlank(conf.ConsumerGroup) { 39 genFunc = amqp.GenerateQueueNameTopicNameWithSuffix(conf.ConsumerGroup) 40 } else { 41 genFunc = amqp.GenerateQueueNameTopicName 42 } 43 44 var cfg amqp.Config 45 if conf.Persistent { 46 cfg = amqp.NewDurablePubSubConfig(ep, genFunc) 47 } else { 48 cfg = amqp.NewNonDurablePubSubConfig(ep, genFunc) 49 } 50 51 cfg.Marshaler = amqp.DefaultMarshaler{ 52 NotPersistentDeliveryMode: !conf.Persistent, 53 AppID: config.Use(appName).AppName(), 54 } 55 56 pub, err := amqp.NewPublisher(cfg, logger) 57 if err != nil { 58 panic(errors.Wrapf(err, "initialize mq component amqp publisher failed: %s", err)) 59 } 60 61 return &_AMQPPublisher{ 62 abstractMQ: newPub(ctx, pub, appName, name, conf, logger), 63 publisher: pub, 64 } 65 } 66 67 func (a *_AMQPPublisher) close() (err error) { 68 return a.publisher.Close() 69 } 70 71 type _AMQPSubscriber struct { 72 *abstractMQ 73 subscriber *amqp.Subscriber 74 } 75 76 func newAMQPSubscriber(ctx context.Context, appName, name string, conf *Conf, logger watermill.LoggerAdapter) Subscriber { 77 ep := parseAMQPEndpoint(conf) 78 79 var genFunc amqp.QueueNameGenerator 80 if utils.IsStrNotBlank(conf.ConsumerGroup) { 81 genFunc = amqp.GenerateQueueNameTopicNameWithSuffix(conf.ConsumerGroup) 82 } else { 83 genFunc = amqp.GenerateQueueNameTopicName 84 } 85 86 var cfg amqp.Config 87 if conf.Persistent { 88 cfg = amqp.NewDurablePubSubConfig(ep, genFunc) 89 } else { 90 cfg = amqp.NewNonDurablePubSubConfig(ep, genFunc) 91 } 92 93 sub, err := amqp.NewSubscriber(cfg, logger) 94 if err != nil { 95 panic(errors.Wrapf(err, "initialize mq component amqp subscriber failed: %s", err)) 96 } 97 98 utils.MustSuccess(sub.SubscribeInitialize(conf.Topic)) 99 100 return &_AMQPSubscriber{ 101 abstractMQ: newSub(ctx, sub, appName, name, conf, logger), 102 subscriber: sub, 103 } 104 } 105 106 func (a *_AMQPSubscriber) close() (err error) { 107 return a.subscriber.Close() 108 } 109 110 func parseAMQPEndpoint(conf *Conf) (result string) { 111 hasUser := utils.IsStrNotBlank(conf.Endpoint.User) 112 hasPassword := utils.IsStrNotBlank(conf.Endpoint.Password) 113 if hasUser && hasPassword { 114 addr := strings.TrimPrefix(conf.Endpoint.Addresses[0], "amqp://") 115 result = fmt.Sprintf("amqp://%s:%s@%s", conf.Endpoint.User, conf.Endpoint.Password, addr) 116 } else if hasUser { 117 addr := strings.TrimPrefix(conf.Endpoint.Addresses[0], "amqp://") 118 result = fmt.Sprintf("amqp://%s@%s", conf.Endpoint.User, addr) 119 } else { 120 addr := strings.TrimPrefix(conf.Endpoint.Addresses[0], "amqp://") 121 result = fmt.Sprintf("amqp://%s", addr) 122 } 123 124 return 125 }