Rename the package name (#29)
* Rename the package name * Fixes https://github.com/rabbitmq/rabbitmq-amqp-go-client/issues/28 Signed-off-by: Gabriele Santomaggio <G.santomaggio@gmail.com>
This commit is contained in:
parent
72ac394935
commit
54eab6556d
4
Makefile
4
Makefile
|
|
@ -4,10 +4,10 @@ format:
|
||||||
go fmt ./...
|
go fmt ./...
|
||||||
|
|
||||||
vet:
|
vet:
|
||||||
go vet ./pkg/rabbitmq_amqp
|
go vet ./pkg/rabbitmqamqp
|
||||||
|
|
||||||
test: format vet
|
test: format vet
|
||||||
cd ./pkg/rabbitmq_amqp && go run -mod=mod github.com/onsi/ginkgo/v2/ginkgo \
|
cd ./pkg/rabbitmqamqp && go run -mod=mod github.com/onsi/ginkgo/v2/ginkgo \
|
||||||
--randomize-all --randomize-suites \
|
--randomize-all --randomize-suites \
|
||||||
--cover --coverprofile=coverage.txt --covermode=atomic \
|
--cover --coverprofile=coverage.txt --covermode=atomic \
|
||||||
--race
|
--race
|
||||||
|
|
|
||||||
14
README.md
14
README.md
|
|
@ -1,4 +1,4 @@
|
||||||
# RabbitMQ AMQP 1.0 .Golang Client
|
# RabbitMQ AMQP 1.0 Golang Client
|
||||||
|
|
||||||
This library is meant to be used with RabbitMQ 4.0.
|
This library is meant to be used with RabbitMQ 4.0.
|
||||||
Suitable for testing in pre-production environments.
|
Suitable for testing in pre-production environments.
|
||||||
|
|
@ -6,9 +6,19 @@ Suitable for testing in pre-production environments.
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
- [Getting_started](docs/examples/getting_started)
|
- [Getting Started](docs/examples/getting_started)
|
||||||
- [Examples](docs/examples)
|
- [Examples](docs/examples)
|
||||||
|
|
||||||
|
|
||||||
|
# Packages
|
||||||
|
|
||||||
|
The rabbitmq amqp client is a wrapper around the azure amqp client.</b>
|
||||||
|
You need the following packages to use the rabbitmq amqp client:
|
||||||
|
|
||||||
|
- `rabbitmqamqp` - The main package for the rabbitmq amqp client.
|
||||||
|
- `amqp` - The azure amqp client (You may not need to use this package directly).
|
||||||
|
|
||||||
|
|
||||||
## Build from source
|
## Build from source
|
||||||
|
|
||||||
- Start the broker with `./.ci/ubuntu/gha-setup.sh start`. Note that this has been tested on Ubuntu 22 with docker.
|
- Start the broker with `./.ci/ubuntu/gha-setup.sh start`. Note that this has been tested on Ubuntu 22 with docker.
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/Azure/go-amqp"
|
rmq "github.com/rabbitmq/rabbitmq-amqp-go-client/pkg/rabbitmqamqp"
|
||||||
"github.com/rabbitmq/rabbitmq-amqp-go-client/pkg/rabbitmq_amqp"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -14,62 +13,62 @@ func main() {
|
||||||
queueName := "getting-started-go-queue"
|
queueName := "getting-started-go-queue"
|
||||||
routingKey := "routing-key"
|
routingKey := "routing-key"
|
||||||
|
|
||||||
rabbitmq_amqp.Info("Getting started with AMQP Go AMQP 1.0 Client")
|
rmq.Info("Getting started with AMQP Go AMQP 1.0 Client")
|
||||||
|
|
||||||
/// Create a channel to receive state change notifications
|
/// Create a channel to receive state change notifications
|
||||||
stateChanged := make(chan *rabbitmq_amqp.StateChanged, 1)
|
stateChanged := make(chan *rmq.StateChanged, 1)
|
||||||
go func(ch chan *rabbitmq_amqp.StateChanged) {
|
go func(ch chan *rmq.StateChanged) {
|
||||||
for statusChanged := range ch {
|
for statusChanged := range ch {
|
||||||
rabbitmq_amqp.Info("[connection]", "Status changed", statusChanged)
|
rmq.Info("[connection]", "Status changed", statusChanged)
|
||||||
}
|
}
|
||||||
}(stateChanged)
|
}(stateChanged)
|
||||||
|
|
||||||
// rabbitmq_amqp.NewEnvironment setups the environment.
|
// rmq.NewEnvironment setups the environment.
|
||||||
// The environment is used to create connections
|
// The environment is used to create connections
|
||||||
// given the same parameters
|
// given the same parameters
|
||||||
env := rabbitmq_amqp.NewEnvironment([]string{"amqp://"}, nil)
|
env := rmq.NewEnvironment([]string{"amqp://"}, nil)
|
||||||
|
|
||||||
// Open a connection to the AMQP 1.0 server ( RabbitMQ >= 4.0)
|
// Open a connection to the AMQP 1.0 server ( RabbitMQ >= 4.0)
|
||||||
amqpConnection, err := env.NewConnection(context.Background())
|
amqpConnection, err := env.NewConnection(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rabbitmq_amqp.Error("Error opening connection", err)
|
rmq.Error("Error opening connection", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Register the channel to receive status change notifications
|
// Register the channel to receive status change notifications
|
||||||
// this is valid for the connection lifecycle
|
// this is valid for the connection lifecycle
|
||||||
amqpConnection.NotifyStatusChange(stateChanged)
|
amqpConnection.NotifyStatusChange(stateChanged)
|
||||||
|
|
||||||
rabbitmq_amqp.Info("AMQP connection opened.\n")
|
rmq.Info("AMQP connection opened.\n")
|
||||||
// Create the management interface for the connection
|
// Create the management interface for the connection
|
||||||
// so we can declare exchanges, queues, and bindings
|
// so we can declare exchanges, queues, and bindings
|
||||||
management := amqpConnection.Management()
|
management := amqpConnection.Management()
|
||||||
exchangeInfo, err := management.DeclareExchange(context.TODO(), &rabbitmq_amqp.TopicExchangeSpecification{
|
exchangeInfo, err := management.DeclareExchange(context.TODO(), &rmq.TopicExchangeSpecification{
|
||||||
Name: exchangeName,
|
Name: exchangeName,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rabbitmq_amqp.Error("Error declaring exchange", err)
|
rmq.Error("Error declaring exchange", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Declare a Quorum queue
|
// Declare a Quorum queue
|
||||||
queueInfo, err := management.DeclareQueue(context.TODO(), &rabbitmq_amqp.QuorumQueueSpecification{
|
queueInfo, err := management.DeclareQueue(context.TODO(), &rmq.QuorumQueueSpecification{
|
||||||
Name: queueName,
|
Name: queueName,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rabbitmq_amqp.Error("Error declaring queue", err)
|
rmq.Error("Error declaring queue", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bind the queue to the exchange
|
// Bind the queue to the exchange
|
||||||
bindingPath, err := management.Bind(context.TODO(), &rabbitmq_amqp.ExchangeToQueueBindingSpecification{
|
bindingPath, err := management.Bind(context.TODO(), &rmq.ExchangeToQueueBindingSpecification{
|
||||||
SourceExchange: exchangeName,
|
SourceExchange: exchangeName,
|
||||||
DestinationQueue: queueName,
|
DestinationQueue: queueName,
|
||||||
BindingKey: routingKey,
|
BindingKey: routingKey,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rabbitmq_amqp.Error("Error binding", err)
|
rmq.Error("Error binding", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -78,7 +77,7 @@ func main() {
|
||||||
|
|
||||||
consumer, err := amqpConnection.NewConsumer(context.Background(), queueName, nil)
|
consumer, err := amqpConnection.NewConsumer(context.Background(), queueName, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rabbitmq_amqp.Error("Error creating consumer", err)
|
rmq.Error("Error creating consumer", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -90,61 +89,61 @@ func main() {
|
||||||
deliveryContext, err := consumer.Receive(ctx)
|
deliveryContext, err := consumer.Receive(ctx)
|
||||||
if errors.Is(err, context.Canceled) {
|
if errors.Is(err, context.Canceled) {
|
||||||
// The consumer was closed correctly
|
// The consumer was closed correctly
|
||||||
rabbitmq_amqp.Info("[NewConsumer]", "consumer closed. Context", err)
|
rmq.Info("[NewConsumer]", "consumer closed. Context", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// An error occurred receiving the message
|
// An error occurred receiving the message
|
||||||
rabbitmq_amqp.Error("[NewConsumer]", "Error receiving message", err)
|
rmq.Error("[NewConsumer]", "Error receiving message", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
rabbitmq_amqp.Info("[NewConsumer]", "Received message",
|
rmq.Info("[NewConsumer]", "Received message",
|
||||||
fmt.Sprintf("%s", deliveryContext.Message().Data))
|
fmt.Sprintf("%s", deliveryContext.Message().Data))
|
||||||
|
|
||||||
err = deliveryContext.Accept(context.Background())
|
err = deliveryContext.Accept(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rabbitmq_amqp.Error("Error accepting message", err)
|
rmq.Error("Error accepting message", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}(consumerContext)
|
}(consumerContext)
|
||||||
|
|
||||||
publisher, err := amqpConnection.NewPublisher(context.Background(), &rabbitmq_amqp.ExchangeAddress{
|
publisher, err := amqpConnection.NewPublisher(context.Background(), &rmq.ExchangeAddress{
|
||||||
Exchange: exchangeName,
|
Exchange: exchangeName,
|
||||||
Key: routingKey,
|
Key: routingKey,
|
||||||
}, "getting-started-publisher")
|
}, "getting-started-publisher")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rabbitmq_amqp.Error("Error creating publisher", err)
|
rmq.Error("Error creating publisher", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < 100; i++ {
|
for i := 0; i < 100; i++ {
|
||||||
// Publish a message to the exchange
|
// Publish a message to the exchange
|
||||||
publishResult, err := publisher.Publish(context.Background(), amqp.NewMessage([]byte("Hello, World!"+fmt.Sprintf("%d", i))))
|
publishResult, err := publisher.Publish(context.Background(), rmq.NewMessage([]byte("Hello, World!"+fmt.Sprintf("%d", i))))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rabbitmq_amqp.Error("Error publishing message", "error", err)
|
rmq.Error("Error publishing message", "error", err)
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
switch publishResult.Outcome.(type) {
|
switch publishResult.Outcome.(type) {
|
||||||
case *amqp.StateAccepted:
|
case *rmq.StateAccepted:
|
||||||
rabbitmq_amqp.Info("[NewPublisher]", "Message accepted", publishResult.Message.Data[0])
|
rmq.Info("[NewPublisher]", "Message accepted", publishResult.Message.Data[0])
|
||||||
break
|
break
|
||||||
case *amqp.StateReleased:
|
case *rmq.StateReleased:
|
||||||
rabbitmq_amqp.Warn("[NewPublisher]", "Message was not routed", publishResult.Message.Data[0])
|
rmq.Warn("[NewPublisher]", "Message was not routed", publishResult.Message.Data[0])
|
||||||
break
|
break
|
||||||
case *amqp.StateRejected:
|
case *rmq.StateRejected:
|
||||||
rabbitmq_amqp.Warn("[NewPublisher]", "Message rejected", publishResult.Message.Data[0])
|
rmq.Warn("[NewPublisher]", "Message rejected", publishResult.Message.Data[0])
|
||||||
stateType := publishResult.Outcome.(*amqp.StateRejected)
|
stateType := publishResult.Outcome.(*rmq.StateRejected)
|
||||||
if stateType.Error != nil {
|
if stateType.Error != nil {
|
||||||
rabbitmq_amqp.Warn("[NewPublisher]", "Message rejected with error: %v", stateType.Error)
|
rmq.Warn("[NewPublisher]", "Message rejected with error: %v", stateType.Error)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
// these status are not supported. Leave it for AMQP 1.0 compatibility
|
// these status are not supported. Leave it for AMQP 1.0 compatibility
|
||||||
// see: https://www.rabbitmq.com/docs/next/amqp#outcomes
|
// see: https://www.rabbitmq.com/docs/next/amqp#outcomes
|
||||||
rabbitmq_amqp.Warn("Message state: %v", publishResult.Outcome)
|
rmq.Warn("Message state: %v", publishResult.Outcome)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -157,13 +156,13 @@ func main() {
|
||||||
//Close the consumer
|
//Close the consumer
|
||||||
err = consumer.Close(context.Background())
|
err = consumer.Close(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rabbitmq_amqp.Error("[NewConsumer]", err)
|
rmq.Error("[NewConsumer]", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Close the publisher
|
// Close the publisher
|
||||||
err = publisher.Close(context.Background())
|
err = publisher.Close(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rabbitmq_amqp.Error("[NewPublisher]", err)
|
rmq.Error("[NewPublisher]", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -171,27 +170,27 @@ func main() {
|
||||||
err = management.Unbind(context.TODO(), bindingPath)
|
err = management.Unbind(context.TODO(), bindingPath)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rabbitmq_amqp.Error("Error unbinding: %v\n", err)
|
rmq.Error("Error unbinding: %v\n", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = management.DeleteExchange(context.TODO(), exchangeInfo.Name())
|
err = management.DeleteExchange(context.TODO(), exchangeInfo.Name())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rabbitmq_amqp.Error("Error deleting exchange: %v\n", err)
|
rmq.Error("Error deleting exchange: %v\n", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Purge the queue
|
// Purge the queue
|
||||||
purged, err := management.PurgeQueue(context.TODO(), queueInfo.Name())
|
purged, err := management.PurgeQueue(context.TODO(), queueInfo.Name())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rabbitmq_amqp.Error("Error purging queue: %v\n", err)
|
rmq.Error("Error purging queue: %v\n", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
rabbitmq_amqp.Info("Purged %d messages from the queue.\n", purged)
|
rmq.Info("Purged %d messages from the queue.\n", purged)
|
||||||
|
|
||||||
err = management.DeleteQueue(context.TODO(), queueInfo.Name())
|
err = management.DeleteQueue(context.TODO(), queueInfo.Name())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rabbitmq_amqp.Error("Error deleting queue: %v\n", err)
|
rmq.Error("Error deleting queue: %v\n", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -199,11 +198,11 @@ func main() {
|
||||||
// to create new connections
|
// to create new connections
|
||||||
err = env.CloseConnections(context.Background())
|
err = env.CloseConnections(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rabbitmq_amqp.Error("Error closing connection: %v\n", err)
|
rmq.Error("Error closing connection: %v\n", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
rabbitmq_amqp.Info("AMQP connection closed.\n")
|
rmq.Info("AMQP connection closed.\n")
|
||||||
// not necessary. It waits for the status change to be printed
|
// not necessary. It waits for the status change to be printed
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
close(stateChanged)
|
close(stateChanged)
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,12 @@ package main
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/Azure/go-amqp"
|
"github.com/Azure/go-amqp"
|
||||||
"github.com/rabbitmq/rabbitmq-amqp-go-client/pkg/rabbitmq_amqp"
|
rmq "github.com/rabbitmq/rabbitmq-amqp-go-client/pkg/rabbitmqamqp"
|
||||||
)
|
)
|
||||||
|
|
||||||
func checkError(err error) {
|
func checkError(err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rabbitmq_amqp.Error("Error", err)
|
rmq.Error("Error", err)
|
||||||
// it should not happen for the example
|
// it should not happen for the example
|
||||||
// so panic just to make sure we catch it
|
// so panic just to make sure we catch it
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|
@ -16,15 +16,15 @@ func checkError(err error) {
|
||||||
}
|
}
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
rabbitmq_amqp.Info("Define the publisher message targets")
|
rmq.Info("Define the publisher message targets")
|
||||||
|
|
||||||
env := rabbitmq_amqp.NewEnvironment([]string{"amqp://"}, nil)
|
env := rmq.NewEnvironment([]string{"amqp://"}, nil)
|
||||||
amqpConnection, err := env.NewConnection(context.Background())
|
amqpConnection, err := env.NewConnection(context.Background())
|
||||||
checkError(err)
|
checkError(err)
|
||||||
queues := []string{"queue1", "queue2", "queue3"}
|
queues := []string{"queue1", "queue2", "queue3"}
|
||||||
management := amqpConnection.Management()
|
management := amqpConnection.Management()
|
||||||
for _, queue := range queues {
|
for _, queue := range queues {
|
||||||
_, err = management.DeclareQueue(context.TODO(), &rabbitmq_amqp.QuorumQueueSpecification{
|
_, err = management.DeclareQueue(context.TODO(), &rmq.QuorumQueueSpecification{
|
||||||
Name: queue,
|
Name: queue,
|
||||||
})
|
})
|
||||||
checkError(err)
|
checkError(err)
|
||||||
|
|
@ -40,24 +40,24 @@ func main() {
|
||||||
// with this helper function we create a message with a target
|
// with this helper function we create a message with a target
|
||||||
// that is the same to create a message with:
|
// that is the same to create a message with:
|
||||||
// msg := amqp.NewMessage([]byte("hello"))
|
// msg := amqp.NewMessage([]byte("hello"))
|
||||||
// MessageToAddressHelper(msg, &QueueAddress{Queue: qName})
|
// MessagePropertyToAddress(msg, &QueueAddress{Queue: qName})
|
||||||
// same like:
|
// same like:
|
||||||
// msg := amqp.NewMessage([]byte("hello"))
|
// msg := amqp.NewMessage([]byte("hello"))
|
||||||
// msg.Properties = &amqp.MessageProperties{}
|
// msg.Properties = &amqp.MessageProperties{}
|
||||||
// msg.Properties.To = &address
|
// msg.Properties.To = &address
|
||||||
// NewMessageToAddress and MessageToAddressHelper helpers are provided to make the
|
// NewMessageWithAddress and MessagePropertyToAddress helpers are provided to make the
|
||||||
// code more readable and easier to use
|
// code more readable and easier to use
|
||||||
msg, err := rabbitmq_amqp.NewMessageToAddress([]byte("Hello World"),
|
msg, err := rmq.NewMessageWithAddress([]byte("Hello World"),
|
||||||
&rabbitmq_amqp.QueueAddress{Queue: queues[i%3]})
|
&rmq.QueueAddress{Queue: queues[i%3]})
|
||||||
checkError(err)
|
checkError(err)
|
||||||
publishResult, err := publisher.Publish(context.Background(), msg)
|
publishResult, err := publisher.Publish(context.Background(), msg)
|
||||||
checkError(err)
|
checkError(err)
|
||||||
switch publishResult.Outcome.(type) {
|
switch publishResult.Outcome.(type) {
|
||||||
case *amqp.StateAccepted:
|
case *amqp.StateAccepted:
|
||||||
rabbitmq_amqp.Info("[Publisher]", "Message accepted", publishResult.Message.Data[0])
|
rmq.Info("[Publisher]", "Message accepted", publishResult.Message.Data[0])
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
rabbitmq_amqp.Warn("[Publisher]", "Message not accepted", publishResult.Message.Data[0])
|
rmq.Warn("[Publisher]", "Message not accepted", publishResult.Message.Data[0])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/Azure/go-amqp"
|
"github.com/Azure/go-amqp"
|
||||||
"github.com/rabbitmq/rabbitmq-amqp-go-client/pkg/rabbitmq_amqp"
|
rmq "github.com/rabbitmq/rabbitmq-amqp-go-client/pkg/rabbitmqamqp"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -26,30 +26,30 @@ func main() {
|
||||||
time.Sleep(5 * time.Second)
|
time.Sleep(5 * time.Second)
|
||||||
total := stateAccepted + stateReleased + stateRejected
|
total := stateAccepted + stateReleased + stateRejected
|
||||||
messagesPerSecond := float64(total) / time.Since(startTime).Seconds()
|
messagesPerSecond := float64(total) / time.Since(startTime).Seconds()
|
||||||
rabbitmq_amqp.Info("[Stats]", "sent", total, "received", received, "failed", failed, "messagesPerSecond", messagesPerSecond)
|
rmq.Info("[Stats]", "sent", total, "received", received, "failed", failed, "messagesPerSecond", messagesPerSecond)
|
||||||
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
rabbitmq_amqp.Info("How to deal with network disconnections")
|
rmq.Info("How to deal with network disconnections")
|
||||||
signalBlock := sync.Cond{L: &sync.Mutex{}}
|
signalBlock := sync.Cond{L: &sync.Mutex{}}
|
||||||
/// Create a channel to receive state change notifications
|
/// Create a channel to receive state change notifications
|
||||||
stateChanged := make(chan *rabbitmq_amqp.StateChanged, 1)
|
stateChanged := make(chan *rmq.StateChanged, 1)
|
||||||
go func(ch chan *rabbitmq_amqp.StateChanged) {
|
go func(ch chan *rmq.StateChanged) {
|
||||||
for statusChanged := range ch {
|
for statusChanged := range ch {
|
||||||
rabbitmq_amqp.Info("[connection]", "Status changed", statusChanged)
|
rmq.Info("[connection]", "Status changed", statusChanged)
|
||||||
switch statusChanged.To.(type) {
|
switch statusChanged.To.(type) {
|
||||||
case *rabbitmq_amqp.StateOpen:
|
case *rmq.StateOpen:
|
||||||
signalBlock.Broadcast()
|
signalBlock.Broadcast()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}(stateChanged)
|
}(stateChanged)
|
||||||
|
|
||||||
// Open a connection to the AMQP 1.0 server
|
// Open a connection to the AMQP 1.0 server
|
||||||
amqpConnection, err := rabbitmq_amqp.Dial(context.Background(), []string{"amqp://"}, &rabbitmq_amqp.AmqpConnOptions{
|
amqpConnection, err := rmq.Dial(context.Background(), []string{"amqp://"}, &rmq.AmqpConnOptions{
|
||||||
SASLType: amqp.SASLTypeAnonymous(),
|
SASLType: amqp.SASLTypeAnonymous(),
|
||||||
ContainerID: "reliable-amqp10-go",
|
ContainerID: "reliable-amqp10-go",
|
||||||
RecoveryConfiguration: &rabbitmq_amqp.RecoveryConfiguration{
|
RecoveryConfiguration: &rmq.RecoveryConfiguration{
|
||||||
ActiveRecovery: true,
|
ActiveRecovery: true,
|
||||||
BackOffReconnectInterval: 2 * time.Second, // we reduce the reconnect interval to speed up the test. The default is 5 seconds
|
BackOffReconnectInterval: 2 * time.Second, // we reduce the reconnect interval to speed up the test. The default is 5 seconds
|
||||||
// In production, you should avoid BackOffReconnectInterval with low values since it can cause a high number of reconnection attempts
|
// In production, you should avoid BackOffReconnectInterval with low values since it can cause a high number of reconnection attempts
|
||||||
|
|
@ -57,7 +57,7 @@ func main() {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rabbitmq_amqp.Error("Error opening connection", err)
|
rmq.Error("Error opening connection", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Register the channel to receive status change notifications
|
// Register the channel to receive status change notifications
|
||||||
|
|
@ -69,17 +69,17 @@ func main() {
|
||||||
management := amqpConnection.Management()
|
management := amqpConnection.Management()
|
||||||
|
|
||||||
// Declare a Quorum queue
|
// Declare a Quorum queue
|
||||||
queueInfo, err := management.DeclareQueue(context.TODO(), &rabbitmq_amqp.QuorumQueueSpecification{
|
queueInfo, err := management.DeclareQueue(context.TODO(), &rmq.QuorumQueueSpecification{
|
||||||
Name: queueName,
|
Name: queueName,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rabbitmq_amqp.Error("Error declaring queue", err)
|
rmq.Error("Error declaring queue", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
consumer, err := amqpConnection.NewConsumer(context.Background(), queueName, nil)
|
consumer, err := amqpConnection.NewConsumer(context.Background(), queueName, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rabbitmq_amqp.Error("Error creating consumer", err)
|
rmq.Error("Error creating consumer", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -97,9 +97,9 @@ func main() {
|
||||||
// An error occurred receiving the message
|
// An error occurred receiving the message
|
||||||
// here the consumer could be disconnected from the server due to a network error
|
// here the consumer could be disconnected from the server due to a network error
|
||||||
signalBlock.L.Lock()
|
signalBlock.L.Lock()
|
||||||
rabbitmq_amqp.Info("[Consumer]", "Consumer is blocked, queue", queueName, "error", err)
|
rmq.Info("[Consumer]", "Consumer is blocked, queue", queueName, "error", err)
|
||||||
signalBlock.Wait()
|
signalBlock.Wait()
|
||||||
rabbitmq_amqp.Info("[Consumer]", "Consumer is unblocked, queue", queueName)
|
rmq.Info("[Consumer]", "Consumer is unblocked, queue", queueName)
|
||||||
|
|
||||||
signalBlock.L.Unlock()
|
signalBlock.L.Unlock()
|
||||||
continue
|
continue
|
||||||
|
|
@ -116,11 +116,11 @@ func main() {
|
||||||
}
|
}
|
||||||
}(consumerContext)
|
}(consumerContext)
|
||||||
|
|
||||||
publisher, err := amqpConnection.NewPublisher(context.Background(), &rabbitmq_amqp.QueueAddress{
|
publisher, err := amqpConnection.NewPublisher(context.Background(), &rmq.QueueAddress{
|
||||||
Queue: queueName,
|
Queue: queueName,
|
||||||
}, "reliable-publisher")
|
}, "reliable-publisher")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rabbitmq_amqp.Error("Error creating publisher", err)
|
rmq.Error("Error creating publisher", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -130,7 +130,7 @@ func main() {
|
||||||
go func() {
|
go func() {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
for i := 0; i < 500_000; i++ {
|
for i := 0; i < 500_000; i++ {
|
||||||
publishResult, err := publisher.Publish(context.Background(), amqp.NewMessage([]byte("Hello, World!"+fmt.Sprintf("%d", i))))
|
publishResult, err := publisher.Publish(context.Background(), rmq.NewMessage([]byte("Hello, World!"+fmt.Sprintf("%d", i))))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// here you need to deal with the error. You can store the message in a local in memory/persistent storage
|
// here you need to deal with the error. You can store the message in a local in memory/persistent storage
|
||||||
// then retry to send the message as soon as the connection is reestablished
|
// then retry to send the message as soon as the connection is reestablished
|
||||||
|
|
@ -138,26 +138,26 @@ func main() {
|
||||||
atomic.AddInt32(&failed, 1)
|
atomic.AddInt32(&failed, 1)
|
||||||
// block signalBlock until the connection is reestablished
|
// block signalBlock until the connection is reestablished
|
||||||
signalBlock.L.Lock()
|
signalBlock.L.Lock()
|
||||||
rabbitmq_amqp.Info("[Publisher]", "Publisher is blocked, queue", queueName, "error", err)
|
rmq.Info("[Publisher]", "Publisher is blocked, queue", queueName, "error", err)
|
||||||
signalBlock.Wait()
|
signalBlock.Wait()
|
||||||
rabbitmq_amqp.Info("[Publisher]", "Publisher is unblocked, queue", queueName)
|
rmq.Info("[Publisher]", "Publisher is unblocked, queue", queueName)
|
||||||
signalBlock.L.Unlock()
|
signalBlock.L.Unlock()
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
switch publishResult.Outcome.(type) {
|
switch publishResult.Outcome.(type) {
|
||||||
case *amqp.StateAccepted:
|
case *rmq.StateAccepted:
|
||||||
atomic.AddInt32(&stateAccepted, 1)
|
atomic.AddInt32(&stateAccepted, 1)
|
||||||
break
|
break
|
||||||
case *amqp.StateReleased:
|
case *rmq.StateReleased:
|
||||||
atomic.AddInt32(&stateReleased, 1)
|
atomic.AddInt32(&stateReleased, 1)
|
||||||
break
|
break
|
||||||
case *amqp.StateRejected:
|
case *rmq.StateRejected:
|
||||||
atomic.AddInt32(&stateRejected, 1)
|
atomic.AddInt32(&stateRejected, 1)
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
// these status are not supported. Leave it for AMQP 1.0 compatibility
|
// these status are not supported. Leave it for AMQP 1.0 compatibility
|
||||||
// see: https://www.rabbitmq.com/docs/next/amqp#outcomes
|
// see: https://www.rabbitmq.com/docs/next/amqp#outcomes
|
||||||
rabbitmq_amqp.Warn("Message state: %v", publishResult.Outcome)
|
rmq.Warn("Message state: %v", publishResult.Outcome)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -174,13 +174,13 @@ func main() {
|
||||||
//Close the consumer
|
//Close the consumer
|
||||||
err = consumer.Close(context.Background())
|
err = consumer.Close(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rabbitmq_amqp.Error("[NewConsumer]", err)
|
rmq.Error("[NewConsumer]", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Close the publisher
|
// Close the publisher
|
||||||
err = publisher.Close(context.Background())
|
err = publisher.Close(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rabbitmq_amqp.Error("[NewPublisher]", err)
|
rmq.Error("[NewPublisher]", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,13 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/Azure/go-amqp"
|
rmq "github.com/rabbitmq/rabbitmq-amqp-go-client/pkg/rabbitmqamqp"
|
||||||
"github.com/rabbitmq/rabbitmq-amqp-go-client/pkg/rabbitmq_amqp"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func checkError(err error) {
|
func checkError(err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rabbitmq_amqp.Error("Error", err)
|
rmq.Error("Error", err)
|
||||||
// it should not happen for the example
|
// it should not happen for the example
|
||||||
// so panic just to make sure we catch it
|
// so panic just to make sure we catch it
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|
@ -18,59 +17,59 @@ func checkError(err error) {
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
rabbitmq_amqp.Info("Golang AMQP 1.0 Streams example")
|
rmq.Info("Golang AMQP 1.0 Streams example")
|
||||||
queueStream := "stream-go-queue-" + time.Now().String()
|
queueStream := "stream-go-queue-" + time.Now().String()
|
||||||
env := rabbitmq_amqp.NewEnvironment([]string{"amqp://"}, nil)
|
env := rmq.NewEnvironment([]string{"amqp://"}, nil)
|
||||||
amqpConnection, err := env.NewConnection(context.Background())
|
amqpConnection, err := env.NewConnection(context.Background())
|
||||||
checkError(err)
|
checkError(err)
|
||||||
management := amqpConnection.Management()
|
management := amqpConnection.Management()
|
||||||
// define a stream queue
|
// define a stream queue
|
||||||
_, err = management.DeclareQueue(context.TODO(), &rabbitmq_amqp.StreamQueueSpecification{
|
_, err = management.DeclareQueue(context.TODO(), &rmq.StreamQueueSpecification{
|
||||||
Name: queueStream,
|
Name: queueStream,
|
||||||
// it is a best practice to set the max length of the stream
|
// it is a best practice to set the max length of the stream
|
||||||
// to avoid the stream to grow indefinitely
|
// to avoid the stream to grow indefinitely
|
||||||
// the value here is low just for the example
|
// the value here is low just for the example
|
||||||
MaxLengthBytes: rabbitmq_amqp.CapacityGB(5),
|
MaxLengthBytes: rmq.CapacityGB(5),
|
||||||
})
|
})
|
||||||
checkError(err)
|
checkError(err)
|
||||||
|
|
||||||
// create a stream publisher. In this case we use the QueueAddress to make the example
|
// create a stream publisher. In this case we use the QueueAddress to make the example
|
||||||
// simple. So we use the default exchange here.
|
// simple. So we use the default exchange here.
|
||||||
publisher, err := amqpConnection.NewPublisher(context.TODO(), &rabbitmq_amqp.QueueAddress{Queue: queueStream}, "stream-publisher")
|
publisher, err := amqpConnection.NewPublisher(context.TODO(), &rmq.QueueAddress{Queue: queueStream}, "stream-publisher")
|
||||||
checkError(err)
|
checkError(err)
|
||||||
|
|
||||||
// publish messages to the stream
|
// publish messages to the stream
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
publishResult, err := publisher.Publish(context.Background(), amqp.NewMessage([]byte("Hello World")))
|
publishResult, err := publisher.Publish(context.Background(), rmq.NewMessage([]byte("Hello World")))
|
||||||
checkError(err)
|
checkError(err)
|
||||||
|
|
||||||
// check the outcome of the publishResult
|
// check the outcome of the publishResult
|
||||||
switch publishResult.Outcome.(type) {
|
switch publishResult.Outcome.(type) {
|
||||||
case *amqp.StateAccepted:
|
case *rmq.StateAccepted:
|
||||||
rabbitmq_amqp.Info("[Publisher]", "Message accepted", publishResult.Message.Data[0])
|
rmq.Info("[Publisher]", "Message accepted", publishResult.Message.Data[0])
|
||||||
break
|
break
|
||||||
case *amqp.StateReleased:
|
case *rmq.StateReleased:
|
||||||
rabbitmq_amqp.Warn("[Publisher]", "Message was not routed", publishResult.Message.Data[0])
|
rmq.Warn("[Publisher]", "Message was not routed", publishResult.Message.Data[0])
|
||||||
break
|
break
|
||||||
case *amqp.StateRejected:
|
case *rmq.StateRejected:
|
||||||
rabbitmq_amqp.Warn("[Publisher]", "Message rejected", publishResult.Message.Data[0])
|
rmq.Warn("[Publisher]", "Message rejected", publishResult.Message.Data[0])
|
||||||
stateType := publishResult.Outcome.(*amqp.StateRejected)
|
stateType := publishResult.Outcome.(*rmq.StateRejected)
|
||||||
if stateType.Error != nil {
|
if stateType.Error != nil {
|
||||||
rabbitmq_amqp.Warn("[Publisher]", "Message rejected with error: %v", stateType.Error)
|
rmq.Warn("[Publisher]", "Message rejected with error: %v", stateType.Error)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
// these status are not supported. Leave it for AMQP 1.0 compatibility
|
// these status are not supported. Leave it for AMQP 1.0 compatibility
|
||||||
// see: https://www.rabbitmq.com/docs/next/amqp#outcomes
|
// see: https://www.rabbitmq.com/docs/next/amqp#outcomes
|
||||||
rabbitmq_amqp.Warn("Message state: %v", publishResult.Outcome)
|
rmq.Warn("Message state: %v", publishResult.Outcome)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// create a stream consumer
|
// create a stream consumer
|
||||||
consumer, err := amqpConnection.NewConsumer(context.Background(), queueStream, &rabbitmq_amqp.StreamConsumerOptions{
|
consumer, err := amqpConnection.NewConsumer(context.Background(), queueStream, &rmq.StreamConsumerOptions{
|
||||||
// the offset is set to the first chunk of the stream
|
// the offset is set to the first chunk of the stream
|
||||||
// so here it starts from the beginning
|
// so here it starts from the beginning
|
||||||
Offset: &rabbitmq_amqp.OffsetFirst{},
|
Offset: &rmq.OffsetFirst{},
|
||||||
})
|
})
|
||||||
checkError(err)
|
checkError(err)
|
||||||
|
|
||||||
|
|
@ -78,7 +77,7 @@ func main() {
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
deliveryContext, err := consumer.Receive(context.Background())
|
deliveryContext, err := consumer.Receive(context.Background())
|
||||||
checkError(err)
|
checkError(err)
|
||||||
rabbitmq_amqp.Info("[Consumer]", "Message received", deliveryContext.Message().Data[0])
|
rmq.Info("[Consumer]", "Message received", deliveryContext.Message().Data[0])
|
||||||
// accept the message
|
// accept the message
|
||||||
err = deliveryContext.Accept(context.Background())
|
err = deliveryContext.Accept(context.Background())
|
||||||
checkError(err)
|
checkError(err)
|
||||||
|
|
@ -94,5 +93,5 @@ func main() {
|
||||||
err = env.CloseConnections(context.Background())
|
err = env.CloseConnections(context.Background())
|
||||||
checkError(err)
|
checkError(err)
|
||||||
|
|
||||||
rabbitmq_amqp.Info("Example completed")
|
rmq.Info("Example completed")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,13 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/Azure/go-amqp"
|
rmq "github.com/rabbitmq/rabbitmq-amqp-go-client/pkg/rabbitmqamqp"
|
||||||
"github.com/rabbitmq/rabbitmq-amqp-go-client/pkg/rabbitmq_amqp"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func checkError(err error) {
|
func checkError(err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rabbitmq_amqp.Error("Error", err)
|
rmq.Error("Error", err)
|
||||||
// it should not happen for the example
|
// it should not happen for the example
|
||||||
// so panic just to make sure we catch it
|
// so panic just to make sure we catch it
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|
@ -18,67 +17,62 @@ func checkError(err error) {
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
rabbitmq_amqp.Info("Golang AMQP 1.0 Streams example with filtering")
|
rmq.Info("Golang AMQP 1.0 Streams example with filtering")
|
||||||
queueStream := "stream-go-queue-filtering-" + time.Now().String()
|
queueStream := "stream-go-queue-filtering-" + time.Now().String()
|
||||||
env := rabbitmq_amqp.NewEnvironment([]string{"amqp://"}, nil)
|
env := rmq.NewEnvironment([]string{"amqp://"}, nil)
|
||||||
amqpConnection, err := env.NewConnection(context.Background())
|
amqpConnection, err := env.NewConnection(context.Background())
|
||||||
checkError(err)
|
checkError(err)
|
||||||
management := amqpConnection.Management()
|
management := amqpConnection.Management()
|
||||||
// define a stream queue
|
// define a stream queue
|
||||||
_, err = management.DeclareQueue(context.TODO(), &rabbitmq_amqp.StreamQueueSpecification{
|
_, err = management.DeclareQueue(context.TODO(), &rmq.StreamQueueSpecification{
|
||||||
Name: queueStream,
|
Name: queueStream,
|
||||||
// it is a best practice to set the max length of the stream
|
// it is a best practice to set the max length of the stream
|
||||||
// to avoid the stream to grow indefinitely
|
// to avoid the stream to grow indefinitely
|
||||||
// the value here is low just for the example
|
// the value here is low just for the example
|
||||||
MaxLengthBytes: rabbitmq_amqp.CapacityGB(5),
|
MaxLengthBytes: rmq.CapacityGB(5),
|
||||||
})
|
})
|
||||||
checkError(err)
|
checkError(err)
|
||||||
|
|
||||||
// create a stream publisher. In this case we use the QueueAddress to make the example
|
// create a stream publisher. In this case we use the QueueAddress to make the example
|
||||||
// simple. So we use the default exchange here.
|
// simple. So we use the default exchange here.
|
||||||
publisher, err := amqpConnection.NewPublisher(context.TODO(), &rabbitmq_amqp.QueueAddress{Queue: queueStream}, "stream-publisher")
|
publisher, err := amqpConnection.NewPublisher(context.TODO(), &rmq.QueueAddress{Queue: queueStream}, "stream-publisher")
|
||||||
checkError(err)
|
checkError(err)
|
||||||
|
|
||||||
filters := []string{"MyFilter1", "MyFilter2", "MyFilter3", "MyFilter4"}
|
filters := []string{"MyFilter1", "MyFilter2", "MyFilter3", "MyFilter4"}
|
||||||
|
|
||||||
// publish messages to the stream
|
// publish messages to the stream
|
||||||
for i := 0; i < 40; i++ {
|
for i := 0; i < 40; i++ {
|
||||||
msg := amqp.NewMessage([]byte("Hello World! with filter:" + filters[i%4]))
|
msg := rmq.NewMessageWithFilter([]byte("Hello World"), filters[i%4])
|
||||||
// add a filter to the message
|
|
||||||
msg.Annotations = amqp.Annotations{
|
|
||||||
// here we set the filter value taken from the filters array
|
|
||||||
rabbitmq_amqp.StreamFilterValue: filters[i%4],
|
|
||||||
}
|
|
||||||
publishResult, err := publisher.Publish(context.Background(), msg)
|
publishResult, err := publisher.Publish(context.Background(), msg)
|
||||||
checkError(err)
|
checkError(err)
|
||||||
|
|
||||||
// check the outcome of the publishResult
|
// check the outcome of the publishResult
|
||||||
switch publishResult.Outcome.(type) {
|
switch publishResult.Outcome.(type) {
|
||||||
case *amqp.StateAccepted:
|
case *rmq.StateAccepted:
|
||||||
rabbitmq_amqp.Info("[Publisher]", "Message accepted", publishResult.Message.Data[0])
|
rmq.Info("[Publisher]", "Message accepted", publishResult.Message.Data[0])
|
||||||
break
|
break
|
||||||
case *amqp.StateReleased:
|
case *rmq.StateReleased:
|
||||||
rabbitmq_amqp.Warn("[Publisher]", "Message was not routed", publishResult.Message.Data[0])
|
rmq.Warn("[Publisher]", "Message was not routed", publishResult.Message.Data[0])
|
||||||
break
|
break
|
||||||
case *amqp.StateRejected:
|
case *rmq.StateRejected:
|
||||||
rabbitmq_amqp.Warn("[Publisher]", "Message rejected", publishResult.Message.Data[0])
|
rmq.Warn("[Publisher]", "Message rejected", publishResult.Message.Data[0])
|
||||||
stateType := publishResult.Outcome.(*amqp.StateRejected)
|
stateType := publishResult.Outcome.(*rmq.StateRejected)
|
||||||
if stateType.Error != nil {
|
if stateType.Error != nil {
|
||||||
rabbitmq_amqp.Warn("[Publisher]", "Message rejected with error: %v", stateType.Error)
|
rmq.Warn("[Publisher]", "Message rejected with error: %v", stateType.Error)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
// these status are not supported. Leave it for AMQP 1.0 compatibility
|
// these status are not supported. Leave it for AMQP 1.0 compatibility
|
||||||
// see: https://www.rabbitmq.com/docs/next/amqp#outcomes
|
// see: https://www.rabbitmq.com/docs/next/amqp#outcomes
|
||||||
rabbitmq_amqp.Warn("Message state: %v", publishResult.Outcome)
|
rmq.Warn("Message state: %v", publishResult.Outcome)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// create a stream consumer
|
// create a stream consumer
|
||||||
consumer, err := amqpConnection.NewConsumer(context.Background(), queueStream, &rabbitmq_amqp.StreamConsumerOptions{
|
consumer, err := amqpConnection.NewConsumer(context.Background(), queueStream, &rmq.StreamConsumerOptions{
|
||||||
// the offset is set to the first chunk of the stream
|
// the offset is set to the first chunk of the stream
|
||||||
// so here it starts from the beginning
|
// so here it starts from the beginning
|
||||||
Offset: &rabbitmq_amqp.OffsetFirst{},
|
Offset: &rmq.OffsetFirst{},
|
||||||
|
|
||||||
// add a filter to the consumer, in this case we use only the filter values
|
// add a filter to the consumer, in this case we use only the filter values
|
||||||
// MyFilter1 and MyFilter2. So all other messages won't be received
|
// MyFilter1 and MyFilter2. So all other messages won't be received
|
||||||
|
|
@ -92,7 +86,7 @@ func main() {
|
||||||
for i := 0; i < 20; i++ {
|
for i := 0; i < 20; i++ {
|
||||||
deliveryContext, err := consumer.Receive(context.Background())
|
deliveryContext, err := consumer.Receive(context.Background())
|
||||||
checkError(err)
|
checkError(err)
|
||||||
rabbitmq_amqp.Info("[Consumer]", "Message received", deliveryContext.Message().Data[0])
|
rmq.Info("[Consumer]", "Message received", deliveryContext.Message().Data[0])
|
||||||
// accept the message
|
// accept the message
|
||||||
err = deliveryContext.Accept(context.Background())
|
err = deliveryContext.Accept(context.Background())
|
||||||
checkError(err)
|
checkError(err)
|
||||||
|
|
@ -108,5 +102,5 @@ func main() {
|
||||||
err = env.CloseConnections(context.Background())
|
err = env.CloseConnections(context.Background())
|
||||||
checkError(err)
|
checkError(err)
|
||||||
|
|
||||||
rabbitmq_amqp.Info("Example completed")
|
rmq.Info("Example completed")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
package rabbitmq_amqp
|
package rabbitmqamqp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/Azure/go-amqp"
|
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -45,38 +44,6 @@ func (eas *ExchangeAddress) toAddress() (string, error) {
|
||||||
return exchangeAddress(ex, k)
|
return exchangeAddress(ex, k)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MessageToAddressHelper sets the To property of the message to the address of the target.
|
|
||||||
// The target must be a QueueAddress or an ExchangeAddress.
|
|
||||||
// Note: The field msgRef.Properties.To will be overwritten if it is already set.
|
|
||||||
func MessageToAddressHelper(msgRef *amqp.Message, target TargetAddress) error {
|
|
||||||
if target == nil {
|
|
||||||
return errors.New("target cannot be nil")
|
|
||||||
}
|
|
||||||
|
|
||||||
address, err := target.toAddress()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if msgRef.Properties == nil {
|
|
||||||
msgRef.Properties = &amqp.MessageProperties{}
|
|
||||||
}
|
|
||||||
msgRef.Properties.To = &address
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewMessageToAddress creates a new message with the given payload and sets the To property to the address of the target.
|
|
||||||
// The target must be a QueueAddress or an ExchangeAddress.
|
|
||||||
// This function is a helper that combines NewMessage and MessageToAddressHelper.
|
|
||||||
func NewMessageToAddress(msg []byte, target TargetAddress) (*amqp.Message, error) {
|
|
||||||
message := amqp.NewMessage(msg)
|
|
||||||
err := MessageToAddressHelper(message, target)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return message, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// address Creates the address for the exchange or queue following the RabbitMQ conventions.
|
// address Creates the address for the exchange or queue following the RabbitMQ conventions.
|
||||||
// see: https://www.rabbitmq.com/docs/next/amqp#address-v2
|
// see: https://www.rabbitmq.com/docs/next/amqp#address-v2
|
||||||
func address(exchange, key, queue *string, urlParameters *string) (string, error) {
|
func address(exchange, key, queue *string, urlParameters *string) (string, error) {
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package rabbitmq_amqp
|
package rabbitmqamqp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
. "github.com/onsi/ginkgo/v2"
|
. "github.com/onsi/ginkgo/v2"
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package rabbitmq_amqp
|
package rabbitmqamqp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package rabbitmq_amqp
|
package rabbitmqamqp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package rabbitmq_amqp
|
package rabbitmqamqp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package rabbitmq_amqp
|
package rabbitmqamqp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package rabbitmq_amqp
|
package rabbitmqamqp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package rabbitmq_amqp
|
package rabbitmqamqp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package rabbitmq_amqp
|
package rabbitmqamqp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package rabbitmq_amqp
|
package rabbitmqamqp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
@ -21,10 +21,7 @@ func publishMessagesWithStreamTag(queueName string, filterValue string, count in
|
||||||
|
|
||||||
for i := 0; i < count; i++ {
|
for i := 0; i < count; i++ {
|
||||||
body := filterValue + " #" + strconv.Itoa(i)
|
body := filterValue + " #" + strconv.Itoa(i)
|
||||||
msg := amqp.NewMessage([]byte(body))
|
msg := NewMessageWithFilter([]byte(body), filterValue)
|
||||||
msg.Annotations = amqp.Annotations{
|
|
||||||
StreamFilterValue: filterValue,
|
|
||||||
}
|
|
||||||
publishResult, err := publisher.Publish(context.TODO(), msg)
|
publishResult, err := publisher.Publish(context.TODO(), msg)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
Expect(publishResult).NotTo(BeNil())
|
Expect(publishResult).NotTo(BeNil())
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package rabbitmq_amqp
|
package rabbitmqamqp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package rabbitmq_amqp
|
package rabbitmqamqp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package rabbitmq_amqp
|
package rabbitmqamqp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package rabbitmq_amqp
|
package rabbitmqamqp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package rabbitmq_amqp
|
package rabbitmqamqp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package rabbitmq_amqp
|
package rabbitmqamqp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package rabbitmq_amqp
|
package rabbitmqamqp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package rabbitmq_amqp
|
package rabbitmqamqp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
@ -9,7 +9,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type PublishResult struct {
|
type PublishResult struct {
|
||||||
Outcome amqp.DeliveryState
|
Outcome DeliveryState
|
||||||
Message *amqp.Message
|
Message *amqp.Message
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -63,12 +63,12 @@ RabbitMQ supports the following DeliveryState types:
|
||||||
See: https://www.rabbitmq.com/docs/next/amqp#outcomes for more information.
|
See: https://www.rabbitmq.com/docs/next/amqp#outcomes for more information.
|
||||||
|
|
||||||
Note: If the destination address is not defined during the creation, the message must have a TO property set.
|
Note: If the destination address is not defined during the creation, the message must have a TO property set.
|
||||||
You can use the helper "MessageToAddressHelper" to create the destination address.
|
You can use the helper "MessagePropertyToAddress" to create the destination address.
|
||||||
See the examples:
|
See the examples:
|
||||||
Create a new publisher that sends messages to a specific destination address:
|
Create a new publisher that sends messages to a specific destination address:
|
||||||
<code>
|
<code>
|
||||||
|
|
||||||
publisher, err := amqpConnection.NewPublisher(context.Background(), &rabbitmq_amqp.ExchangeAddress{
|
publisher, err := amqpConnection.NewPublisher(context.Background(), &rabbitmqamqp.ExchangeAddress{
|
||||||
Exchange: "myExchangeName",
|
Exchange: "myExchangeName",
|
||||||
Key: "myRoutingKey",
|
Key: "myRoutingKey",
|
||||||
}
|
}
|
||||||
|
|
@ -81,7 +81,7 @@ Create a new publisher that sends messages based on message destination address:
|
||||||
|
|
||||||
publisher, err := connection.NewPublisher(context.Background(), nil, "test")
|
publisher, err := connection.NewPublisher(context.Background(), nil, "test")
|
||||||
msg := amqp.NewMessage([]byte("hello"))
|
msg := amqp.NewMessage([]byte("hello"))
|
||||||
..:= MessageToAddressHelper(msg, &QueueAddress{Queue: "myQueueName"})
|
..:= MessagePropertyToAddress(msg, &QueueAddress{Queue: "myQueueName"})
|
||||||
..:= publisher.Publish(context.Background(), msg)
|
..:= publisher.Publish(context.Background(), msg)
|
||||||
|
|
||||||
</code>
|
</code>
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package rabbitmq_amqp
|
package rabbitmqamqp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
@ -23,7 +23,7 @@ var _ = Describe("AMQP publisher ", func() {
|
||||||
Expect(publisher).NotTo(BeNil())
|
Expect(publisher).NotTo(BeNil())
|
||||||
Expect(publisher).To(BeAssignableToTypeOf(&Publisher{}))
|
Expect(publisher).To(BeAssignableToTypeOf(&Publisher{}))
|
||||||
|
|
||||||
publishResult, err := publisher.Publish(context.Background(), amqp.NewMessage([]byte("hello")))
|
publishResult, err := publisher.Publish(context.Background(), NewMessage([]byte("hello")))
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
Expect(publishResult).NotTo(BeNil())
|
Expect(publishResult).NotTo(BeNil())
|
||||||
Expect(publishResult.Outcome).To(Equal(&amqp.StateAccepted{}))
|
Expect(publishResult.Outcome).To(Equal(&amqp.StateAccepted{}))
|
||||||
|
|
@ -65,10 +65,10 @@ var _ = Describe("AMQP publisher ", func() {
|
||||||
}, "test")
|
}, "test")
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
Expect(publisher).NotTo(BeNil())
|
Expect(publisher).NotTo(BeNil())
|
||||||
publishResult, err := publisher.Publish(context.Background(), amqp.NewMessage([]byte("hello")))
|
publishResult, err := publisher.Publish(context.Background(), NewMessage([]byte("hello")))
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
Expect(publishResult).NotTo(BeNil())
|
Expect(publishResult).NotTo(BeNil())
|
||||||
Expect(publishResult.Outcome).To(Equal(&amqp.StateReleased{}))
|
Expect(publishResult.Outcome).To(Equal(&StateReleased{}))
|
||||||
Expect(connection.Management().DeleteExchange(context.Background(), eName)).To(BeNil())
|
Expect(connection.Management().DeleteExchange(context.Background(), eName)).To(BeNil())
|
||||||
Expect(connection.Close(context.Background())).To(BeNil())
|
Expect(connection.Close(context.Background())).To(BeNil())
|
||||||
})
|
})
|
||||||
|
|
@ -85,12 +85,12 @@ var _ = Describe("AMQP publisher ", func() {
|
||||||
publisher, err := connection.NewPublisher(context.Background(), &QueueAddress{Queue: qName}, "test")
|
publisher, err := connection.NewPublisher(context.Background(), &QueueAddress{Queue: qName}, "test")
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
Expect(publisher).NotTo(BeNil())
|
Expect(publisher).NotTo(BeNil())
|
||||||
publishResult, err := publisher.Publish(context.Background(), amqp.NewMessage([]byte("hello")))
|
publishResult, err := publisher.Publish(context.Background(), NewMessage([]byte("hello")))
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
Expect(publishResult.Outcome).To(Equal(&amqp.StateAccepted{}))
|
Expect(publishResult.Outcome).To(Equal(&StateAccepted{}))
|
||||||
err = connection.management.DeleteQueue(context.Background(), qName)
|
err = connection.management.DeleteQueue(context.Background(), qName)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
publishResult, err = publisher.Publish(context.Background(), amqp.NewMessage([]byte("hello")))
|
publishResult, err = publisher.Publish(context.Background(), NewMessage([]byte("hello")))
|
||||||
Expect(err).NotTo(BeNil())
|
Expect(err).NotTo(BeNil())
|
||||||
Expect(connection.Close(context.Background()))
|
Expect(connection.Close(context.Background()))
|
||||||
})
|
})
|
||||||
|
|
@ -104,12 +104,12 @@ var _ = Describe("AMQP publisher ", func() {
|
||||||
Expect(publisher).NotTo(BeNil())
|
Expect(publisher).NotTo(BeNil())
|
||||||
qName := generateNameWithDateTime("Targets NewPublisher should fail when the destination does not exist")
|
qName := generateNameWithDateTime("Targets NewPublisher should fail when the destination does not exist")
|
||||||
msg := amqp.NewMessage([]byte("hello"))
|
msg := amqp.NewMessage([]byte("hello"))
|
||||||
Expect(MessageToAddressHelper(msg, &QueueAddress{Queue: qName})).To(BeNil())
|
Expect(MessagePropertyToAddress(msg, &QueueAddress{Queue: qName})).To(BeNil())
|
||||||
publishResult, err := publisher.Publish(context.Background(), msg)
|
publishResult, err := publisher.Publish(context.Background(), msg)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
Expect(publishResult).NotTo(BeNil())
|
Expect(publishResult).NotTo(BeNil())
|
||||||
Expect(publishResult.Outcome).To(Equal(&amqp.StateReleased{}))
|
Expect(publishResult.Outcome).To(Equal(&amqp.StateReleased{}))
|
||||||
msg, err = NewMessageToAddress([]byte("hello"), &QueueAddress{Queue: qName})
|
msg, err = NewMessageWithAddress([]byte("hello"), &QueueAddress{Queue: qName})
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
publishResult, err = publisher.Publish(context.Background(), msg)
|
publishResult, err = publisher.Publish(context.Background(), msg)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
|
|
@ -134,25 +134,25 @@ var _ = Describe("AMQP publisher ", func() {
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
// as first message is sent to a queue, the outcome should be StateReceived
|
// as first message is sent to a queue, the outcome should be StateReceived
|
||||||
// since the message was accepted by the existing queue
|
// since the message was accepted by the existing queue
|
||||||
msg := amqp.NewMessage([]byte("hello"))
|
msg := NewMessage([]byte("hello"))
|
||||||
Expect(MessageToAddressHelper(msg, &QueueAddress{Queue: name})).To(BeNil())
|
Expect(MessagePropertyToAddress(msg, &QueueAddress{Queue: name})).To(BeNil())
|
||||||
|
|
||||||
publishResult, err := publisher.Publish(context.Background(), msg)
|
publishResult, err := publisher.Publish(context.Background(), msg)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
Expect(publishResult).NotTo(BeNil())
|
Expect(publishResult).NotTo(BeNil())
|
||||||
Expect(publishResult.Outcome).To(Equal(&amqp.StateAccepted{}))
|
Expect(publishResult.Outcome).To(Equal(&StateAccepted{}))
|
||||||
|
|
||||||
_, err = connection.Management().DeclareExchange(context.Background(), &TopicExchangeSpecification{
|
_, err = connection.Management().DeclareExchange(context.Background(), &TopicExchangeSpecification{
|
||||||
Name: name,
|
Name: name,
|
||||||
IsAutoDelete: false,
|
IsAutoDelete: false,
|
||||||
})
|
})
|
||||||
msg = amqp.NewMessage([]byte("hello"))
|
msg = NewMessage([]byte("hello"))
|
||||||
Expect(MessageToAddressHelper(msg, &ExchangeAddress{Exchange: name})).To(BeNil())
|
Expect(MessagePropertyToAddress(msg, &ExchangeAddress{Exchange: name})).To(BeNil())
|
||||||
// the status should be StateReleased since the exchange does not have any binding
|
// the status should be StateReleased since the exchange does not have any binding
|
||||||
publishResult, err = publisher.Publish(context.Background(), msg)
|
publishResult, err = publisher.Publish(context.Background(), msg)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
Expect(publishResult).NotTo(BeNil())
|
Expect(publishResult).NotTo(BeNil())
|
||||||
Expect(publishResult.Outcome).To(Equal(&amqp.StateReleased{}))
|
Expect(publishResult.Outcome).To(Equal(&StateReleased{}))
|
||||||
|
|
||||||
// Create the binding between the exchange and the queue
|
// Create the binding between the exchange and the queue
|
||||||
_, err = connection.Management().Bind(context.Background(), &ExchangeToQueueBindingSpecification{
|
_, err = connection.Management().Bind(context.Background(), &ExchangeToQueueBindingSpecification{
|
||||||
|
|
@ -162,12 +162,12 @@ var _ = Describe("AMQP publisher ", func() {
|
||||||
})
|
})
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
// the status should be StateAccepted since the exchange has a binding
|
// the status should be StateAccepted since the exchange has a binding
|
||||||
msg = amqp.NewMessage([]byte("hello"))
|
msg = NewMessage([]byte("hello"))
|
||||||
Expect(MessageToAddressHelper(msg, &ExchangeAddress{Exchange: name})).To(BeNil())
|
Expect(MessagePropertyToAddress(msg, &ExchangeAddress{Exchange: name})).To(BeNil())
|
||||||
publishResult, err = publisher.Publish(context.Background(), msg)
|
publishResult, err = publisher.Publish(context.Background(), msg)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
Expect(publishResult).NotTo(BeNil())
|
Expect(publishResult).NotTo(BeNil())
|
||||||
Expect(publishResult.Outcome).To(Equal(&amqp.StateAccepted{}))
|
Expect(publishResult.Outcome).To(Equal(&StateAccepted{}))
|
||||||
Expect(connection.Management().DeleteQueue(context.Background(), name)).To(BeNil())
|
Expect(connection.Management().DeleteQueue(context.Background(), name)).To(BeNil())
|
||||||
Expect(connection.Management().DeleteExchange(context.Background(), name)).To(BeNil())
|
Expect(connection.Management().DeleteExchange(context.Background(), name)).To(BeNil())
|
||||||
Expect(connection.Close(context.Background())).To(BeNil())
|
Expect(connection.Close(context.Background())).To(BeNil())
|
||||||
|
|
@ -180,7 +180,7 @@ var _ = Describe("AMQP publisher ", func() {
|
||||||
publisher, err := connection.NewPublisher(context.Background(), nil, "test")
|
publisher, err := connection.NewPublisher(context.Background(), nil, "test")
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
Expect(publisher).NotTo(BeNil())
|
Expect(publisher).NotTo(BeNil())
|
||||||
msg := amqp.NewMessage([]byte("hello"))
|
msg := NewMessage([]byte("hello"))
|
||||||
// the message should fail since the TO property is not set
|
// the message should fail since the TO property is not set
|
||||||
publishResult, err := publisher.Publish(context.Background(), msg)
|
publishResult, err := publisher.Publish(context.Background(), msg)
|
||||||
Expect(err).NotTo(BeNil())
|
Expect(err).NotTo(BeNil())
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package rabbitmq_amqp
|
package rabbitmqamqp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
@ -1,12 +1,10 @@
|
||||||
package rabbitmq_amqp
|
package rabbitmqamqp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/Azure/go-amqp"
|
|
||||||
. "github.com/onsi/ginkgo/v2"
|
. "github.com/onsi/ginkgo/v2"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = Describe("AMQP Queue test ", func() {
|
var _ = Describe("AMQP Queue test ", func() {
|
||||||
|
|
@ -230,10 +228,10 @@ func publishMessages(queueName string, count int, args ...string) {
|
||||||
body = args[0]
|
body = args[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
publishResult, err := publisher.Publish(context.TODO(), amqp.NewMessage([]byte(body)))
|
publishResult, err := publisher.Publish(context.TODO(), NewMessage([]byte(body)))
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
Expect(publishResult).NotTo(BeNil())
|
Expect(publishResult).NotTo(BeNil())
|
||||||
Expect(publishResult.Outcome).To(Equal(&amqp.StateAccepted{}))
|
Expect(publishResult.Outcome).To(Equal(&StateAccepted{}))
|
||||||
}
|
}
|
||||||
err = conn.Close(context.TODO())
|
err = conn.Close(context.TODO())
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
|
|
@ -1,10 +1,18 @@
|
||||||
package rabbitmq_amqp
|
package rabbitmqamqp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/Azure/go-amqp"
|
"github.com/Azure/go-amqp"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// the following types are alias to the go-amqp package
|
||||||
|
|
||||||
|
type DeliveryState = amqp.DeliveryState
|
||||||
|
type StateAccepted = amqp.StateAccepted
|
||||||
|
type StateRejected = amqp.StateRejected
|
||||||
|
type StateReleased = amqp.StateReleased
|
||||||
|
type StateModified = amqp.StateModified
|
||||||
|
|
||||||
type linkerName interface {
|
type linkerName interface {
|
||||||
linkName() string
|
linkName() string
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package rabbitmq_amqp
|
package rabbitmqamqp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package rabbitmq_amqp
|
package rabbitmqamqp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package rabbitmq_amqp
|
package rabbitmqamqp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package rabbitmq_amqp
|
package rabbitmqamqp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package rabbitmq_amqp
|
package rabbitmqamqp
|
||||||
|
|
||||||
type entityIdentifier interface {
|
type entityIdentifier interface {
|
||||||
Id() string
|
Id() string
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package rabbitmq_amqp
|
package rabbitmqamqp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package rabbitmq_amqp
|
package rabbitmqamqp
|
||||||
|
|
||||||
import "log/slog"
|
import "log/slog"
|
||||||
|
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
package rabbitmqamqp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"github.com/Azure/go-amqp"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MessagePropertyToAddress sets the To property of the message to the address of the target.
|
||||||
|
// The target must be a QueueAddress or an ExchangeAddress.
|
||||||
|
// Note: The field msgRef.Properties.To will be overwritten if it is already set.
|
||||||
|
func MessagePropertyToAddress(msgRef *amqp.Message, target TargetAddress) error {
|
||||||
|
if target == nil {
|
||||||
|
return errors.New("target cannot be nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
address, err := target.toAddress()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if msgRef.Properties == nil {
|
||||||
|
msgRef.Properties = &amqp.MessageProperties{}
|
||||||
|
}
|
||||||
|
msgRef.Properties.To = &address
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMessage creates a new AMQP 1.0 message with the given payload.
|
||||||
|
func NewMessage(body []byte) *amqp.Message {
|
||||||
|
return amqp.NewMessage(body)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMessageWithAddress creates a new AMQP 1.0 new message with the given payload and sets the To property to the address of the target.
|
||||||
|
// The target must be a QueueAddress or an ExchangeAddress.
|
||||||
|
// This function is a helper that combines NewMessage and MessagePropertyToAddress.
|
||||||
|
func NewMessageWithAddress(body []byte, target TargetAddress) (*amqp.Message, error) {
|
||||||
|
message := amqp.NewMessage(body)
|
||||||
|
err := MessagePropertyToAddress(message, target)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return message, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMessageWithFilter creates a new AMQP 1.0 message with the given payload and sets the
|
||||||
|
// StreamFilterValue property to the filter value.
|
||||||
|
func NewMessageWithFilter(body []byte, filter string) *amqp.Message {
|
||||||
|
msg := amqp.NewMessage(body)
|
||||||
|
msg.Annotations = amqp.Annotations{
|
||||||
|
// here we set the filter value taken from the filters array
|
||||||
|
StreamFilterValue: filter,
|
||||||
|
}
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package rabbitmq_amqp_test
|
package rabbitmqamqp_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package rabbitmq_amqp
|
package rabbitmqamqp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package rabbitmq_amqp
|
package rabbitmqamqp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package rabbitmq_amqp
|
package rabbitmqamqp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
. "github.com/onsi/ginkgo/v2"
|
. "github.com/onsi/ginkgo/v2"
|
||||||
Loading…
Reference in New Issue