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  }