github.com/wfusion/gofusion@v1.1.14/common/infra/watermill/pubsub/amqp/correlatingmarshaler.go (about)

     1  package amqp
     2  
     3  import (
     4  	"github.com/pkg/errors"
     5  
     6  	"github.com/wfusion/gofusion/common/infra/watermill/message"
     7  
     8  	amqp "github.com/rabbitmq/amqp091-go"
     9  )
    10  
    11  // CorrelatingMarshaler will pass UUID through the AMQP native correlation ID rather than as a header
    12  type CorrelatingMarshaler struct {
    13  	// PostprocessPublishing can be used to make some extra processing with amqp.Publishing,
    14  	// for example add CorrelationId and ContentType:
    15  	//
    16  	//  amqp.DefaultMarshaler{
    17  	//		PostprocessPublishing: func(publishing stdAmqp.Publishing) stdAmqp.Publishing {
    18  	//			publishing.CorrelationId = "correlation"
    19  	//			publishing.ContentType = "application/json"
    20  	//
    21  	//			return publishing
    22  	//		},
    23  	//	}
    24  	PostprocessPublishing func(amqp.Publishing) amqp.Publishing
    25  
    26  	// When true, DeliveryMode will be not set to Persistent.
    27  	//
    28  	// DeliveryMode Transient means higher throughput, but messages will not be
    29  	// restored on broker restart. The delivery mode of publishings is unrelated
    30  	// to the durability of the queues they reside on. Transient messages will
    31  	// not be restored to durable queues, persistent messages will be restored to
    32  	// durable queues and lost on non-durable queues during server restart.
    33  	NotPersistentDeliveryMode bool
    34  }
    35  
    36  func (cm CorrelatingMarshaler) Marshal(msg *message.Message) (amqp.Publishing, error) {
    37  	headers := make(amqp.Table, len(msg.Metadata))
    38  
    39  	for key, value := range msg.Metadata {
    40  		headers[key] = value
    41  	}
    42  
    43  	publishing := amqp.Publishing{
    44  		Body:          msg.Payload,
    45  		Headers:       headers,
    46  		CorrelationId: msg.UUID,
    47  	}
    48  	if !cm.NotPersistentDeliveryMode {
    49  		publishing.DeliveryMode = amqp.Persistent
    50  	}
    51  
    52  	if cm.PostprocessPublishing != nil {
    53  		publishing = cm.PostprocessPublishing(publishing)
    54  	}
    55  
    56  	return publishing, nil
    57  }
    58  
    59  func (cm CorrelatingMarshaler) Unmarshal(amqpMsg amqp.Delivery) (*message.Message, error) {
    60  	msg := message.NewMessage(amqpMsg.CorrelationId, amqpMsg.Body)
    61  	msg.Metadata = make(message.Metadata)
    62  
    63  	for key, value := range amqpMsg.Headers {
    64  		var ok bool
    65  		msg.Metadata[key], ok = value.(string)
    66  		if !ok {
    67  			return nil, errors.Errorf("metadata %s is not a string, but %#v", key, value)
    68  		}
    69  	}
    70  
    71  	return msg, nil
    72  }