# 📋 Java Testing System - Microservices Hệ thống **Microservices** backend được xây dựng trên nền tảng **Spring Boot**, triển khai kiến trúc **Saga Pattern** để xử lý distributed transactions. Hệ thống sử dụng **MongoDB** làm cơ sở dữ liệu chính, **Redis** cho distributed locking và caching, được đóng gói hoàn toàn bằng **Docker Compose**. --- ## 🎯 Tổng Quan Hệ Thống Hệ thống bao gồm **2 microservices độc lập** giao tiếp với nhau qua **REST API**, sử dụng **Saga Pattern** với **compensating transactions** để đảm bảo tính nhất quán dữ liệu trong môi trường phân tán. ### 🔄 Luồng Hoạt Động Chính (Saga Pattern) ``` User Service GiftCode Service | | |---(1) Reserve---------------> | | (Đặt trước gift code) | - Validate gift code | | - Check usage history | | - Create RESERVED transaction |<---(2) Return Amount-----------| | | | (3) Process Local: | | - Add balance to user | | - Create RedeemLog | | | |---(4) Confirm----------------> | | | - Update to CONFIRMED | | - Increase usageCount |<---(5) Success----------------| | | | (6) Update log to SUCCESS | ``` **Xử lý lỗi:** - ❌ Lỗi ở bước 3 → Gọi `cancel()` để rollback - ⏱️ Lỗi ở bước 4 → `RetryConfirmScheduler` tự động retry - 🔄 Không confirm sau 5 phút → `ReclaimScheduler` tự động cancel --- ## 🚀 Các Dịch Vụ Chính | Dịch vụ | Port | Công nghệ | Mô tả | | :--- | :--- | :--- | :--- | | **User Service** | `8601` | Spring Boot, MongoDB | Quản lý người dùng và xử lý áp dụng gift code | | **GiftCode Service** | `8602` | Spring Boot, MongoDB, Redis | Quản lý mã quà tặng và xử lý giao dịch redeem | | **Redis** | `6379` | Redis | Distributed locking và caching | | **MongoDB** | `27017` | MongoDB | Cơ sở dữ liệu NoSQL chính | --- ## 🧑‍💼 User Service (Port: 8601) ### Chức Năng Chính Quản lý thông tin người dùng và xử lý việc áp dụng mã quà tặng. ### API Endpoints #### **Quản lý User** - **`POST /users`** - Tạo người dùng mới ```json { "name": "Nguyen Van A", "email": "user@example.com", "password": "password123", "phone": "0123456789", "sex": "MALE" } ``` - **`GET /users/{id}`** - Lấy thông tin user theo ID - **`GET /users?page=0&size=10`** - Lấy danh sách users (có phân trang) - Sắp xếp theo `createdAt` giảm dần - `page`: số trang (default: 0) - `size`: kích thước trang (default: 10, max: 100) #### **Áp Dụng Gift Code** - **`POST /users/apply-gift-code`** - User sử dụng mã quà tặng ```json { "userId": "507f1f77bcf86cd799439011", "giftCode": "WELCOME2024" } ``` **Response:** ```json { "message": "Gift code applied successfully", "status": "success", "amount": 100000, "transactionId": "uuid-transaction-id" } ``` ### Data Models - **User**: `id`, `name`, `email`, `password`, `phone`, `sex`, `balance`, `status`, `createdAt`, `updatedAt` - **RedeemLog**: `transactionId`, `userId`, `giftCode`, `amount`, `status` (PENDING_CONFIRM/SUCCESS) ### Background Jobs - **RetryConfirmScheduler** (mỗi 60 giây) - Tự động retry các giao dịch `PENDING_CONFIRM` - Đảm bảo eventual consistency khi network lỗi --- ## 🎁 GiftCode Service (Port: 8602) ### Chức Năng Chính Quản lý mã quà tặng, kiểm soát việc sử dụng, và xử lý giao dịch redeem với distributed locking. ### API Endpoints #### **Quản lý Gift Code** - **`POST /gift-codes`** - Tạo mã quà tặng mới ```json { "type": "WELCOME", "multiUse": true, "onePerType": true, "usageLimit": 1000, "amount": 100000, "startAt": "2024-01-01T00:00:00Z", "endAt": "2024-12-31T23:59:59Z" } ``` - Tự động generate `code` từ `type` (sử dụng SHA-256) - **`GET /gift-codes?page=0&size=10`** - Lấy danh sách gift codes - **`GET /gift-codes/{code}`** - Lấy thông tin gift code theo mã #### **Xử Lý Giao Dịch (Internal APIs)** - **`POST /gift-codes/reserve`** - Đặt trước gift code (Saga Step 1) ```json { "transactionId": "uuid", "userId": "507f1f77bcf86cd799439011", "code": "WELCOME2024" } ``` **Kiểm tra:** - ✅ Gift code tồn tại và active - ✅ Chưa hết hạn (startAt, endAt) - ✅ Còn lượt sử dụng (usageLimit vs usageCount) - ✅ User chưa dùng code này (nếu onePerType = true) - 🔒 Sử dụng Redis Lock để tránh race condition - **`POST /gift-codes/confirm`** - Xác nhận giao dịch (Saga Step 3) ```json { "transactionId": "uuid" } ``` - Cập nhật: RESERVED → CONFIRMED - Tăng `usageCount` - Lưu vào `GiftCodeUsage` history - **`POST /gift-codes/cancel`** - Hủy giao dịch (Compensating Transaction) ```json { "transactionId": "uuid" } ``` - Cập nhật: RESERVED → CANCELLED - Rollback, không tăng usageCount ### Data Models - **GiftCode**: `id`, `code`, `multiUse`, `onePerType`, `type`, `usageLimit`, `usageCount`, `startAt`, `endAt`, `active`, `amount` - **RedeemTransaction**: `transactionId`, `userId`, `giftCode`, `amount`, `status` (RESERVED/CONFIRMED/CANCELLED) - **GiftCodeUsage**: `userId`, `giftCode`, `type`, `usedAt` ### Business Logic - **multiUse**: Cho phép nhiều user sử dụng cùng 1 code - **onePerType**: Mỗi user chỉ được dùng 1 lần cho mỗi loại (type) - **usageLimit**: Giới hạn tổng số lần sử dụng - **Validation**: Kiểm tra expired, active, usage limit ### Background Jobs - **ReclaimScheduler** (mỗi 60 giây) - Tìm transaction RESERVED quá 5 phút - Tự động cancel để giải phóng gift code - Xử lý trường hợp User Service crash ### Concurrency Control - 🔒 **Redis Distributed Lock** (timeout: 10 giây) - Key format: `giftcode:lock:{code}` - Đảm bảo atomic operation khi nhiều request đồng thời --- ## 🛡️ Cơ Chế Đảm Bảo Tính Nhất Quán 1. **Redis Distributed Lock** - Tránh race condition 2. **Transaction Status Tracking** - Theo dõi RESERVED/CONFIRMED/CANCELLED 3. **Retry Mechanism** - Tự động retry confirm nếu network lỗi 4. **Timeout Reclaim** - Tự động hủy transaction bị stuck 5. **Usage History** - Kiểm tra lịch sử để enforce onePerType rule 6. **Saga Pattern** - Compensating transactions cho rollback --- ## 🛠 Yêu Cầu Hệ Thống - **Docker** & **Docker Compose** - **Java 21** (nếu build thủ công) - **Maven 3.9+** (nếu build thủ công) --- ## 📦 Hướng Dẫn Cài Đặt và Khởi Chạy ### 1. Build và chạy toàn bộ bằng Docker Compose ```bash # Xóa sạch các container cũ và build lại từ đầu docker-compose down docker-compose up -d --build