Skip to content

A Spring Boot microservices demo featuring JWT authentication, API Gateway, and event-driven architecture with RabbitMQ. Includes user management, order processing, and payment services with async messaging.

Notifications You must be signed in to change notification settings

rafiq15/Spring-RabbitMQ-JWT-Ecosystem

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

1 Commit
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Microservices with JWT Authentication and RabbitMQ

A comprehensive Spring Boot microservices architecture demonstrating JWT-based authentication, API Gateway routing, and event-driven communication using RabbitMQ.

πŸ“‹ Table of Contents

πŸ—οΈ Architecture Overview

This project implements a microservices architecture with the following components:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   API Gateway   β”‚ (Port 8080)
β”‚  JWT Validation β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚
    β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚                         β”‚              β”‚
β”Œβ”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   User     β”‚      β”‚   Order     β”‚   β”‚   Payment/Invoice β”‚
β”‚  Service   β”‚      β”‚  Service    β”‚   β”‚     Service       β”‚
β”‚ (Port 8081)β”‚      β”‚ (Port 8083) β”‚   β”‚   (Port 8082)     β”‚
β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
      β”‚                    β”‚                  β”‚
      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           β”‚
                    β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”
                    β”‚  RabbitMQ   β”‚
                    β”‚  Message    β”‚
                    β”‚   Broker    β”‚
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           β”‚
                    β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”
                    β”‚ PostgreSQL  β”‚
                    β”‚  Database   β”‚
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Key Features

  • JWT Authentication: Secure token-based authentication with Bearer token validation
  • API Gateway: Centralized routing and authentication filter
  • Event-Driven Communication: Asynchronous messaging using RabbitMQ
  • Multi-Module Maven Project: Organized with shared common module
  • PostgreSQL Database: Relational data persistence for each service
  • RESTful APIs: Standard REST endpoints with proper HTTP methods

πŸ› οΈ Technology Stack

Core Technologies

  • Java: 21
  • Spring Boot: 3.2.0
  • Spring Cloud Gateway: 2023.0.0
  • Maven: Multi-module project structure

Key Dependencies

  • Spring Security: Authentication and authorization
  • Spring Data JPA: Database interaction
  • Spring AMQP: RabbitMQ integration
  • JWT (JJWT): 0.11.5 - JSON Web Token implementation
  • PostgreSQL: Database
  • Lombok: Code generation for POJOs
  • Jackson: JSON serialization/deserialization

πŸ“¦ Services Description

1. Gateway Service (Port 8080)

Purpose: API Gateway with JWT authentication filter

Responsibilities:

  • Route requests to appropriate microservices
  • Validate JWT tokens for protected endpoints
  • Centralized security enforcement

Key Components:

  • JwtAuthenticationFilter: Custom gateway filter for JWT validation
  • GatewayConfig: Route configuration for all services

2. User Service (Port 8081)

Purpose: User management and authentication

Responsibilities:

  • User registration and authentication
  • JWT token generation
  • Password encryption (BCrypt)
  • Publish user registration events

Key Components:

  • AuthController: Registration and login endpoints
  • UserService: Business logic for user operations
  • JwtUtil: JWT token generation and validation
  • SecurityConfig: Spring Security configuration

3. Order Service (Port 8083)

Purpose: Order management

Responsibilities:

  • Create and manage orders
  • Publish order created events
  • Listen to payment processed events
  • Update order status based on payment results

Key Components:

  • OrderController: Order CRUD endpoints
  • OrderService: Order business logic
  • OrderEventPublisher: Publish order events to RabbitMQ
  • PaymentEventConsumer: Listen to payment events

4. Payment-Invoice Service (Port 8082)

Purpose: Payment processing and invoice generation

Responsibilities:

  • Listen to order created events
  • Process payments (simulated)
  • Generate invoices
  • Publish payment processed events
  • Send welcome emails to new users

Key Components:

  • OrderEventConsumer: Listen to order events
  • PaymentService: Payment processing logic
  • InvoiceService: Invoice generation
  • PaymentEventPublisher: Publish payment events
  • WelcomeEmailListener: Listen to user registration events

5. Common Module

Purpose: Shared data structures and utilities

Contains:

  • DTOs (Data Transfer Objects): UserDTO, OrderDTO, LoginRequest, LoginResponse
  • Events: OrderCreatedEvent, PaymentProcessedEvent

πŸ“ Project Structure

microservices-jwt/
β”œβ”€β”€ pom.xml                          # Parent POM
β”œβ”€β”€ common/                          # Shared module
β”‚   β”œβ”€β”€ src/main/java/com/common/
β”‚   β”‚   β”œβ”€β”€ dto/                    # Data Transfer Objects
β”‚   β”‚   β”‚   β”œβ”€β”€ UserDTO.java
β”‚   β”‚   β”‚   β”œβ”€β”€ OrderDTO.java
β”‚   β”‚   β”‚   β”œβ”€β”€ LoginRequest.java
β”‚   β”‚   β”‚   └── LoginResponse.java
β”‚   β”‚   └── event/                  # Event classes
β”‚   β”‚       β”œβ”€β”€ OrderCreatedEvent.java
β”‚   β”‚       └── PaymentProcessedEvent.java
β”‚   └── pom.xml
β”œβ”€β”€ gateway-service/
β”‚   β”œβ”€β”€ src/main/java/com/gateway_service/
β”‚   β”‚   β”œβ”€β”€ GatewayServiceApplication.java
β”‚   β”‚   β”œβ”€β”€ config/
β”‚   β”‚   β”‚   └── GatewayConfig.java
β”‚   β”‚   └── filter/
β”‚   β”‚       └── JwtAuthenticationFilter.java
β”‚   β”œβ”€β”€ src/main/resources/
β”‚   β”‚   └── application.properties
β”‚   └── pom.xml
β”œβ”€β”€ user-service/
β”‚   β”œβ”€β”€ src/main/java/com/user_service/
β”‚   β”‚   β”œβ”€β”€ UserServiceApplication.java
β”‚   β”‚   β”œβ”€β”€ config/
β”‚   β”‚   β”‚   β”œβ”€β”€ JwtUtil.java
β”‚   β”‚   β”‚   β”œβ”€β”€ SecurityConfig.java
β”‚   β”‚   β”‚   └── RabbitConfig.java
β”‚   β”‚   β”œβ”€β”€ controller/
β”‚   β”‚   β”‚   └── AuthController.java
β”‚   β”‚   β”œβ”€β”€ model/
β”‚   β”‚   β”‚   └── User.java
β”‚   β”‚   β”œβ”€β”€ repository/
β”‚   β”‚   β”‚   └── UserRepository.java
β”‚   β”‚   └── service/
β”‚   β”‚       └── UserService.java
β”‚   β”œβ”€β”€ src/main/resources/
β”‚   β”‚   └── application.properties
β”‚   └── pom.xml
β”œβ”€β”€ order-service/
β”‚   β”œβ”€β”€ src/main/java/com/order_service/
β”‚   β”‚   β”œβ”€β”€ OrderServiceApplication.java
β”‚   β”‚   β”œβ”€β”€ config/
β”‚   β”‚   β”‚   └── RabbitMQConfig.java
β”‚   β”‚   β”œβ”€β”€ controller/
β”‚   β”‚   β”‚   └── OrderController.java
β”‚   β”‚   β”œβ”€β”€ model/
β”‚   β”‚   β”‚   └── Order.java
β”‚   β”‚   β”œβ”€β”€ repository/
β”‚   β”‚   β”‚   └── OrderRepository.java
β”‚   β”‚   └── service/
β”‚   β”‚       β”œβ”€β”€ OrderService.java
β”‚   β”‚       β”œβ”€β”€ OrderEventPublisher.java
β”‚   β”‚       └── PaymentEventConsumer.java
β”‚   β”œβ”€β”€ src/main/resources/
β”‚   β”‚   └── application.properties
β”‚   └── pom.xml
└── payment-invoice-service/
    β”œβ”€β”€ src/main/java/com/payment_invoice_service/
    β”‚   β”œβ”€β”€ PaymentInvoiceServiceApplication.java
    β”‚   β”œβ”€β”€ config/
    β”‚   β”‚   └── RabbitConfig.java
    β”‚   β”œβ”€β”€ listener/
    β”‚   β”‚   └── WelcomeEmailListener.java
    β”‚   β”œβ”€β”€ model/
    β”‚   β”‚   β”œβ”€β”€ Payment.java
    β”‚   β”‚   └── Invoice.java
    β”‚   β”œβ”€β”€ repository/
    β”‚   β”‚   β”œβ”€β”€ PaymentRepository.java
    β”‚   β”‚   └── InvoiceRepository.java
    β”‚   └── service/
    β”‚       β”œβ”€β”€ OrderEventConsumer.java
    β”‚       β”œβ”€β”€ PaymentService.java
    β”‚       β”œβ”€β”€ InvoiceService.java
    β”‚       └── PaymentEventPublisher.java
    β”œβ”€β”€ src/main/resources/
    β”‚   └── application.properties
    └── pom.xml

πŸ—„οΈ Database Schema

User Service Database (user_db)

users table:

CREATE TABLE users (
    id BIGSERIAL PRIMARY KEY,
    username VARCHAR(255) UNIQUE NOT NULL,
    email VARCHAR(255) UNIQUE NOT NULL,
    password VARCHAR(255) NOT NULL
);

Order Service Database (user_db)

orders table:

CREATE TABLE orders (
    id BIGSERIAL PRIMARY KEY,
    user_id BIGINT NOT NULL,
    product_name VARCHAR(255) NOT NULL,
    quantity INTEGER NOT NULL,
    amount DECIMAL(19,2) NOT NULL,
    status VARCHAR(50) NOT NULL DEFAULT 'PENDING',
    created_at TIMESTAMP NOT NULL
);

Payment-Invoice Service Database (user_db)

payments table:

CREATE TABLE payments (
    id BIGSERIAL PRIMARY KEY,
    order_id BIGINT NOT NULL,
    user_id BIGINT NOT NULL,
    status VARCHAR(50) NOT NULL,
    transaction_id VARCHAR(255),
    processed_at TIMESTAMP NOT NULL
);

invoices table:

CREATE TABLE invoices (
    id BIGSERIAL PRIMARY KEY,
    order_id BIGINT NOT NULL,
    user_id BIGINT NOT NULL,
    user_email VARCHAR(255),
    amount DECIMAL(19,2) NOT NULL,
    product_name VARCHAR(255),
    quantity INTEGER,
    generated_at TIMESTAMP NOT NULL
);

πŸ“¨ Event-Driven Architecture

RabbitMQ Queues and Exchanges

1. User Registration Flow

  • Exchange: user.exchange (TopicExchange)
  • Routing Key: user.welcome
  • Queue: user.welcome.queue
  • Purpose: Send welcome emails to newly registered users

2. Order Processing Flow

  • Queue: order.queue
  • Purpose: Notify payment service when an order is created
  • Event: OrderCreatedEvent

3. Payment Processing Flow

  • Queue: payment.queue
  • Purpose: Update order status when payment is processed
  • Event: PaymentProcessedEvent

Event Models

OrderCreatedEvent:

record OrderCreatedEvent(
    Long orderId,
    Long userId,
    String productName,
    Integer quantity,
    BigDecimal amount
)

PaymentProcessedEvent:

record PaymentProcessedEvent(
    Long orderId,
    Long userId,
    String status,
    String transactionId
)

πŸšͺ API Gateway Routes

Configured Routes

Path Pattern Target Service Port Authentication Required
/api/auth/** user-service 8081 ❌ No (Public)
/api/orders/** order-service 8083 βœ… Yes (JWT Required)

Note: The gateway configuration shows commented routes for /api/users/** and /api/payments/** which can be enabled for additional secured endpoints.

πŸ“‹ Prerequisites

Before running the application, ensure you have the following installed:

  • Java Development Kit (JDK): Version 21 or higher
  • Maven: Version 3.6 or higher
  • PostgreSQL: Version 12 or higher
  • RabbitMQ: Version 3.8 or higher
  • IDE: IntelliJ IDEA, Eclipse, or VS Code (recommended)

βš™οΈ Setup and Installation

1. Clone the Repository

git clone <repository-url>
cd microservices-jwt

2. Database Setup

Create a PostgreSQL database:

CREATE DATABASE user_db;

Note: All services currently use the same database (user_db). In production, consider using separate databases for each service.

3. RabbitMQ Setup

Ensure RabbitMQ is running:

# Start RabbitMQ server
rabbitmq-server

# Check RabbitMQ status
rabbitmqctl status

Access RabbitMQ Management Console: http://localhost:15672

  • Default credentials: guest/guest

4. Build the Project

Navigate to the project root and build all modules:

mvn clean install

Or build specific modules:

# Build common module first (required by others)
cd common
mvn clean install

# Build individual services
cd ../user-service
mvn clean package

cd ../gateway-service
mvn clean package

cd ../order-service
mvn clean package

cd ../payment-invoice-service
mvn clean package

πŸ”§ Configuration

Application Properties

User Service (Port 8081)

server.port=8081
spring.application.name=user-service

# Database
spring.datasource.url=jdbc:postgresql://localhost:5432/user_db
spring.datasource.username=postgres
spring.datasource.password=root
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql=true

# JWT Configuration
jwt.secret=mySecretKeymySecretKeymySecretKeymySecretKeymySecretKeymySecretKey
jwt.expiration=86400000  # 24 hours in milliseconds

# RabbitMQ
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest

Gateway Service (Port 8080)

server.port=8080
spring.application.name=gateway-service

# JWT Configuration (must match user-service)
jwt.secret=mySecretKeymySecretKeymySecretKeymySecretKeymySecretKeymySecretKey

spring.cloud.gateway.discovery.locator.enabled=false

Order Service (Port 8083)

server.port=8083
spring.application.name=order-service

# Database
spring.datasource.url=jdbc:postgresql://localhost:5432/user_db
spring.datasource.username=postgres
spring.datasource.password=root
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql=true

# RabbitMQ
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest

Payment-Invoice Service (Port 8082)

server.port=8082
spring.application.name=payment-invoice-service

# Database
spring.datasource.url=jdbc:postgresql://localhost:5432/user_db
spring.datasource.username=postgres
spring.datasource.password=root
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql=true

⚠️ Important Configuration Notes:

  • JWT secret must be identical in both gateway-service and user-service
  • Database credentials should match your PostgreSQL setup
  • Change jwt.secret in production to a secure value
  • Set spring.jpa.hibernate.ddl-auto=update or validate in production (not create-drop)

πŸš€ Running the Application

Start Services in Order:

  1. Start PostgreSQL and RabbitMQ (if not already running)

  2. Start User Service:

cd user-service
mvn spring-boot:run

Service will start on: http://localhost:8081

  1. Start Gateway Service:
cd gateway-service
mvn spring-boot:run

Service will start on: http://localhost:8080

  1. Start Order Service:
cd order-service
mvn spring-boot:run

Service will start on: http://localhost:8083

  1. Start Payment-Invoice Service:
cd payment-invoice-service
mvn spring-boot:run

Service will start on: http://localhost:8082

Running from JAR files:

# Build all services
mvn clean package

# Run services
java -jar user-service/target/user-service-0.0.1-SNAPSHOT.jar
java -jar gateway-service/target/gateway-service-0.0.1-SNAPSHOT.jar
java -jar order-service/target/order-service-0.0.1-SNAPSHOT.jar
java -jar payment-invoice-service/target/payment-invoice-service-0.0.1-SNAPSHOT.jar

πŸ“‘ API Endpoints

Authentication Endpoints (via Gateway: Port 8080)

Register User

POST http://localhost:8080/api/auth/register
Content-Type: application/json

{
    "username": "john_doe",
    "email": "john@example.com",
    "password": "password123"
}

Response:

{
    "id": 1,
    "username": "john_doe",
    "email": "john@example.com",
    "password": null
}

Login

POST http://localhost:8080/api/auth/login
Content-Type: application/json

{
    "username": "john_doe",
    "password": "password123"
}

Response:

{
    "token": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJqb2huX2RvZSIsImlhdCI6MTYzMjE...",
    "username": "john_doe",
    "email": "john@example.com"
}

Order Endpoints (via Gateway: Port 8080)

Note: All order endpoints require JWT authentication via Authorization: Bearer <token> header.

Create Order

POST http://localhost:8080/api/orders
Content-Type: application/json
Authorization: Bearer <your-jwt-token>

{
    "userId": 1,
    "productName": "Laptop",
    "quantity": 2,
    "amount": 2500.00
}

Response:

{
    "id": 1,
    "userId": 1,
    "productName": "Laptop",
    "quantity": 2,
    "amount": 2500.00,
    "status": "PENDING"
}

Get Orders by User

GET http://localhost:8080/api/orders/user/1
Authorization: Bearer <your-jwt-token>

Response:

[
    {
        "id": 1,
        "userId": 1,
        "productName": "Laptop",
        "quantity": 2,
        "amount": 2500.00,
        "status": "PAID"
    }
]

Get Order by ID

GET http://localhost:8080/api/orders/1
Authorization: Bearer <your-jwt-token>

Direct Service Endpoints (Development Only)

For development/testing, you can access services directly:

  • User Service: http://localhost:8081/api/auth/**
  • Order Service: http://localhost:8083/api/orders/**

Production: All requests should go through the API Gateway (port 8080).

πŸ”„ Event Flow

Complete Order Processing Flow

1. User Registration
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚   Client    β”‚
   β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
          β”‚ POST /api/auth/register
          β–Ό
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚   Gateway    β”‚
   β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
          β”‚
          β–Ό
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      Publish UserDTO        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚ User Service │──────to user.welcome────────>β”‚ Payment-Invoice  β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                              β”‚     Service      β”‚
          β”‚                                      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
          β”‚                                               β”‚
          β–Ό                                               β–Ό
    Save to DB                               Log: "πŸ“© Welcome email sent"

2. User Login
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚   Client    β”‚
   β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
          β”‚ POST /api/auth/login
          β–Ό
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚   Gateway    β”‚
   β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
          β”‚
          β–Ό
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚ User Service │──────> Generate JWT Token
   β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
          β”‚
          β–Ό
    Return token to client

3. Create Order Flow
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚   Client    β”‚
   β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
          β”‚ POST /api/orders + JWT
          β–Ό
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚   Gateway    │──────> Validate JWT
   β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
          β”‚
          β–Ό
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      Publish OrderCreatedEvent     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚Order Service │───────to order.queue───────────────>β”‚ Payment-Invoice  β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                     β”‚     Service      β”‚
          β”‚                                             β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
          β”‚                                                      β”‚
          β–Ό                                                      β–Ό
    Save Order                                        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    (Status: PENDING)                                 β”‚  Process Payment    β”‚
                                                      β”‚  Generate Invoice   β”‚
                                                      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                                                β”‚
                                                                β”‚ Publish PaymentProcessedEvent
                                                                β”‚ to payment.queue
                                                                β–Ό
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚Order Service β”‚<────────────────────────────────── Payment-Invoice  β”‚
   β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜                                   β”‚     Service      β”‚
          β”‚                                           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
          β–Ό
    Update Order Status
    (Status: PAID)

Event Processing Timeline

  1. Order Created β†’ OrderCreatedEvent published to order.queue
  2. Payment Service consumes event from order.queue
  3. Payment Processed β†’ Creates Payment & Invoice records
  4. PaymentProcessedEvent published to payment.queue
  5. Order Service consumes event from payment.queue
  6. Order Updated β†’ Status changes from PENDING to PAID

πŸ” Security Implementation

JWT Token Structure

Header:

{
    "alg": "HS256",
    "typ": "JWT"
}

Payload:

{
    "sub": "username",
    "iat": 1632123456,
    "exp": 1632209856
}

Authentication Flow

  1. User Registration: Password encrypted with BCrypt
  2. User Login: Credentials validated, JWT token generated
  3. Token Validation: Gateway validates token before routing
  4. Protected Endpoints: Require valid JWT in Authorization header

Security Configuration

User Service:

  • Public endpoints: /api/auth/**
  • All other endpoints require authentication
  • Stateless session management
  • CSRF disabled (for REST API)

Gateway Service:

  • JWT validation in JwtAuthenticationFilter
  • Returns 401 Unauthorized for invalid/missing tokens
  • Routes without filter are public (e.g., /api/auth/**)

Password Security

  • BCrypt hashing with default strength (10 rounds)
  • Passwords never returned in API responses
  • Stored securely in database

πŸ§ͺ Testing

Manual Testing with cURL

Register a User

curl -X POST http://localhost:8080/api/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "username": "testuser",
    "email": "test@example.com",
    "password": "password123"
  }'

Login

curl -X POST http://localhost:8080/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "username": "testuser",
    "password": "password123"
  }'

Create Order (with JWT)

TOKEN="<your-jwt-token>"

curl -X POST http://localhost:8080/api/orders \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{
    "userId": 1,
    "productName": "Gaming Laptop",
    "quantity": 1,
    "amount": 1500.00
  }'

Get Orders

curl -X GET http://localhost:8080/api/orders/user/1 \
  -H "Authorization: Bearer $TOKEN"

Testing with Postman

  1. Import Collection: Create a new collection in Postman
  2. Set Environment Variables:
    • base_url: http://localhost:8080
    • token: (will be set after login)
  3. Register & Login: Save token from login response
  4. Use Token: Add to Authorization header for protected endpoints

Monitoring RabbitMQ

Access RabbitMQ Management UI: http://localhost:15672

Verify Queues:

  • order.queue
  • payment.queue
  • user.welcome.queue

Monitor:

  • Message rates
  • Queue depths
  • Consumer connections

Console Logs

Each service logs important events:

User Service:

User registered: john_doe
Welcome email event published for: john@example.com

Order Service:

Order created event published: 1
Received payment processed event for order: 1
Order 1 status updated to PAID

Payment-Invoice Service:

Received order created event: 1
Payment processed for order: 1
Invoice generated for order: 1
πŸ“© Received welcome email event: john@example.com

πŸ› Troubleshooting

Common Issues and Solutions

1. JWT Token Validation Fails

Symptom: 401 Unauthorized from Gateway Causes:

  • JWT secret mismatch between services
  • Token expired
  • Malformed token

Solution:

# Ensure identical JWT secrets in both services
# user-service/application.properties
jwt.secret=mySecretKeymySecretKeymySecretKeymySecretKeymySecretKeymySecretKey

# gateway-service/application.properties
jwt.secret=mySecretKeymySecretKeymySecretKeymySecretKeymySecretKeymySecretKey

2. RabbitMQ Connection Failed

Symptom: Connection refused to localhost:5672 Solution:

# Check RabbitMQ status
rabbitmqctl status

# Start RabbitMQ
rabbitmq-server

# Verify credentials in application.properties
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest

3. Database Connection Error

Symptom: Unable to connect to PostgreSQL Solution:

# Verify PostgreSQL is running
pg_isready

# Check database exists
psql -U postgres -c "\l"

# Create database if missing
psql -U postgres -c "CREATE DATABASE user_db;"

# Verify credentials in application.properties
spring.datasource.username=postgres
spring.datasource.password=root

4. Port Already in Use

Symptom: Port 8080/8081/8082/8083 already in use Solution:

# Windows
netstat -ano | findstr :<PORT>
taskkill /PID <PID> /F

# Linux/Mac
lsof -i :<PORT>
kill -9 <PID>

# Or change port in application.properties
server.port=8085

5. Messages Not Being Consumed

Symptom: Events published but not processed Checks:

  • Verify queues exist in RabbitMQ Management UI
  • Check consumer connections
  • Review Jackson converter configuration
  • Ensure message serialization format matches

Solution:

// Ensure Jackson2JsonMessageConverter is configured
@Bean
public Jackson2JsonMessageConverter jsonConverter() {
    return new Jackson2JsonMessageConverter();
}

6. Common Module Not Found

Symptom: Cannot resolve dependency on common module Solution:

# Build and install common module first
cd common
mvn clean install

7. Schema Auto-Creation Issues

Symptom: Tables not created automatically Solution:

# For development, use create-drop
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql=true

# For production, use update or validate
spring.jpa.hibernate.ddl-auto=update

Debug Mode

Enable debug logging for troubleshooting:

# In application.properties
logging.level.org.springframework=DEBUG
logging.level.com.user_service=DEBUG
logging.level.org.springframework.amqp=DEBUG
logging.level.org.springframework.security=DEBUG

πŸ“ Development Notes

Code Quality

  • Uses Lombok for reduced boilerplate
  • Java Records for immutable DTOs and Events
  • Spring Boot 3.x with Jakarta EE
  • RESTful API design principles

Database Design

  • All services share same database (for simplicity)
  • Production should use separate databases per service
  • Auto-schema generation enabled (development only)

Security Considerations

  • JWT secret should be environment variable in production
  • HTTPS should be enabled in production
  • Consider OAuth2/OIDC for production systems
  • Implement rate limiting on Gateway

Scalability Considerations

  • Services are stateless and can be horizontally scaled
  • RabbitMQ provides message persistence
  • Consider implementing Circuit Breaker pattern
  • Add service discovery (Eureka) for dynamic routing

πŸš€ Future Enhancements

  • Implement service discovery with Eureka
  • Add distributed tracing with Zipkin/Sleuth
  • Implement circuit breaker with Resilience4j
  • Add centralized configuration with Spring Cloud Config
  • Implement API rate limiting
  • Add comprehensive unit and integration tests
  • Dockerize all services with docker-compose
  • Implement proper logging with ELK stack
  • Add API documentation with Swagger/OpenAPI
  • Implement CORS configuration
  • Add refresh token mechanism
  • Implement proper email service integration

πŸ“„ License

This project is for educational and demonstration purposes.

πŸ‘₯ Contributing

Contributions are welcome! Please follow standard Git workflow:

  1. Fork the repository
  2. Create a feature branch
  3. Commit your changes
  4. Push to the branch
  5. Create a Pull Request

πŸ“§ Contact

For questions or support, please contact the development team.


Built with ❀️ using Spring Boot and RabbitMQ

About

A Spring Boot microservices demo featuring JWT authentication, API Gateway, and event-driven architecture with RabbitMQ. Includes user management, order processing, and payment services with async messaging.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages