Detailed description can be found here: Building and testing message-driven microservices using Spring Cloud Stream
- Architecture Overview
- Technology Stack
- Services Description
- Message Flow
- Prerequisites
- Running the Applications
- API Endpoints
- Testing
- Configuration
- Monitoring and Management
This project demonstrates a message-driven microservices architecture using Spring Cloud Stream with RabbitMQ as the message broker. The system consists of three core business services that communicate asynchronously through message queues.
graph TB
subgraph "Client Layer"
C["Client/API Consumer"]
end
subgraph "Microservices"
OS["Order Service<br/>:8090"]
AS["Account Service<br/>:8091"]
PS["Product Service<br/>:8093"]
end
subgraph "Message Broker"
RMQ["RabbitMQ<br/>:5672"]
OIN["orders-in queue"]
OOUT["orders-out queue"]
end
subgraph "Common"
MC["messaging-common<br/>Shared DTOs"]
end
C --> OS
C --> AS
C --> PS
OS --> OIN
OIN --> AS
OIN --> PS
AS --> OOUT
PS --> OOUT
OOUT --> OS
OS -.-> MC
AS -.-> MC
PS -.-> MC
- Java: 21
- Spring Boot: 3.5.0
- Spring Cloud: 2025.0.0
- Spring Cloud Stream: Message-driven microservices framework
- RabbitMQ: Message broker for asynchronous communication
- Maven: Build and dependency management
- Docker & Docker Compose: Containerization and orchestration
- Testcontainers: Integration testing with real dependencies
- CircleCI: Continuous Integration
- SonarCloud: Code quality and security analysis
- JaCoCo: Code coverage analysis
The central orchestrator service that manages customer orders. It receives order requests via REST API and publishes order events.
Key Features:
- REST API for order management
- Order event publishing with customer-based partitioning
- Order status tracking and updates
Manages customer accounts and financial transactions. It listens for order events and processes withdrawals.
Key Features:
- Account management REST API
- Partitioned message consumption
- Account balance withdrawals
Handles product catalog and inventory. It processes order events to update availability.
Key Features:
- Product management REST API
- Partitioned message consumption
- Inventory tracking
Shared library with common DTOs and enums for consistent message contracts.
Components:
Order
– Order data modelOrderStatus
– Enumeration (NEW, PROCESSING, ACCEPTED, DONE, REJECTED)
The services communicate through two main message destinations:
- orders-in: Order Service publishes new orders
- orders-out: Account and Product Services publish processing results
Message Flow Pattern:
1. Client creates order → Order Service
2. Order Service publishes order → orders-in queue
3. Account Service processes withdrawal → orders-out queue
4. Product Service updates inventory → orders-out queue
5. Order Service receives updates → Final order status
Partitioning Strategy:
- Partitioned by
customerId
for ordered processing - Supports multiple instances per service with load balancing
- Java 21 or higher
- Maven 3.6+
- Docker & Docker Compose
- Git
git clone https://github.com/piomin/sample-message-driven-microservices.git
cd sample-message-driven-microservices
docker-compose up -d
- RabbitMQ AMQP on 5672
- Management UI on http://localhost:15672 (guest/guest)
mvn clean compile
Option A: Separate terminals
cd order-service && mvn spring-boot:run
cd account-service && mvn spring-boot:run
cd product-service && mvn spring-boot:run
Option B: Background
cd order-service && mvn spring-boot:run &
cd account-service && mvn spring-boot:run &
cd product-service && mvn spring-boot:run &
curl http://localhost:8090/actuator/health
curl http://localhost:8091/actuator/health
curl http://localhost:8093/actuator/health
SPRING_PROFILES_ACTIVE=instance1 mvn spring-boot:run -pl account-service
SPRING_PROFILES_ACTIVE=instance2 mvn spring-boot:run -pl account-service
SPRING_PROFILES_ACTIVE=instance1 mvn spring-boot:run -pl product-service
SPRING_PROFILES_ACTIVE=instance2 mvn spring-boot:run -pl product-service
Order Service (http://localhost:8090)
Method | Endpoint | Description |
---|---|---|
POST | /orders |
Create a new order |
PUT | /orders |
Update an order |
GET | /orders/{id} |
Get order by ID |
GET | /orders/customer/{customerId} |
Get orders by customer ID |
Account Service (http://localhost:8091)
Method | Endpoint | Description |
---|---|---|
POST | /accounts |
Create a new account |
PUT | /accounts |
Update an account |
PUT | /accounts/withdraw/{id}/{amount} |
Withdraw amount from account |
GET | /accounts/{id} |
Get account by ID |
GET | /accounts/customer/{customerId} |
Get accounts by customer ID |
Product Service (http://localhost:8093)
Method | Endpoint | Description |
---|---|---|
POST | /products |
Create a new product |
PUT | /products |
Update a product |
GET | /products/{id} |
Get product by ID |
GET | /products/ids |
Get products by IDs |
curl -X POST http://localhost:8091/accounts \
-H "Content-Type: application/json" \
-d '{"customerId":1,"balance":1000}'
curl -X POST http://localhost:8093/products \
-H "Content-Type: application/json" \
-d '{"name":"Sample","price":50,"count":100}'
curl -X POST http://localhost:8090/orders \
-H "Content-Type: application/json" \
-d '{"customerId":1,"productIds":[1],"price":50}'
mvn test
mvn test -pl order-service
mvn test -pl account-service
mvn test -pl product-service
OrderControllerTest
– Order Service REST endpointsOrderReceiverTest
– Account Service message handlingOrderReceiverTest
– Product Service message handling
mvn jacoco:report
Coverage reports in target/site/jacoco/index.html
per module.
Variable | Default | Description |
---|---|---|
PORT |
service-specific | Override default service port |
SPRING_PROFILES_ACTIVE |
Activate specific Spring profiles |
- Host: localhost
- Port: 5672
- Username: guest
- Password: guest
Eureka available at http://localhost:8761/eureka/ (optional)
- orders-in: Direct exchange for new orders
- orders-out: Topic exchange for processing results
- Partitioning: 2 partitions by
customerId
All services expose Actuator endpoints:
- Health:
/actuator/health
- Metrics:
/actuator/metrics
- Stream bindings:
/actuator/bindings
RabbitMQ Management UI: http://localhost:15672 (guest/guest)