Skip to content

Commit e24518b

Browse files
authored
fix: linter (#14)
1 parent 90f5e49 commit e24518b

File tree

19 files changed

+323
-113
lines changed

19 files changed

+323
-113
lines changed

.github/workflows/integration-testing.yaml renamed to .github/workflows/rabbitmq-integration-testing.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Integration Testing
1+
name: Integration Testing with RabbitMQ
22

33
on:
44
push:

README.md

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,12 @@ import (
3737

3838
"github.com/bxcodec/goqueue"
3939
"github.com/bxcodec/goqueue/consumer"
40-
rmqConsumer "github.com/bxcodec/goqueue/consumer/rabbitmq"
40+
"github.com/bxcodec/goqueue/interfaces"
4141
"github.com/bxcodec/goqueue/middleware"
42+
"github.com/bxcodec/goqueue/options"
43+
consumerOpts "github.com/bxcodec/goqueue/options/consumer"
44+
publisherOpts "github.com/bxcodec/goqueue/options/publisher"
4245
"github.com/bxcodec/goqueue/publisher"
43-
rmqPublisher "github.com/bxcodec/goqueue/publisher/rabbitmq"
4446
)
4547

4648
func initExchange(ch *amqp.Channel, exchangeName string) error {
@@ -62,9 +64,14 @@ func main() {
6264
panic(err)
6365
}
6466

65-
rmqPub := rmqPublisher.NewPublisher(rmqConn,
66-
publisher.WithPublisherID("publisher_id"),
67-
publisher.WithMiddlewares(
67+
rmqPub := publisher.NewPublisher(
68+
publisherOpts.PublisherPlatformRabbitMQ,
69+
publisherOpts.WithRabbitMQPublisherConfig(&publisherOpts.RabbitMQPublisherConfig{
70+
Conn: rmqConn,
71+
PublisherChannelPoolSize: 5,
72+
}),
73+
publisherOpts.WithPublisherID("publisher_id"),
74+
publisherOpts.WithMiddlewares(
6875
middleware.HelloWorldMiddlewareExecuteBeforePublisher(),
6976
middleware.HelloWorldMiddlewareExecuteAfterPublisher(),
7077
),
@@ -83,35 +90,36 @@ func main() {
8390
panic(err)
8491
}
8592
defer consumerChannel.Close()
86-
87-
rmqConsumer := rmqConsumer.NewConsumer(
88-
publisherChannel,
89-
consumerChannel,
90-
consumer.WithMiddlewares(
93+
rmqConsumer := consumer.NewConsumer(
94+
consumerOpts.ConsumerPlatformRabbitMQ,
95+
consumerOpts.WithRabbitMQConsumerConfig(&consumerOpts.RabbitMQConsumerConfig{
96+
ConsumerChannel: consumerChannel,
97+
ReQueueChannel: publisherChannel,
98+
}),
99+
consumerOpts.WithConsumerID("consumer_id"),
100+
consumerOpts.WithMiddlewares(
91101
middleware.HelloWorldMiddlewareExecuteAfterInboundMessageHandler(),
92102
middleware.HelloWorldMiddlewareExecuteBeforeInboundMessageHandler(),
93103
),
94-
consumer.WithQueueName("consumer_queue"),
95-
consumer.WithConsumerID("consumer_id"),
96-
consumer.WithBatchMessageSize(1),
97-
consumer.WithMaxRetryFailedMessage(3),
98-
consumer.WithActionsPatternSubscribed("goqueue.payments.#", "goqueue.users.#"),
99-
consumer.WithTopicName("goqueue"),
104+
consumerOpts.WithMaxRetryFailedMessage(3),
105+
consumerOpts.WithBatchMessageSize(1),
106+
consumerOpts.WithActionsPatternSubscribed("goqueue.payments.#", "goqueue.users.#"),
107+
consumerOpts.WithTopicName("goqueue"),
108+
consumerOpts.WithQueueName("consumer_queue"),
100109
)
101110

102111
queueSvc := goqueue.NewQueueService(
103-
goqueue.WithPublisher(rmqPub),
104-
goqueue.WithConsumer(rmqConsumer),
105-
goqueue.WithMessageHandler(handler()),
112+
options.WithConsumer(rmqConsumer),
113+
options.WithPublisher(rmqPub),
114+
options.WithMessageHandler(handler()),
106115
)
107-
108116
go func() {
109117
for i := 0; i < 10; i++ {
110118
data := map[string]interface{}{
111119
"message": fmt.Sprintf("Hello World %d", i),
112120
}
113121
jbyt, _ := json.Marshal(data)
114-
err := queueSvc.Publish(context.Background(), goqueue.Message{
122+
err := queueSvc.Publish(context.Background(), interfaces.Message{
115123
Data: data,
116124
Action: "goqueue.payments.create",
117125
Topic: "goqueue",
@@ -132,14 +140,15 @@ func main() {
132140
}
133141
}
134142

135-
func handler() goqueue.InboundMessageHandlerFunc {
136-
return func(ctx context.Context, m goqueue.InboundMessage) (err error) {
143+
func handler() interfaces.InboundMessageHandlerFunc {
144+
return func(ctx context.Context, m interfaces.InboundMessage) (err error) {
137145
data := m.Data
138146
jbyt, _ := json.Marshal(data)
139147
fmt.Println("Message Received: ", string(jbyt))
140148
return m.Ack(ctx)
141149
}
142150
}
151+
143152
```
144153

145154
## Contribution

consumer/service.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import (
77
consumerOpts "github.com/bxcodec/goqueue/options/consumer"
88
)
99

10+
// NewConsumer creates a new consumer based on the specified platform.
11+
// It accepts a platform option and additional consumer option functions.
12+
// It returns a consumer.Consumer interface implementation.
1013
func NewConsumer(platform options.Platform, opts ...consumerOpts.ConsumerOptionFunc) consumer.Consumer {
1114
switch platform {
1215
case consumerOpts.ConsumerPlatformRabbitMQ:

encoding.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,7 @@ var (
7272
}
7373
DefaultEncoding = JSONEncoding
7474
)
75+
76+
func init() {
77+
AddGoQueueEncoding(JSONEncoding.ContentType, JSONEncoding)
78+
}

errors/error.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
package errors
22

33
const (
4-
InvalidMessageFormatCode = "INVALID_MESSAGE_FORMAT"
4+
InvalidMessageFormatCode = "INVALID_MESSAGE_FORMAT"
5+
EncodingFormatNotSupported = "ENCODING_FORMAT_NOT_SUPPORTED"
6+
UnKnownError = "UNKNOWN_ERROR"
57
)
68

9+
// Error represents an error with a code and a message.
710
type Error struct {
811
Code string `json:"code"`
912
Message string `json:"message"`
@@ -14,7 +17,17 @@ func (e Error) Error() string {
1417
}
1518

1619
var (
20+
// ErrInvalidMessageFormat is an error that occurs when attempting to unmarshal a message with an invalid format.
1721
ErrInvalidMessageFormat = Error{
1822
Code: InvalidMessageFormatCode,
1923
Message: "failed to unmarshal the message, removing the message due to wrong message format"}
24+
// ErrEncodingFormatNotSupported is an error that indicates the encoding format is not supported.
25+
ErrEncodingFormatNotSupported = Error{
26+
Code: EncodingFormatNotSupported,
27+
Message: "encoding format not supported. Please register the encoding format before using it"}
28+
29+
// ErrUnknownError is an error that indicates an unknown error occurred.
30+
ErrUnknownError = Error{
31+
Code: UnKnownError,
32+
Message: "an unknown error occurred"}
2033
)

internal/consumer/rabbitmq/blackbox_consumer_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ func TestSuiteRabbitMQConsumer(t *testing.T) {
4343
t.Skip("Skip the Test Suite for RabbitMQ Consumer")
4444
}
4545

46+
time.Sleep(5 * time.Second) // wait for the rabbitmq to be ready
47+
4648
rmqURL := os.Getenv("RABBITMQ_TEST_URL")
4749
if rmqURL == "" {
4850
rmqURL = "amqp://test:test@localhost:5672/test"

internal/consumer/rabbitmq/consumer.go

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,11 +126,20 @@ func (r *rabbitMQ) initConsumer() {
126126
r.msgReceiver = receiver
127127
}
128128

129-
// Consume consumes messages from a RabbitMQ queue.
130-
// It takes a context, an inbound message handler, and metadata as input parameters.
131-
// The method continuously listens for messages from the queue and handles them using the provided handler.
132-
// If the context is canceled, the method stops consuming messages and returns.
133-
// The method returns an error if there was an issue consuming messages.
129+
// Consume consumes messages from a RabbitMQ queue and handles them using the provided message handler.
130+
// It takes a context, an inbound message handler, and a map of metadata as input parameters.
131+
// The function continuously listens for messages from the queue and processes them until the context is canceled.
132+
// If the context is canceled, the function stops consuming messages and returns.
133+
// For each received message, the function builds an inbound message, extracts the retry count, and checks if the maximum retry count has been reached.
134+
// If the maximum retry count has been reached, the message is moved to the dead letter queue.
135+
// Otherwise, the message is passed to the message handler for processing.
136+
// The message handler is responsible for handling the message and returning an error if any.
137+
// If an error occurs while handling the message, it is logged.
138+
// The function provides methods for acknowledging, rejecting, and moving messages to the dead letter queue.
139+
// These methods can be used by the message handler to control the message processing flow.
140+
// The function also logs information about the received message, such as the message ID, topic, action, and timestamp.
141+
// It applies any configured middlewares to the message handler before calling it.
142+
// The function returns an error if any occurred during message handling or if the context was canceled.
134143
func (r *rabbitMQ) Consume(ctx context.Context,
135144
h interfaces.InboundMessageHandler,
136145
meta map[string]interface{}) (err error) {

internal/publisher/rabbitmq/blackbox_publisher_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ func TestSuiteRabbitMQPublisher(t *testing.T) {
4040
t.Skip("Skip the Test Suite for RabbitMQ Publisher")
4141
}
4242

43+
time.Sleep(5 * time.Second) // wait for the rabbitmq to be ready
44+
4345
rmqURL := os.Getenv("RABBITMQ_TEST_URL")
4446
if rmqURL == "" {
4547
rmqURL = "amqp://test:test@localhost:5672/test"

internal/publisher/rabbitmq/channel_pool.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,18 @@ import (
88
"go.uber.org/multierr"
99
)
1010

11+
// ChannelPool represents a pool of AMQP channels used for publishing messages.
12+
// It provides a way to manage and reuse AMQP channels efficiently.
1113
type ChannelPool struct {
1214
conn *amqp.Connection
1315
mutex sync.Mutex
1416
pool chan *amqp.Channel
1517
maxSize int
1618
}
1719

20+
// NewChannelPool creates a new ChannelPool instance.
21+
// It takes an AMQP connection and the maximum size of the pool as parameters.
22+
// It returns a pointer to the newly created ChannelPool.
1823
func NewChannelPool(conn *amqp.Connection, maxSize int) *ChannelPool {
1924
return &ChannelPool{
2025
conn: conn,
@@ -23,6 +28,8 @@ func NewChannelPool(conn *amqp.Connection, maxSize int) *ChannelPool {
2328
}
2429
}
2530

31+
// Get returns a channel from the pool. If there are available channels in the pool, it returns one of them.
32+
// Otherwise, it creates a new channel from the underlying connection and returns it.
2633
func (cp *ChannelPool) Get() (*amqp.Channel, error) {
2734
cp.mutex.Lock()
2835
defer cp.mutex.Unlock()
@@ -35,6 +42,8 @@ func (cp *ChannelPool) Get() (*amqp.Channel, error) {
3542
}
3643
}
3744

45+
// Return returns a channel back to the channel pool.
46+
// If the pool is full, the channel is closed.
3847
func (cp *ChannelPool) Return(ch *amqp.Channel) {
3948
cp.mutex.Lock()
4049
defer cp.mutex.Unlock()
@@ -51,6 +60,8 @@ func (cp *ChannelPool) Return(ch *amqp.Channel) {
5160
}
5261
}
5362

63+
// Close closes the ChannelPool and all its associated channels.
64+
// It returns an error if there was an error closing any of the channels.
5465
func (cp *ChannelPool) Close() (err error) {
5566
cp.mutex.Lock()
5667
defer cp.mutex.Unlock()

internal/publisher/rabbitmq/publisher.go

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"time"
66

77
"github.com/bxcodec/goqueue"
8+
"github.com/bxcodec/goqueue/errors"
89
headerKey "github.com/bxcodec/goqueue/headers/key"
910
headerVal "github.com/bxcodec/goqueue/headers/value"
1011
"github.com/bxcodec/goqueue/interfaces"
@@ -25,6 +26,32 @@ type rabbitMQ struct {
2526
option *publisherOpts.PublisherOption
2627
}
2728

29+
// NewPublisher creates a new instance of the publisher.Publisher interface
30+
// using the provided options. It returns a publisher.Publisher implementation
31+
// that utilizes RabbitMQ as the underlying message broker.
32+
//
33+
// The function accepts a variadic parameter `opts` of type
34+
// `publisherOpts.PublisherOptionFunc`, which allows the caller to provide
35+
// custom configuration options for the publisher.
36+
//
37+
// Example usage:
38+
//
39+
// publisher := NewPublisher(
40+
// publisherOpts.PublisherPlatformRabbitMQ,
41+
// publisherOpts.WithRabbitMQPublisherConfig(&publisherOpts.RabbitMQPublisherConfig{
42+
// Conn: rmqConn,
43+
// PublisherChannelPoolSize: 5,
44+
// }),
45+
// publisherOpts.WithPublisherID("publisher_id"),
46+
// publisherOpts.WithMiddlewares(
47+
// middleware.HelloWorldMiddlewareExecuteBeforePublisher(),
48+
// middleware.HelloWorldMiddlewareExecuteAfterPublisher(),
49+
// ),
50+
//
51+
// )
52+
//
53+
// The returned publisher can be used to publish messages to the configured
54+
// RabbitMQ exchange and routing key.
2855
func NewPublisher(
2956
opts ...publisherOpts.PublisherOptionFunc,
3057
) publisher.Publisher {
@@ -47,6 +74,9 @@ func NewPublisher(
4774
}
4875
}
4976

77+
// Publish sends a message to the RabbitMQ exchange.
78+
// It applies the default content type if not specified in the message.
79+
// It also applies any registered middlewares before publishing the message.
5080
func (r *rabbitMQ) Publish(ctx context.Context, m interfaces.Message) (err error) {
5181
if m.ContentType == "" {
5282
m.ContentType = publisherOpts.DefaultContentType
@@ -94,7 +124,7 @@ func (r *rabbitMQ) buildPublisher() interfaces.PublisherFunc {
94124
m.ID = id
95125
encoder, ok := goqueue.GetGoQueueEncoding(m.ContentType)
96126
if !ok {
97-
encoder = goqueue.DefaultEncoding
127+
return errors.ErrEncodingFormatNotSupported
98128
}
99129

100130
data, err := encoder.Encode(ctx, m)

0 commit comments

Comments
 (0)