github.com/mundipagg/boleto-api@v0.0.0-20230620145841-3f9ec742599f/queue/rabbitmq.go (about) 1 package queue 2 3 import ( 4 "crypto/tls" 5 "errors" 6 "fmt" 7 "strconv" 8 "time" 9 10 "github.com/mundipagg/boleto-api/config" 11 "github.com/mundipagg/boleto-api/util" 12 13 "github.com/mundipagg/healthcheck-go/checks/rabbit" 14 "github.com/streadway/amqp" 15 ) 16 17 const HEARTBEAT_DEFAULT = 10 18 19 func openChannel(conn *amqp.Connection, op string) (*amqp.Channel, error) { 20 var channel *amqp.Channel 21 var err error 22 23 if conn == nil { 24 err = errors.New("failed to open a channel. The connection is closed") 25 failOnError(err, "Failed to open a channel. The connection is closed", op) 26 return nil, err 27 } 28 29 if channel, err = conn.Channel(); err != nil { 30 failOnError(err, "Failed to open a channel", op) 31 return nil, err 32 } 33 34 if err = channel.Confirm(false); err != nil { 35 failOnError(err, "Failed to set channel into Confirm Mode", op) 36 return nil, err 37 } 38 39 if err = channel.Qos(1, 0, false); err != nil { 40 failOnError(err, "Error setting qos", op) 41 return nil, err 42 } 43 44 return channel, err 45 } 46 47 func closeChannel(channel *amqp.Channel, op string) { 48 if channel != nil { 49 err := channel.Close() 50 failOnError(err, "Failed to close a channel", op) 51 } 52 } 53 54 func exchangeDeclare(channel *amqp.Channel, exchange, kind string) bool { 55 err := channel.ExchangeDeclare(exchange, kind, true, false, false, false, nil) 56 hdr := fmt.Sprintf("[{Application}: {Operation}] - Error Declaring RabbitMQ Exchange %s", exchange) 57 failOnError(err, hdr, "ExchangeDeclare") 58 return err == nil 59 } 60 61 func queueDeclare(channel *amqp.Channel, q amqp.Queue, queueName string) bool { 62 63 q, err := channel.QueueDeclare(queueName, true, false, false, false, nil) 64 hdr := fmt.Sprintf("[{Application}: {Operation}] - Error Declaring RabbitMQ Queue %s", queueName) 65 failOnError(err, hdr, "QueueDeclare") 66 return err == nil 67 } 68 69 func queueBinding(channel *amqp.Channel, queue, exchange, key string) bool { 70 err := channel.QueueBind(queue, key, exchange, false, nil) 71 hdr := fmt.Sprintf("[{Application}: {Operation}] - Error Binding RabbitMQ Queue %s into Exchange %s", queue, exchange) 72 failOnError(err, hdr, "QueueBinding") 73 return err == nil 74 } 75 76 func writeMessage(channel *amqp.Channel, p PublisherInterface) error { 77 notifyConfirm := make(chan amqp.Confirmation) 78 channel.NotifyPublish(notifyConfirm) 79 80 err := channel.Publish( 81 p.GetExchangeName(), 82 p.GetRoutingKey(), // queue 83 false, // mandatory 84 false, // immediate 85 amqp.Publishing{ 86 DeliveryMode: amqp.Persistent, 87 ContentType: "text/plain, charset=UTF-8", 88 Body: p.GetMessageToPublish(), 89 }) 90 91 if err == nil { 92 if confirm := <-notifyConfirm; !confirm.Ack { 93 err = errors.New("nack received from the server during message posting") 94 } 95 } 96 97 failOnError(err, "Failed to publish a message", "WriteMessage") 98 return err 99 } 100 101 func openConnection() (*amqp.Connection, error) { 102 103 var hb int 104 var err error 105 106 if hb, err = strconv.Atoi(config.Get().Heartbeat); err != nil { 107 hb = HEARTBEAT_DEFAULT 108 } 109 110 conn, err := amqp.DialConfig(config.Get().ConnQueue, amqp.Config{ 111 Heartbeat: time.Duration(hb) * time.Second, 112 TLSClientConfig: &tls.Config{ 113 MinVersion: util.GetTLSVersion(config.Get().QueueMinTLS), 114 MaxVersion: util.GetTLSVersion(config.Get().QueueMaxTLS), 115 InsecureSkipVerify: config.Get().QueueByPassCertificate, 116 }, 117 }) 118 119 return conn, err 120 } 121 122 func closeConnection(conn *amqp.Connection, op string) { 123 if conn != nil { 124 err := conn.Close() 125 failOnError(err, "Failed to close connection to RabbitMQ", op) 126 } 127 } 128 129 func GetQueueConfiguration() *rabbit.Config { 130 return &rabbit.Config{ 131 ConnectionString: config.Get().ConnQueue, 132 } 133 }