https://github.com/rahul-ghadge/order-management-microservices
Production-ready Order Management System built with Spring Boot 3, Apache Kafka, Redis & PostgreSQL. Features event-driven microservices, stateless JWT auth, RBAC, per-service databases, Prometheus/Grafana observability, and full Docker Compose setup. One command to run everything.
https://github.com/rahul-ghadge/order-management-microservices
ddd docker event-driven java21 jwt kafka microservices open-api postgresql prafana prometheus redis spring-boot spring-cloud-gateway
Last synced: 25 days ago
JSON representation
Production-ready Order Management System built with Spring Boot 3, Apache Kafka, Redis & PostgreSQL. Features event-driven microservices, stateless JWT auth, RBAC, per-service databases, Prometheus/Grafana observability, and full Docker Compose setup. One command to run everything.
- Host: GitHub
- URL: https://github.com/rahul-ghadge/order-management-microservices
- Owner: rahul-ghadge
- Created: 2026-04-30T06:37:07.000Z (2 months ago)
- Default Branch: main
- Last Pushed: 2026-05-29T18:38:27.000Z (about 1 month ago)
- Last Synced: 2026-05-29T20:15:04.610Z (about 1 month ago)
- Topics: ddd, docker, event-driven, java21, jwt, kafka, microservices, open-api, postgresql, prafana, prometheus, redis, spring-boot, spring-cloud-gateway
- Language: Java
- Homepage:
- Size: 147 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# ποΈ Spring Boot Order Management System β Microservices Architecture
> Demonstrating production-ready microservices
> with event-driven communication, distributed security, observability, and containerization.
> ### This is high level Architectural documentation.
> ### To deep dive into more technical stuff for these micro-services, [Detailed technical guide](https://github.com/rahul-ghadge/order-management-microservices/blob/main/DETAILED_TECHNICAL_GUIDE.md) is also present
---
## π Architecture Overview
```
ββββββββββββββββββββββββββββββββββββββββββββ
β CLIENT (Browser / Mobile) β
βββββββββββββββββββββ¬βββββββββββββββββββββββ
β HTTPS
βββββββββββββββββββββΌβββββββββββββββββββββββ
β API GATEWAY :8080 β
β JWT validation Β· Rate limiting Β· CORS β
β Spring Cloud Gateway + Redis β
ββββββββ¬βββββββββββ¬βββββββββββ¬βββββββββββ¬βββ
β β β β
βββββββββββββΌβββ βββββββΌββββββ ββββΌβββββββ βββΌββββββββββββββ
β user-service β βorder-svc β βpay-svc β βnotif-svc β
β :8081 β β :8082 β β :8083 β β :8084 β
β JWT issuance β β Order β βPayment β βEmail dispatch β
β Redis cache β β Kafka pub β βKafka pubβ βKafka consumer β
ββββββββ¬ββββββββ ββββββ¬βββββββ ββββ¬βββββββ βββββββββββββββββ
β β β
ββββββββΌβββββββ βββββββΌββββββ βββββΌββββββββ
β PostgreSQL β βPostgreSQL β βPostgreSQL β
β user_db β β order_db β βpayment_db β
βββββββββββββββ βββββββ¬ββββββ βββββββββββββ
β
ββββββββββββββββββΌββββββββββββββββ
β Apache Kafka β
β order.placed β
β payment.processed β
β order.status.changed β
ββββββββββββββββββββββββββββββββββ
ββββββββββββββββ βββββββββββββββ
β Prometheus β β Grafana β
β :9090 ββββΆβ :3000 β
ββββββββββββββββ βββββββββββββββ
```
---
## β¨ Key Features
| Category | Feature |
|---|---|
| **Architecture** | Event-driven microservices, Domain-Driven Design, clean package structure |
| **Security** | Stateless JWT (access + refresh tokens), token blacklisting via Redis, RBAC (`ROLE_USER`, `ROLE_ADMIN`), Spring Security 6 |
| **Messaging** | Apache Kafka with idempotent producer, consumer retry (3Γ with back-off), DLT-ready |
| **Caching** | Redis for JWT blacklisting, user profiles (`@Cacheable`), order lookups, API Gateway rate limiting |
| **Persistence** | PostgreSQL per service (database-per-service pattern), JPA/Hibernate, UUID primary keys |
| **API** | RESTful APIs, Swagger/OpenAPI 3 on every service, standardised `ApiResponse` envelope |
| **Observability** | Micrometer + Prometheus + Grafana dashboards, Spring Boot Actuator on all services |
| **Containerisation** | Docker multi-stage builds (non-root user), Docker Compose for full local stack |
| **Testing** | Unit tests (`@MockitoExtension`), controller tests (`@WebMvcTest`), idempotency guards |
| **Code Quality** | Lombok, MapStruct, `@Builder`, interface+impl pattern, constants classes, `@Transactional` |
---
## π¦ Module Structure
```
order-management-microservices/
β
βββ common-lib/ # Shared library (NOT a Spring Boot app)
β βββ src/main/java/com/orderms/common/
β βββ dto/ApiResponse.java # Generic response envelope
β βββ event/BaseEvent.java # Kafka event base class
β βββ event/OrderPlacedEvent.java # order-service β payment-service
β βββ event/PaymentProcessedEvent.java # payment-service β order + notification
β βββ event/OrderStatusChangedEvent.java # order-service β notification-service
β βββ exception/BaseException.java
β βββ util/KafkaTopics.java # Topic + group ID constants
β
βββ api-gateway/ :8080 # Spring Cloud Gateway β JWT validation at edge
βββ user-service/ :8081 # Auth, JWT, user CRUD, Redis blacklist
βββ order-service/ :8082 # Order lifecycle, Kafka producer + consumer
βββ payment-service/:8083 # Payment processing, Kafka consumer + producer
βββ notification-service/:8084 # Email dispatch, Kafka consumer
β
βββ infra/
β βββ prometheus/prometheus.yml # Scrape config for all 5 services
β βββ grafana/provisioning/ # Auto-provisioned Prometheus datasource
β
βββ scripts/
β βββ init-databases.sql # Creates all 4 PostgreSQL databases
β βββ start-dev.sh # One-command dev stack launcher
β
βββ docker-compose.yml # Full stack: 5 services + 4 DBs + Kafka + Redis + monitoring
βββ Dockerfile # Multi-stage build template
βββ pom.xml # Maven multi-module parent POM
βββ README.md
```
---
## β‘ Kafka Event Flow
```
User places order
β
βΌ
order-service ββ[order.placed]βββββββββββββββββββΆ payment-service
β
β Simulates payment (85% success)
β
ββββββββββββββββΌβββββββββββββββββββ
β [payment.processed] β
ββββββββββββ¬βββββββββββββββββββββββ
β
ββββββββββββββββββββββββΌβββββββββββββββββββββββββ
β β β
βΌ βΌ βΌ
order-service order-service notification-service
(Updates status: [order.status.changed] (Sends payment
PAID or FAILED) β success/failure
β β email)
β βΌ
β notification-service
ββββββββββΆ (Sends order status
update email)
```
---
## π Security Architecture
### JWT Token Flow
```
1. POST /api/v1/auth/register OR POST /api/v1/auth/login
β
ββββΆ user-service validates credentials
β
ββββΆ Issues: access_token (15 min) + refresh_token (7 days)
2. Every protected request:
Client sends: Authorization: Bearer
β
ββββΆ API Gateway validates JWT at edge
β
ββββΆ Forwards X-User-Id + X-User-Role headers to downstream
3. POST /api/v1/auth/logout
β
ββββΆ JTI (JWT ID) stored in Redis with TTL = remaining token lifetime
ββββΆ Subsequent requests with this token are rejected (blacklisted)
4. POST /api/v1/auth/refresh
β
ββββΆ Valid refresh token β new access token (refresh token reused)
```
### RBAC
| Role | Permissions |
|---|---|
| `ROLE_USER` | Place orders, view own orders/payments, manage own profile |
| `ROLE_ADMIN` | All of the above + list all users, all orders, all payments |
| `ROLE_MANAGER` | Intermediate access (extensible) |
---
## π Quick Start
### Prerequisites
| Tool | Minimum Version |
|---|---|
| Java | 21 |
| Maven | 3.9 |
| Docker + Docker Compose | 24 |
## π One-command startup π- just run one command and all sevices will be up and running (can be verified on Docker Desktop)
```bash
git clone https://github.com/rahul-ghadge/order-management-microservices.git
cd order-management-microservices
chmod +x scripts/start-dev.sh
./scripts/start-dev.sh
```
### Manual startup
```bash
# 1. Build
mvn clean install -DskipTests
# 2. Start infrastructure
docker-compose up -d postgres-user postgres-order postgres-payment postgres-notification \
redis zookeeper kafka kafka-ui
# 3. Wait for infra, then start services
sleep 20
docker-compose up -d user-service order-service payment-service notification-service api-gateway
# 4. Start monitoring
docker-compose up -d prometheus grafana
```
---
## π Service URLs
| Service | URL | Description |
|---|---|---|
| API Gateway | http://localhost:8080 | Single entry point |
| User Service | http://localhost:8081/swagger-ui.html | Auth + user management |
| Order Service | http://localhost:8082/swagger-ui.html | Order lifecycle |
| Payment Service | http://localhost:8083/swagger-ui.html | Payment records |
| Notification Service | http://localhost:8084/swagger-ui.html | Notification logs |
| Kafka UI | http://localhost:8090 | Topic / message browser |
| Prometheus | http://localhost:9090 | Metrics scraping |
| Grafana | http://localhost:3000 | Dashboards (admin/admin) |
---
## π API Reference
### Authentication
```bash
# Register
curl -X POST http://localhost:8080/api/v1/auth/register \
-H "Content-Type: application/json" \
-d '{
"username": "rahulghadage",
"email": "rahul@example.com",
"password": "stringP@ssw0rd",
"firstName": "Rahul",
"lastName": "ghadage"
}'
# Login
curl -X POST http://localhost:8080/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{ "usernameOrEmail": "john@example.com", "password": "Password1" }'
# Save the token
TOKEN=""
# Logout (blacklists token in Redis)
curl -X POST http://localhost:8080/api/v1/auth/logout \
-H "Authorization: Bearer $TOKEN"
```
### Place an Order
```bash
curl -X POST http://localhost:8080/api/v1/orders \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"userEmail": "rahul@example.com",
"shippingAddress": "123 Main Street, New York, NY 10001",
"currency": "USD",
"items": [
{ "productId": "PROD-001", "productName": "Laptop Pro", "quantity": 1, "unitPrice": 1299.99 },
{ "productId": "PROD-002", "productName": "USB-C Hub", "quantity": 2, "unitPrice": 49.99 }
]
}'
```
After placing the order, watch the Kafka event chain:
1. `order.placed` β payment-service processes payment (85% success rate)
2. `payment.processed` β order-service updates status; notification-service sends email
3. `order.status.changed` β notification-service sends status email
```bash
# Check order status (cached in Redis)
curl http://localhost:8080/api/v1/orders/ \
-H "Authorization: Bearer $TOKEN"
# Check payment result
curl http://localhost:8080/api/v1/payments/order/ \
-H "Authorization: Bearer $TOKEN"
# Check notification logs
curl http://localhost:8080/api/v1/notifications/order/ \
-H "Authorization: Bearer $TOKEN"
```
### Cancel an Order (only PENDING or CONFIRMED)
```bash
curl -X PATCH http://localhost:8080/api/v1/orders//cancel \
-H "Authorization: Bearer $TOKEN"
```
---
## ποΈ Database Schema
Each service owns its own PostgreSQL database (Database-per-Service pattern):
| Service | Database | Key Tables |
|---|---|---|
| user-service | `user_db` | `users` |
| order-service | `order_db` | `orders`, `order_items` |
| payment-service | `payment_db` | `payments` |
| notification-service | `notification_db` | `notification_logs` |
---
## π Observability
### Health Checks
```bash
curl http://localhost:8081/actuator/health
curl http://localhost:8082/actuator/health
curl http://localhost:8083/actuator/health
curl http://localhost:8084/actuator/health
```
### Prometheus Metrics
All services expose metrics at `/actuator/prometheus` β automatically scraped by Prometheus.
**Key metrics to monitor:**
- `http_server_requests_seconds` β request latency per endpoint
- `kafka_consumer_fetch_manager_records_consumed_total` β event throughput
- `jvm_memory_used_bytes` β heap usage per service
- `hikaricp_connections_active` β DB connection pool saturation
- `spring_cache_gets_total` β Redis cache hit/miss ratio
### Grafana
Navigate to http://localhost:3000, login with `admin/admin`.
The Prometheus datasource is auto-provisioned. Import dashboard ID **4701** (JVM Micrometer)
or **11378** (Spring Boot Statistics) from grafana.com/dashboards.
---
## π§ͺ Running Tests
```bash
# All tests
mvn test
# Specific module
mvn test -pl user-service
mvn test -pl order-service
mvn test -pl payment-service
mvn test -pl notification-service
# Test coverage report
mvn test jacoco:report
```
### Test Inventory
| Module | Tests | Coverage |
|---|---|---|
| user-service | `UserServiceImplTest` (8 tests), `AuthControllerTest` (7 tests) | Auth, CRUD, validation |
| order-service | `OrderServiceImplTest` (5 tests), `OrderControllerTest` (7 tests) | Lifecycle, RBAC, cancel guards |
| payment-service | `PaymentEventProcessorTest` (4 tests) | Idempotency, success/failure, Kafka publish |
| notification-service | `NotificationEventConsumerTest` (5 tests) | Email dispatch, failure handling, NPE guards |
---
## βοΈ Configuration Reference
### Environment Variables
| Variable | Default | Description |
|---|---|---|
| `JWT_SECRET` | (long default) | HS256 signing secret β **change in production** |
| `DB_HOST` | `localhost` | PostgreSQL host |
| `DB_USERNAME` | `postgres` | PostgreSQL username |
| `DB_PASSWORD` | `postgres` | PostgreSQL password |
| `REDIS_HOST` | `localhost` | Redis host |
| `KAFKA_BOOTSTRAP_SERVERS` | `localhost:9092` | Kafka broker address |
| `NOTIFICATION_EMAIL_ENABLED` | `false` | Set `true` to send real emails |
| `MAIL_HOST` | `smtp.gmail.com` | SMTP server host |
| `MAIL_USERNAME` | β | SMTP username |
| `MAIL_PASSWORD` | β | SMTP password |
---
## ποΈ Architecture Decisions (ADR Summary)
| Decision | Choice | Rationale |
|---|---|---|
| Inter-service communication | Kafka (async) | Decouples services; payment/notification don't block order creation |
| Synchronous API | REST/JSON | Gateway routing + Swagger; simpler than gRPC for CRUD |
| Auth token storage | Stateless JWT + Redis blacklist | Horizontal scaling without shared session; instant logout |
| Database strategy | Database-per-service (separate PostgreSQL) | Independent schema evolution; blast radius containment |
| Caching | Redis | Shared infrastructure; supports rate limiting + token blacklist + entity cache |
| Idempotency | JTI-based blacklist + orderId guard in payment | Prevents double-processing on consumer retry |
| Secret management | Environment variables | 12-Factor App compliance; Kubernetes-compatible |
---
## π License
Apache 2.0 β see [LICENSE](LICENSE).
## π§ͺ Manuaal startup

---
## π One-command startup
Run the script below (which is mentioned [here](#-one-command-startup---just-run-one-command-and-all-sevices-will-be-up-and-running-can-be-verified-on-docker-desktop)) from the command line
```bash
./scripts/start-dev.sh
```
Attached sample logs from local [here](https://github.com/rahul-ghadge/order-management-microservices/blob/main/order-management-microservices.log)

