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 }