npm package: @pesalink/queue-publisher-package
Description: Shared queue publisher package that allows microservices to publish to RabbitMQ queues
Author: Nicholas Kute
Latest version: 1.3.3

# RabbitMQ Publisher

A robust Node.js library for publishing messages to RabbitMQ queues with built-in retry logic, dead letter queue (DLQ) support, and automatic connection management.

## Features

- **Automatic Retry Logic**: Exponential backoff retry mechanism for failed publish attempts
- **Dead Letter Queue Support**: Automatic DLQ setup for failed message handling
- **Flexible Exchange Types**: Support for direct and fanout exchanges
- **Environment Configuration**: Configurable via environment variables
- **Connection Management**: Automatic connection and channel lifecycle management
- **Quorum Queue Support**: Built-in support for RabbitMQ quorum queues

## Installation
You can install the package via npm by running the following command:

```bash
npm install @pesalink/queue-publisher-package
```

## Environment Variables

Configure your RabbitMQ connection using the following environment variables:

```bash
# RabbitMQ Connection Settings
RABBITMQ_HOST=localhost          # Default: 10.185.13.110
RABBITMQ_PORT=5672              # Default: 5672
RABBITMQ_USER=admin             # Default: admin
RABBITMQ_PASSWORD=admin123      # Default: admin123
RABBITMQ_HEARTBEAT=60           # Default: 60
RABBITMQ_VHOST=/                # Default: /
RABBITMQ_QUEUE_TYPE=quorum      # Default: quorum

# Application Environment
NODE_ENV=development            # For logging purposes
```

## Basic Usage

```javascript
const publisher = require('@pesalink/queue-publisher-package');
// Simple message publishing
await publisher.publishToQueue('my-queue', { 
  userId: 123, 
  action: 'user_created' 
});
```

## Advanced Usage

### Custom Retry Configuration

```javascript
await publisher.publishToQueue(
  'my-queue',
  { message: 'Hello World' },
  5,        // retries (default: 4)
  2000      // base delay in ms (default: 1000)
);
```

### Custom Exchange and Routing

```javascript
// Direct exchange (default)
await publisher.publishToQueue(
  'user-events',
  { userId: 123, event: 'login' },
  4,                    // retries
  1000,                 // base delay
  'user.login',         // routing key
  'user-exchange',      // exchange name
  'direct'              // exchange type
);

// Fanout exchange
await publisher.publishToQueue(
  'broadcast-queue',
  { announcement: 'System maintenance' },
  4,
  1000,
  '',                   // routing key (ignored for fanout)
  'broadcast-exchange',
  'fanout'
);
```

## API Reference

### `publishToQueue(queueName, data, retries?, baseDelay?, routingKey?, exchange?, exchangeType?)`

Publishes a message to a specified RabbitMQ queue with retry logic and DLQ support.

#### Parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `queueName` | string | - | **Required**. Name of the target queue |
| `data` | object | - | **Required**. Message payload (will be JSON stringified) |
| `retries` | number | 4 | Maximum number of retry attempts |
| `baseDelay` | number | 1000 | Base delay in milliseconds for exponential backoff |
| `routingKey` | string | queueName | Routing key for message delivery |
| `exchange` | string | "dlx" | Exchange name to publish to |
| `exchangeType` | string | "direct" | Exchange type ("direct" or "fanout") |

#### Returns

`Promise<void>` - Resolves when message is successfully published or max retries exceeded.

## Dead Letter Queue (DLQ) Configuration

The publisher automatically creates and configures dead letter queues for each main queue:

- **DLX Name**: `{queueName}-dlx`
- **DLQ Name**: `{queueName}-dlq`
- **DLX Routing Key**: `{queueName}-dlrk`

Example for queue named "user-events":
- Main queue: `user-events`
- Dead letter exchange: `user-events-dlx`
- Dead letter queue: `user-events-dlq`
- Dead letter routing key: `user-events-dlrk`

## Error Handling

### Retry Mechanism

The publisher implements exponential backoff retry logic:

1. **First attempt**: Immediate
2. **Retry 1**: Wait 1 second (baseDelay * 2^0)
3. **Retry 2**: Wait 2 seconds (baseDelay * 2^1)
4. **Retry 3**: Wait 4 seconds (baseDelay * 2^2)
5. **Retry 4**: Wait 8 seconds (baseDelay * 2^3)

### Connection Errors

- Connection errors are automatically logged
- Failed connections trigger retry logic
- Max retries prevent infinite retry loops

## Queue Configuration

All queues are created with the following default settings:

```javascript
{
  durable: true,                              // Survive broker restarts
  arguments: {
    "x-queue-type": "quorum",                 // Use quorum queues
    "x-dead-letter-exchange": "{queue}-dlx",  // DLQ setup
    "x-dead-letter-routing-key": "{queue}-dlrk"
  }
}
```

## Examples

### E-commerce Order Processing

```javascript
const publisher = require('@pesalink/queue-publisher-package');

// Publish order created event
await publisher.publishToQueue('orders', {
  orderId: 'ORD-123',
  customerId: 'CUST-456',
  items: [{ productId: 'PROD-789', quantity: 2 }],
  total: 29.99,
  timestamp: new Date().toISOString()
});

// Publish to specific exchange
await publisher.publishToQueue(
  'order-notifications',
  { orderId: 'ORD-123', status: 'confirmed' },
  3,                      // 3 retries
  1500,                   // 1.5 second base delay
  'order.confirmed',      // routing key
  'notifications',        // exchange
  'direct'               // exchange type
);
```

### User Activity Tracking

```javascript
// Track user login
await publisher.publishToQueue('user-activity', {
  userId: 12345,
  action: 'login',
  timestamp: Date.now(),
  ipAddress: '192.168.1.1',
  userAgent: 'Mozilla/5.0...'
});

// Broadcast system announcement
await publisher.publishToQueue(
  'announcements',
  { 
    message: 'Scheduled maintenance tonight at 2 AM',
    priority: 'high',
    timestamp: Date.now()
  },
  2,                    // fewer retries for broadcasts
  500,                  // faster retry
  '',                   // no routing key needed
  'system-broadcast',   // fanout exchange
  'fanout'
);
```

## Development Notes

- Replace `console.log` statements with proper logging package
- Consider adding Slack notifications for max retry failures
- Monitor DLQ for failed messages requiring manual intervention