A production-ready microservices architecture for modern banking operations
Features β’ Quick Start β’ Architecture β’ API Documentation β’ Monitoring
- Overview
- Features
- Architecture
- Technology Stack
- Getting Started
- Service Details
- API Documentation
- Security
- Monitoring & Observability
- Development
- Deployment
- Contributing
- License
The Enterprise Banking Management System is a full-featured, production-grade microservices application built with Spring Boot. It demonstrates modern software architecture patterns including:
- Microservices Architecture with Spring Cloud
- Event-Driven Design using Apache Kafka
- Distributed Tracing with OpenTelemetry
- Centralized Authentication with JWT
- Real-time Monitoring via Prometheus & Grafana
- Container Orchestration with Docker Compose
π Frontend: https://etb-bank.vercel.app
|
|
- Loan Management: Apply, approve, and manage loans with EMI calculation
- Notification System: Real-time email/SMS notifications for all transactions
- Service Discovery: Eureka-based dynamic service registration
- API Gateway: Centralized routing and load balancing
- Distributed Logging: Centralized log aggregation
- Database Per Service: Independent data management
graph TB
Client[π₯οΈ Client Applications<br/>Web/Mobile]
Gateway[πͺ API Gateway<br/>Port: 8080<br/>Spring Cloud Gateway]
Eureka[π‘ Eureka Server<br/>Port: 8761<br/>Service Discovery]
Auth[π Auth Service<br/>Port: 8081<br/>JWT Authentication]
User[π€ User Service<br/>Port: 8082<br/>User Management]
Account[πΌ Account Service<br/>Port: 8083<br/>Account Operations]
Transaction[π° Transaction Service<br/>Port: 8084<br/>Fund Transfers]
Notification[π’ Notification Service<br/>Port: 8085<br/>Email/SMS]
Loan[π¦ Loan Service<br/>Port: 8086<br/>Loan Processing]
Kafka[π¨ Kafka Broker<br/>Port: 9092<br/>Message Queue]
MySQL[(ποΈ MySQL Database<br/>Port: 3306<br/>Relational DB)]
Redis[(β‘ Redis Cache<br/>Port: 6379<br/>Session Store)]
Prometheus[π Prometheus<br/>Port: 9090<br/>Metrics Collection]
Grafana[π Grafana<br/>Port: 3000<br/>Visualization]
Client -->|HTTPS| Gateway
Gateway -->|Route| Auth
Gateway -->|Route| User
Gateway -->|Route| Account
Gateway -->|Route| Transaction
Gateway -->|Route| Loan
Auth -.->|Register| Eureka
User -.->|Register| Eureka
Account -.->|Register| Eureka
Transaction -.->|Register| Eureka
Notification -.->|Register| Eureka
Loan -.->|Register| Eureka
Gateway -.->|Discover| Eureka
Transaction -->|Events| Kafka
Account -->|Events| Kafka
User -->|Events| Kafka
Loan -->|Events| Kafka
Kafka -->|Consume| Notification
Auth -->|Sessions| Redis
Auth -->|Token Blacklist| Redis
User -->|Persist| MySQL
Account -->|Persist| MySQL
Transaction -->|Persist| MySQL
Loan -->|Persist| MySQL
Auth -->|Metrics| Prometheus
User -->|Metrics| Prometheus
Account -->|Metrics| Prometheus
Transaction -->|Metrics| Prometheus
Notification -->|Metrics| Prometheus
Loan -->|Metrics| Prometheus
Prometheus -->|Dashboard| Grafana
style Gateway fill:#4CAF50,stroke:#2E7D32,color:#fff
style Kafka fill:#231F20,stroke:#000,color:#fff
style Eureka fill:#2196F3,stroke:#1565C0,color:#fff
style Prometheus fill:#E6522C,stroke:#C41E00,color:#fff
style Grafana fill:#F46800,stroke:#D94600,color:#fff
style MySQL fill:#4479A1,stroke:#00546B,color:#fff
style Redis fill:#DC382D,stroke:#A41E11,color:#fff
| From Service | To Service | Protocol | Purpose |
|---|---|---|---|
| API Gateway | All Services | HTTP/REST | Request routing |
| Transaction Service | Account Service | HTTP/REST | Balance validation |
| All Services | Eureka | HTTP | Service registration |
| Auth Service | Redis | TCP | Token management |
| All Services | MySQL | TCP | Data persistence |
| Transaction/Account/User | Kafka | TCP | Event publishing |
| Notification Service | Kafka | TCP | Event consumption |
- Framework: Spring Boot 3.2.x
- Language: Java 21 (LTS)
- Build Tool: Maven 3.9.x
- Spring Cloud: 2023.0.x
- Service Discovery: Netflix Eureka
- API Gateway: Spring Cloud Gateway
- Config Server: Spring Cloud Config
- Circuit Breaker: Resilience4j
- RDBMS: MySQL 8.0
- Cache: Redis 7.x
- ORM: Spring Data JPA / Hibernate
- Message Broker: Apache Kafka 3.x
- Serialization: Apache Avro / JSON
- Authentication: JWT (RS256)
- Authorization: Spring Security
- Password Hashing: BCrypt
- Metrics: Micrometer + Prometheus
- Visualization: Grafana
- Logging: SLF4J + Logback
- Tracing: Spring Cloud Sleuth
- Containerization: Docker
- Orchestration: Docker Compose
- CI/CD: GitHub Actions
- Version Control: Git
Before you begin, ensure you have the following installed:
# Check installations
docker --version # Docker 20.x or higher
docker-compose --version # Docker Compose 2.x or higher
git --version # Git 2.x or higher
java --version # Java 21 (optional, for local dev)
mvn --version # Maven 3.9.x (optional, for local dev)# 1. Clone the repository
git clone https://github.com/Akash-Adak/Banking-system.git
cd Banking-system
# 2. Configure environment variables (optional)
cp .env.example .env
nano .env # Edit as needed
# 3. Start all services
docker-compose up -d
# 4. Verify services are running
docker-compose ps
# 5. View logs
docker-compose logs -f
# 6. Wait for services to be healthy (2-3 minutes)
# Check health: http://localhost:8761# 1. Clone and setup
git clone https://github.com/Akash-Adak/Banking-system.git
cd Banking-system
# 2. Start infrastructure services
docker-compose up -d mysql redis kafka zookeeper
# 3. Build all services
mvn clean install -DskipTests
# 4. Start Eureka Server
cd eureka-server
mvn spring-boot:run &
# 5. Start other services (in separate terminals)
cd auth-service && mvn spring-boot:run &
cd user-service && mvn spring-boot:run &
cd account-service && mvn spring-boot:run &
cd transaction-service && mvn spring-boot:run &
cd notification-service && mvn spring-boot:run &
cd loan-service && mvn spring-boot:run &| Service | URL | Credentials | Description |
|---|---|---|---|
| πͺ API Gateway | http://localhost:8080 |
- | Main entry point |
| π‘ Eureka Dashboard | http://localhost:8761 |
- | Service registry |
| π Prometheus | http://localhost:9090 |
- | Metrics |
| π Grafana | http://localhost:3000 |
admin / admin | Dashboards |
| ποΈ MySQL | localhost:3306 |
root / rootpassword | Database |
| β‘ Redis | localhost:6379 |
- | Cache |
| π¨ Kafka | localhost:9092 |
- | Message broker |
# Check all services health
curl http://localhost:8761/actuator/health
# Check specific service
curl http://localhost:8081/actuator/health # Auth Service
curl http://localhost:8082/actuator/health # User Service
curl http://localhost:8083/actuator/health # Account ServicePurpose: Centralized authentication and authorization
Key Features:
- User registration and login
- JWT token generation (RS256)
- Token validation and refresh
- Redis-based token revocation
- Role-based access control
Endpoints:
POST /api/auth/register - Register new user
POST /api/auth/login - Login and get JWT token
POST /api/auth/refresh - Refresh access token
POST /api/auth/logout - Logout and revoke token
GET /api/auth/validate - Validate JWT token
Purpose: User profile and information management
Key Features:
- User profile CRUD operations
- User search and filtering
- Profile picture management
- KYC verification status
- User preferences
Endpoints:
GET /api/users - Get all users (admin)
GET /api/users/{id} - Get user by ID
PUT /api/users/{id} - Update user profile
DELETE /api/users/{id} - Delete user (admin)
GET /api/users/me - Get current user profile
PUT /api/users/me/password - Change password
Purpose: Bank account management
Key Features:
- Create multiple account types (Savings, Current, Fixed Deposit)
- Account balance management
- Account statement generation
- Interest calculation
- Account freeze/unfreeze
Endpoints:
POST /api/accounts - Create new account
GET /api/accounts - Get all accounts for user
GET /api/accounts/{accountNumber} - Get account details
PUT /api/accounts/{accountNumber} - Update account info
DELETE /api/accounts/{accountNumber} - Close account
GET /api/accounts/{accountNumber}/balance - Get balance
GET /api/accounts/{accountNumber}/statement - Get statement
Purpose: Handle all financial transactions
Key Features:
- Fund transfers (within bank)
- Deposit and withdrawal
- Transaction history
- Transaction status tracking
- Rollback support
- Duplicate transaction prevention
Endpoints:
POST /api/transactions/transfer - Transfer funds
POST /api/transactions/deposit - Deposit money
POST /api/transactions/withdraw - Withdraw money
GET /api/transactions - Get transaction history
GET /api/transactions/{id} - Get transaction details
GET /api/transactions/account/{accountNumber} - Get account transactions
Purpose: Send notifications to users
Key Features:
- Email notifications
- SMS notifications (Twilio integration)
- Kafka event consumption
- Notification templates
- Delivery status tracking
- Retry mechanism
Kafka Topics Consumed:
user.registered - Welcome email
transaction.completed - Transaction alert
account.credit - Credit notification
account.debit - Debit notification
loan.approved - Loan approval
loan.rejected - Loan rejection
Purpose: Loan application and management
Key Features:
- Loan application submission
- Credit score verification
- Loan approval workflow
- EMI calculation
- Repayment tracking
- Loan closure
Endpoints:
POST /api/loans/apply - Apply for loan
GET /api/loans - Get all loans
GET /api/loans/{id} - Get loan details
PUT /api/loans/{id}/approve - Approve loan (admin)
PUT /api/loans/{id}/reject - Reject loan (admin)
POST /api/loans/{id}/repay - Make EMI payment
GET /api/loans/{id}/schedule - Get EMI schedule
Purpose: Service discovery and registration
Features:
- Dynamic service registration
- Health monitoring
- Load balancing support
- Failover handling
Purpose: Single entry point for all services
Features:
- Request routing
- Load balancing
- Rate limiting
- Authentication filter
- CORS handling
- Request/response logging
sequenceDiagram
participant Client
participant Gateway
participant Auth
participant Redis
Client->>Gateway: POST /api/auth/register
Gateway->>Auth: Forward request
Auth->>Auth: Validate & Hash password
Auth->>Redis: Store user session
Auth-->>Gateway: User created
Gateway-->>Client: 201 Created
Client->>Gateway: POST /api/auth/login
Gateway->>Auth: Forward credentials
Auth->>Auth: Validate credentials
Auth->>Redis: Generate & store token
Auth-->>Gateway: JWT Token
Gateway-->>Client: 200 OK + Token
Client->>Gateway: GET /api/users/me<br/>(Authorization: Bearer Token)
Gateway->>Auth: Validate token
Auth->>Redis: Check token validity
Auth-->>Gateway: Token valid
Gateway->>User: Forward request
User-->>Client: User profile data
curl -X POST http://localhost:8080/api/auth/register \
-H "Content-Type: application/json" \
-d '{
"username": "john.doe",
"email": "john@example.com",
"password": "SecurePass123!",
"firstName": "John",
"lastName": "Doe",
"phoneNumber": "+1234567890"
}'Response:
{
"id": "usr_123456",
"username": "john.doe",
"email": "john@example.com",
"firstName": "John",
"lastName": "Doe",
"createdAt": "2024-12-23T10:30:00Z"
}curl -X POST http://localhost:8080/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"username": "john.doe",
"password": "SecurePass123!"
}'Response:
{
"accessToken": "eyJhbGciOiJSUzI1NiIs...",
"refreshToken": "eyJhbGciOiJSUzI1NiIs...",
"tokenType": "Bearer",
"expiresIn": 3600
}curl -X POST http://localhost:8080/api/accounts \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"accountType": "SAVINGS",
"currency": "USD",
"initialDeposit": 1000.00
}'Response:
{
"accountNumber": "ACC1234567890",
"accountType": "SAVINGS",
"balance": 1000.00,
"currency": "USD",
"status": "ACTIVE",
"createdAt": "2024-12-23T10:35:00Z"
}curl -X POST http://localhost:8080/api/transactions/transfer \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"fromAccount": "ACC1234567890",
"toAccount": "ACC0987654321",
"amount": 500.00,
"currency": "USD",
"description": "Payment for services"
}'Response:
{
"transactionId": "TXN_789012",
"fromAccount": "ACC1234567890",
"toAccount": "ACC0987654321",
"amount": 500.00,
"status": "SUCCESS",
"timestamp": "2024-12-23T10:40:00Z",
"referenceNumber": "REF123456789"
}All services follow a standard error format:
{
"timestamp": "2024-12-23T10:45:00Z",
"status": 400,
"error": "Bad Request",
"message": "Insufficient balance",
"path": "/api/transactions/transfer",
"traceId": "abc123def456"
}HTTP Status Codes:
200 OK- Successful request201 Created- Resource created400 Bad Request- Invalid request data401 Unauthorized- Missing or invalid token403 Forbidden- Insufficient permissions404 Not Found- Resource not found409 Conflict- Resource conflict (e.g., duplicate account)500 Internal Server Error- Server error503 Service Unavailable- Service down
The system uses RS256 (RSA Signature with SHA-256) for JWT token generation:
Header:
{
"alg": "RS256",
"typ": "JWT"
}
Payload:
{
"sub": "user_id",
"username": "john.doe",
"roles": ["USER"],
"iat": 1703331000,
"exp": 1703334600
}
Key Features:
- Asymmetric encryption (public/private key pair)
- Token expiration (1 hour for access token, 7 days for refresh token)
- Redis-based token blacklist for logout
- Automatic token refresh mechanism
| Role | Permissions |
|---|---|
| USER | - View own profile - Manage own accounts - Perform transactions - Apply for loans |
| MANAGER | - All USER permissions - Approve loans - View customer accounts - Generate reports |
| ADMIN | - All MANAGER permissions - Manage users - Configure system - Access all endpoints |
-
Password Security
- Minimum 8 characters
- BCrypt hashing (cost factor: 12)
- Password history tracking
- Forced password change every 90 days
-
API Security
- Rate limiting (100 requests per minute)
- CORS configuration
- SQL injection prevention
- XSS protection
-
Data Security
- Sensitive data encryption at rest
- TLS/SSL for data in transit
- PII (Personally Identifiable Information) masking in logs
- Regular security audits
Exposed Metrics:
- JVM metrics (heap, threads, GC)
- HTTP request metrics (rate, duration, errors)
- Database connection pool metrics
- Kafka consumer lag
- Custom business metrics
Prometheus Configuration (prometheus.yml):
global:
scrape_interval: 15s
evaluation_interval: 15s
external_labels:
cluster: 'banking-system'
environment: 'production'
scrape_configs:
- job_name: 'spring-actuator'
metrics_path: '/actuator/prometheus'
static_configs:
- targets:
- 'auth-service:8081'
- 'user-service:8082'
- 'account-service:8083'
- 'transaction-service:8084'
- 'notification-service:8085'
- 'loan-service:8086'
relabel_configs:
- source_labels: [__address__]
target_label: instance
regex: '([^:]+).*'
replacement: '${1}'
- job_name: 'kafka-exporter'
static_configs:
- targets: ['kafka:9092']
- job_name: 'redis-exporter'
static_configs:
- targets: ['redis:6379']Pre-configured Dashboards:
-
System Overview
- Service health status
- Request rate and latency
- Error rate
- Active users
-
JVM Metrics
- Heap memory usage
- GC pause time
- Thread count
- CPU usage
-
Business Metrics
- Transaction volume
- Transaction success rate
- Account creation rate
- Loan approval rate
- Revenue tracking
-
Kafka Metrics
- Message throughput
- Consumer lag
- Partition distribution
- Broker status
# 1. Open Grafana
http://localhost:3000
# 2. Login (default credentials)
Username: admin
Password: admin
# 3. Navigate to Dashboards β Banking System# Total requests per service
sum(rate(http_server_requests_seconds_count[5m])) by (application)
# Error rate
sum(rate(http_server_requests_seconds_count{status=~"5.."}[5m]))
/
sum(rate(http_server_requests_seconds_count[5m]))
# 95th percentile latency
histogram_quantile(0.95,
sum(rate(http_server_requests_seconds_bucket[5m])) by (le, application)
)
# JVM memory usage
jvm_memory_used_bytes{area="heap"} / jvm_memory_max_bytes{area="heap"}
Banking-system/
βββ .github/
β βββ workflows/
β βββ ci-cd.yml # GitHub Actions CI/CD
βββ account-service/
β βββ src/
β β βββ main/
β β β βββ java/com/banking/account/
β β β β βββ controller/
β β β β βββ service/
β β β β βββ repository/
β β β β βββ model/
β β β β βββ dto/
β β β β βββ config/
β β β β βββ AccountServiceApplication.java
β β β βββ resources/
β β β βββ application.yml
β β β βββ application-docker.yml
β β βββ test/
β βββ Dockerfile
β βββ pom.xml
βββ auth-service/
βββ user-service/
βββ transaction-service/
βββ notification-service/
βββ loan-service/
βββ eureka-server/
βββ api-gateway/
βββ docs/
β βββ api-docs.md
β βββ architecture.md
β βββ deployment.md
βββ docker-compose.yml
βββ prometheus.yml
βββ .env.example
βββ .gitignore
βββ README.md
βββ LICENSE
βββ pom.xml # Parent POM
# Build all services
mvn clean package -DskipTests
# Build specific service
cd auth-service
mvn clean package
# Run tests
mvn test
# Run with specific profile
mvn spring-boot:run -Dspring-boot.run.profiles=dev# Unit tests
mvn test
# Integration tests
mvn verify
# Test coverage report
mvn jacoco:report
# View coverage report
open target/site/jacoco/index.html# Run static code analysis
mvn sonar:sonar
# Check for security vulnerabilities
mvn dependency-check:check
# Format code
mvn spotless:applyUsing Flyway for version control:
# Location: src/main/resources/db/migration/
V1__initial_schema.sql
V2__add_account_types.sql
V3__add_loan_tables.sqlApply migrations:
mvn flyway:migrate# Build production images
docker-compose -f docker-compose.prod.yml build
# Start in detached mode
docker-compose -f docker-compose.prod.yml up -d
# Scale services
docker-compose -f docker-compose.prod.yml up -d --scale transaction-service=3
# Rolling update
docker-compose -f docker-compose.prod.yml up -d --no-deps --build transaction-service# Deploy to Kubernetes
kubectl apply -f k8s/
# Check deployment status
kubectl get pods -n banking-system
# View logs
kubectl logs -f deployment/transaction-service -n banking-system
# Scale deployment
kubectl scale deployment transaction-service --replicas=5 -n banking-systemCreate .env file in root directory:
# Database
MYSQL_ROOT_PASSWORD=your_secure_password
MYSQL_DATABASE=banking_db
# Redis
REDIS_PASSWORD=your_redis_password
# JWT
JWT_SECRET_KEY=your_jwt_secret_key
JWT_EXPIRATION=3600000
# Kafka
KAFKA_BOOTSTRAP_SERVERS=kafka:29092
# Email (SMTP)
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USERNAME=your_email@gmail.com
SMTP_PASSWORD=your_app_password
# SMS (Twilio)
TWILIO_ACCOUNT_SID=your_twilio_sid
TWILIO_AUTH_TOKEN=your_twilio_token
TWILIO_PHONE_NUMBER=+1234567890
# Monitoring
GRAFANA_ADMIN_PASSWORD=your_grafana_passwordGitHub Actions workflow (.github/workflows/ci-cd.yml):
name: CI/CD Pipeline
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 21
uses: actions/setup-java@v3
with:
java-version: '21'
distribution: 'temurin'
- name: Run tests
run: mvn clean verify
build:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build Docker images
run: docker-compose build
- name: Push to Docker Hub
run: |
echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin
docker-compose push
deploy:
needs: build
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- name: Deploy to production
run: |
# Add your deployment script hereWe welcome contributions! Please follow these steps