Basic impl added
This commit is contained in:
+320
@@ -0,0 +1,320 @@
|
||||
# Notifier Microservice Architecture
|
||||
|
||||
## Overview
|
||||
|
||||
The Notifier microservice is designed to provide a flexible, scalable notification delivery system that supports multiple notification channels (SMTP, Slack, Ntfy, Stdout) with both REST and gRPC APIs.
|
||||
|
||||
## Architecture Principles
|
||||
|
||||
- **Clean Architecture**: Domain-driven design with clear separation of concerns
|
||||
- **Interface-based Design**: All core components use interfaces for maximum flexibility
|
||||
- **Pluggable Notifiers**: Easy to add new notification providers
|
||||
- **Queue Abstraction**: Supports both local and distributed queues (Kafka)
|
||||
- **Configuration-driven**: Viper-based configuration with environment variable support
|
||||
- **Cloud-native**: Containerized with Kubernetes support
|
||||
|
||||
## Core Components
|
||||
|
||||
### 1. Domain Layer (`internal/domain/`)
|
||||
|
||||
The domain layer defines the core business logic and interfaces:
|
||||
|
||||
#### `notification.go`
|
||||
- **Notification**: Core notification entity with metadata, status tracking, and retry logic
|
||||
- **Priority**: Enumeration for notification urgency (Low, Normal, High, Critical)
|
||||
- **NotificationType**: Supported notification channels (Email, Slack, Ntfy, Stdout)
|
||||
- **NotificationStatus**: Lifecycle states (Pending, Queued, Processing, Sent, Failed, Retrying)
|
||||
- **NotificationResult**: Outcome of notification delivery attempts
|
||||
- **NotificationFilter**: Query interface for retrieving notifications
|
||||
|
||||
#### `notifier.go`
|
||||
- **Notifier**: Core interface that all notification implementations must satisfy
|
||||
- **NotifierFactory**: Factory pattern for creating notifier instances
|
||||
- **NotificationService**: High-level service interface for notification operations
|
||||
- **NotificationStats**: Statistics and metrics about notification processing
|
||||
|
||||
#### `queue.go`
|
||||
- **Queue**: Interface for notification queue implementations
|
||||
- **QueueMessage**: Wrapper around notifications with queue-specific metadata
|
||||
- **QueueConfig**: Configuration for queue implementations
|
||||
- **LocalQueueConfig**: In-memory queue configuration
|
||||
- **KafkaQueueConfig**: Distributed Kafka queue configuration
|
||||
|
||||
### 2. Queue Implementation (`internal/queue/`)
|
||||
|
||||
#### `local.go`
|
||||
- In-memory queue implementation using Go channels
|
||||
- Optional disk persistence for durability
|
||||
- Thread-safe with mutex protection
|
||||
- Supports enqueue, dequeue, ack, and nack operations
|
||||
- Configurable buffer size and retry behavior
|
||||
|
||||
### 3. Notifier Implementations (`internal/notifier/`)
|
||||
|
||||
#### `notifier.go`
|
||||
- **Factory**: Manages and creates notifier instances
|
||||
- **BaseNotifier**: Common functionality shared by all notifiers
|
||||
- Validation and context checking utilities
|
||||
|
||||
#### `stdout.go`
|
||||
- Simple stdout notifier for debugging and development
|
||||
- Prints notifications to console with formatted output
|
||||
|
||||
#### `smtp.go`
|
||||
- Email notifications via SMTP
|
||||
- Supports TLS/SSL
|
||||
- Configurable SMTP server, port, and authentication
|
||||
- RFC-compliant email message formatting
|
||||
|
||||
#### `ntfy.go`
|
||||
- Integration with ntfy.sh push notification service
|
||||
- Supports custom ntfy servers
|
||||
- Priority mapping and metadata support
|
||||
- Rich notification features (tags, click actions, attachments)
|
||||
|
||||
#### `slack.go`
|
||||
- Slack webhook integration
|
||||
- Channel-specific webhook support
|
||||
- Rich message formatting with blocks
|
||||
- Priority indicators and custom branding
|
||||
|
||||
### 4. Configuration (`internal/config/`)
|
||||
|
||||
#### `config.go`
|
||||
- Viper-based configuration management
|
||||
- Support for YAML config files and environment variables
|
||||
- Default value handling
|
||||
- Comprehensive validation
|
||||
- Hierarchical configuration structure:
|
||||
- Server settings (ports, host, mode)
|
||||
- Queue configuration
|
||||
- Notifier credentials
|
||||
- Logging settings
|
||||
- Metrics and observability
|
||||
- Health check configuration
|
||||
|
||||
### 5. API Layer
|
||||
|
||||
#### gRPC API (`api/grpc/`)
|
||||
|
||||
**`notifier.proto`**
|
||||
- Protocol buffer definitions for the gRPC service
|
||||
- Operations:
|
||||
- `SendNotification`: Send single notification
|
||||
- `SendBatchNotifications`: Send multiple notifications
|
||||
- `GetNotification`: Retrieve notification by ID
|
||||
- `ListNotifications`: Query notifications with filters
|
||||
- `CancelNotification`: Cancel pending notification
|
||||
- `RetryNotification`: Retry failed notification
|
||||
- `GetStats`: Retrieve service statistics
|
||||
- `HealthCheck`: Service health verification
|
||||
|
||||
#### REST API (`api/rest/`)
|
||||
|
||||
**`handlers.go`**
|
||||
- HTTP handlers for REST endpoints
|
||||
- Request validation and error handling
|
||||
- JSON serialization/deserialization
|
||||
|
||||
**`router.go`**
|
||||
- Gorilla mux router configuration
|
||||
- Middleware for logging and CORS
|
||||
- Route definitions matching gRPC operations
|
||||
|
||||
**`types.go`**
|
||||
- REST API request/response types
|
||||
- Domain model conversions
|
||||
- Validation logic
|
||||
|
||||
### 6. Entry Points (`cmd/`)
|
||||
|
||||
#### `grpcserver/main.go`
|
||||
- Standalone gRPC server
|
||||
- Service initialization and dependency injection
|
||||
- Graceful shutdown handling
|
||||
|
||||
#### `restserver/main.go`
|
||||
- Standalone REST server
|
||||
- HTTP server configuration
|
||||
- Graceful shutdown handling
|
||||
|
||||
## Data Flow
|
||||
|
||||
### Sending a Notification
|
||||
|
||||
```
|
||||
Client Request (REST/gRPC)
|
||||
↓
|
||||
API Handler
|
||||
↓
|
||||
NotificationService.Send()
|
||||
↓
|
||||
Queue.Enqueue()
|
||||
↓
|
||||
[Notification queued]
|
||||
↓
|
||||
Worker dequeues (Queue.Dequeue())
|
||||
↓
|
||||
NotifierFactory.Create()
|
||||
↓
|
||||
Notifier.Send()
|
||||
↓
|
||||
Provider API (SMTP/Slack/Ntfy/Stdout)
|
||||
↓
|
||||
Queue.Ack() or Queue.Nack()
|
||||
↓
|
||||
Update notification status
|
||||
↓
|
||||
[Notification sent or failed]
|
||||
```
|
||||
|
||||
## Queue Strategies
|
||||
|
||||
### Local Queue
|
||||
- In-memory implementation using Go channels
|
||||
- Fast and simple for single-instance deployments
|
||||
- Optional disk persistence for durability
|
||||
- Suitable for development and small-scale production
|
||||
|
||||
### Kafka Queue (Future)
|
||||
- Distributed queue for multi-instance deployments
|
||||
- Guarantees delivery across service restarts
|
||||
- Horizontal scalability
|
||||
- Exactly-once semantics with idempotence
|
||||
- Suitable for high-throughput production environments
|
||||
|
||||
## Notification Lifecycle
|
||||
|
||||
1. **Pending**: Notification created but not yet queued
|
||||
2. **Queued**: Added to queue, waiting for processing
|
||||
3. **Processing**: Worker has dequeued and is sending
|
||||
4. **Sent**: Successfully delivered to provider
|
||||
5. **Failed**: Delivery failed after max retries
|
||||
6. **Retrying**: Temporarily failed, will retry
|
||||
|
||||
## Retry Strategy
|
||||
|
||||
- Configurable max retries (default: 3)
|
||||
- Pluggable backoff strategies:
|
||||
- **Exponential**: 2^n delay between retries
|
||||
- **Linear**: Fixed increment between retries
|
||||
- **Fixed**: Constant delay between retries
|
||||
|
||||
## Configuration Management
|
||||
|
||||
### Hierarchy (highest to lowest priority)
|
||||
1. Environment variables (prefixed with `NOTIFIER_`)
|
||||
2. Configuration file (config.yaml)
|
||||
3. Default values
|
||||
|
||||
### Example Environment Variables
|
||||
```bash
|
||||
NOTIFIER_SERVER_GRPC_PORT=50051
|
||||
NOTIFIER_SERVER_REST_PORT=8080
|
||||
NOTIFIER_QUEUE_TYPE=local
|
||||
NOTIFIER_NOTIFIERS_SMTP_HOST=smtp.gmail.com
|
||||
NOTIFIER_NOTIFIERS_SLACK_WEBHOOK_URL=https://hooks.slack.com/...
|
||||
```
|
||||
|
||||
## Deployment Strategies
|
||||
|
||||
### Docker Compose
|
||||
- Single-host deployment
|
||||
- All components in one compose file
|
||||
- Optional Kafka, Prometheus, and Grafana services
|
||||
- Volume mounts for configuration and persistence
|
||||
|
||||
### Kubernetes
|
||||
- Multi-instance deployment with HPA
|
||||
- Separate services for REST and gRPC
|
||||
- ConfigMaps for configuration
|
||||
- Secrets for credentials
|
||||
- Ingress for external access
|
||||
- Health checks and readiness probes
|
||||
- Resource limits and requests
|
||||
|
||||
### Scaling Considerations
|
||||
|
||||
#### Horizontal Scaling
|
||||
- Multiple instances can run concurrently
|
||||
- Use Kafka queue for distributed message processing
|
||||
- Stateless design allows easy scaling
|
||||
|
||||
#### Vertical Scaling
|
||||
- Increase worker count per instance
|
||||
- Tune queue buffer sizes
|
||||
- Adjust resource limits
|
||||
|
||||
## Observability
|
||||
|
||||
### Metrics (Prometheus)
|
||||
- Total notifications sent/failed
|
||||
- Notifications by type and status
|
||||
- Average latency
|
||||
- Queue size
|
||||
- Worker utilization
|
||||
|
||||
### Health Checks
|
||||
- Dedicated health endpoint
|
||||
- Component-level health reporting
|
||||
- Kubernetes liveness/readiness probes
|
||||
|
||||
### Logging
|
||||
- Structured JSON logging
|
||||
- Configurable log levels
|
||||
- Request/response logging
|
||||
- Error tracking
|
||||
|
||||
## Security
|
||||
|
||||
### Authentication
|
||||
- API keys for REST endpoints (to be implemented)
|
||||
- mTLS for gRPC (to be implemented)
|
||||
- Kubernetes RBAC for service account
|
||||
|
||||
### Authorization
|
||||
- Per-notifier credential management
|
||||
- Secrets stored in Kubernetes Secrets or external secret manager
|
||||
- No credentials in configuration files
|
||||
|
||||
### Network Security
|
||||
- Non-root container user
|
||||
- Read-only root filesystem where possible
|
||||
- Minimal container image (Alpine-based)
|
||||
- Security context restrictions
|
||||
|
||||
## Extension Points
|
||||
|
||||
### Adding a New Notifier
|
||||
|
||||
1. Create new file in `internal/notifier/`
|
||||
2. Implement the `domain.Notifier` interface:
|
||||
- `Send(ctx, notification) -> result`
|
||||
- `Type() -> NotificationType`
|
||||
- `Validate(notification) -> error`
|
||||
- `Close() -> error`
|
||||
3. Add configuration struct to `internal/config/`
|
||||
4. Register in factory during initialization
|
||||
5. Update protobuf and REST API types
|
||||
6. Add configuration example to `config.yaml`
|
||||
|
||||
### Adding a New Queue Implementation
|
||||
|
||||
1. Create new file in `internal/queue/`
|
||||
2. Implement the `domain.Queue` interface
|
||||
3. Add configuration to `domain.QueueConfig`
|
||||
4. Update queue factory/initialization logic
|
||||
5. Add configuration example
|
||||
|
||||
## Next Steps for Implementation
|
||||
|
||||
1. **Generate Protocol Buffers**: Run `make proto-gen` to generate gRPC code
|
||||
2. **Implement Service Layer**: Create the main service that ties everything together
|
||||
3. **Implement Server Main Functions**: Wire up dependencies in `cmd/`
|
||||
4. **Add Tests**: Unit tests for notifiers, integration tests for queue
|
||||
5. **Add Kafka Queue**: Implement distributed queue using Kafka
|
||||
6. **Add Metrics**: Prometheus instrumentation
|
||||
7. **Add Authentication**: API key or OAuth support
|
||||
8. **Add Rate Limiting**: Prevent abuse and manage provider quotas
|
||||
9. **Add Notification Templates**: Support for templated messages
|
||||
10. **Add Webhooks**: Allow callbacks on notification status changes
|
||||
Reference in New Issue
Block a user