Skip to content

Repository files navigation

🛒 E-Commerce Microservices Platform

A robust, scalable microservices-based e-commerce platform built with Spring Boot, Spring Cloud, and modern resilience patterns. This system demonstrates enterprise-grade architecture with service discovery, API Gateway, circuit breakers, and distributed resilience patterns.


📋 Table of Contents


🏗️ Architecture Overview

graph TB
    Client["Client Application"]
    Gateway["API Gateway<br/>Port: 8080"]
    
    subgraph "Service Mesh"
        OrderSvc["Order Service<br/>Port: 8082"]
        InventorySvc["Inventory Service<br/>Port: 8081"]
    end
    
    subgraph "Infrastructure"
        Eureka["Eureka Discovery<br/>Port: 8761"]
        ConfigSvr["Config Server<br/>Port: 8888"]
    end
    
    subgraph "Databases"
        OrderDB["PostgreSQL<br/>OrderDB"]
        InventoryDB["PostgreSQL<br/>InventoryDB"]
    end
    
    Client -->|Routes Requests| Gateway
    Gateway -->|Service Discovery| Eureka
    Gateway -->|Route to Services| OrderSvc
    Gateway -->|Route to Services| InventorySvc
    
    OrderSvc -->|Register| Eureka
    InventorySvc -->|Register| Eureka
    
    OrderSvc -->|OpenFeign Call| InventorySvc
    
    OrderSvc -->|Persist Data| OrderDB
    InventorySvc -->|Persist Data| InventoryDB
    
    OrderSvc -->|Fetch Config| ConfigSvr
    InventorySvc -->|Fetch Config| ConfigSvr
Loading

🔄 Request Flow Diagram

sequenceDiagram
    participant Client
    participant Gateway as API Gateway
    participant Eureka as Service Registry
    participant OrderSvc as Order Service
    participant InventorySvc as Inventory Service
    participant OrderDB as OrderDB
    participant InventoryDB as InventoryDB
    
    Client->>Gateway: POST /orders/api/v1/orders
    Gateway->>Eureka: Lookup order-service
    Eureka-->>Gateway: Service Instance
    Gateway->>OrderSvc: Forward Request
    
    OrderSvc->>OrderDB: Save Order
    OrderDB-->>OrderSvc: Order Saved
    
    OrderSvc->>InventorySvc: OpenFeign: Check Inventory
    InventorySvc->>InventoryDB: Query Products
    InventoryDB-->>InventorySvc: Product Data
    InventorySvc-->>OrderSvc: Inventory Response
    
    OrderSvc-->>Gateway: Order Response
    Gateway-->>Client: Response
Loading

🎯 Microservices

1. API Gateway (Port: 8080)

  • Central entry point for all client requests
  • Routes requests to appropriate microservices
  • Implements global logging filters
  • Authentication & authorization
  • Circuit breaker integration with Resilience4j

Key Components:

  • GlobalLoggingFilter: Pre and post-request logging
  • AuthenticationFilter: JWT validation
  • OrderController: Routes order-related requests

2. Order Service (Port: 8082)

  • Manages order creation, retrieval, and status updates
  • Communicates with Inventory Service via OpenFeign
  • Implements retry and circuit breaker patterns
  • Database: PostgreSQL (OrderDB)

Key Entities:

  • OrdersEntity: Main order record
  • OrderItemsEntity: Individual items in an order
  • OrderStatus: PENDING, CONFIRMED, SHIPPED, DELIVERED, CANCELLED

Key Components:

  • OrderService: Business logic
  • OrderController: REST endpoints
  • InventoryOpenFeignClient: Remote call to Inventory Service
  • OrderRepo: JPA Repository

3. Inventory Service (Port: 8081)

  • Manages product inventory and stock levels
  • Validates product availability
  • Updates inventory on order placement
  • Database: PostgreSQL (InventoryDB)

Key Entities:

  • ProductEntity: Product information with stock levels

Key Components:

  • ProductService: Business logic
  • ProductsController: REST endpoints
  • OrderFeignClient: Receives order data

4. Discovery Service - Eureka (Port: 8761)

  • Service registry for dynamic service discovery
  • Maintains health status of all services
  • Enables client-side load balancing

5. Config Server (Port: 8888)

  • Centralized configuration management
  • Supports externalized properties
  • Dynamic configuration updates

📚 Tech Stack & Libraries

Core Framework

Library Version Purpose
Spring Boot 3.4.0 Application framework
Spring Cloud 2024.0.0 Microservices patterns
Java 21 Language
Gradle 9.6.1 Build tool

Service Communication

Library Purpose
Spring Cloud Gateway API routing and filtering
OpenFeign Declarative HTTP client
Spring Cloud Netflix Eureka Service discovery
Spring Cloud Config Centralized configuration

Resilience & Observability

Library Purpose
Resilience4j Circuit breaker, retry, rate limiter
Spring Boot Actuator Health checks, metrics, monitoring
Micrometer Metrics collection

Data & Persistence

Library Purpose
Spring Data JPA ORM and repository pattern
Hibernate JPA implementation
PostgreSQL Driver Database connectivity
H2 Database Local development testing

Security

Library Purpose
Spring Security Authentication & authorization
JWT (jjwt) Token-based authentication

Development & Utilities

Library Purpose
Lombok Boilerplate code reduction
ModelMapper Entity-DTO mapping
java-dotenv Environment variable loading

Testing

Library Purpose
JUnit 5 Unit testing framework
Mockito Mocking framework
Testcontainers Integration testing with Docker
Spring Test Spring application testing

📁 Project Structure

ecommerce/
├── api_gateway/                          # API Gateway Module
│   ├── src/main/java/com/ecart/silversurfer/api_gateway/
│   │   ├── controllers/
│   │   │   └── OrderController.java
│   │   ├── filters/
│   │   │   ├── GlobalLoggingFilter.java
│   │   │   ├── AuthenticationFilter.java
│   │   │   └── LoggingOrderFilter.java
│   │   ├── services/
│   │   │   └── JwtService.java
│   │   └── ApiGatewayApplication.java
│   ├── src/main/resources/
│   │   └── application.yaml
│   ├── build.gradle
│   └── settings.gradle
│
├── order_service/                        # Order Service Module
│   ├── src/main/java/com/ecart/silversurfer/order_service/
│   │   ├── controllers/
│   │   │   └── OrderController.java
│   │   ├── services/
│   │   │   └── OrderService.java
│   │   ├── repositories/
│   │   │   └── OrderRepo.java
│   │   ├── entities/
│   │   │   ├── OrdersEntity.java
│   │   │   ├── OrderItemsEntity.java
│   │   │   └── enums/OrderStatus.java
│   │   ├── dtos/
│   │   │   ├── OrderRequestDto.java
│   │   │   └── OrderRequestItemDto.java
│   │   ├── clients/
│   │   │   └── InventoryOpenFeignClient.java
│   │   ├── config/
│   │   └── OrderServiceApplication.java
│   ├── src/main/resources/
│   │   └── application.properties
│   ├── build.gradle
│   └── settings.gradle
│
├── inventory_service/                    # Inventory Service Module
│   ├── src/main/java/com/ecart/silversurfer/inventory_service/
│   │   ├── controllers/
│   │   │   └── ProductsController.java
│   │   ├── services/
│   │   │   └── ProductService.java
│   │   ├── repositories/
│   │   │   └── ProductRepo.java
│   │   ├── entities/
│   │   │   └── ProductEntity.java
│   │   ├── dtos/
│   │   │   └── ProductDto.java
│   │   ├── clients/
│   │   │   └── OrderFeignClient.java
│   │   └── InventoryServiceApplication.java
│   ├── src/main/resources/
│   │   └── application.properties
│   ├── build.gradle
│   └── settings.gradle
│
├── discovery_service/                    # Eureka Discovery Service
│   ├── src/main/resources/
│   │   └── application.yaml
│   └── build.gradle
│
├── config_server/                        # Config Server
│   ├── src/main/resources/
│   │   └── application.yaml
│   └── build.gradle
│
├── build.gradle                          # Root Gradle build file
├── settings.gradle                       # Gradle settings
├── .env                                  # Environment variables
└── README.md                             # This file

🚀 Getting Started

Prerequisites

  • Java 21+
  • PostgreSQL 12+
  • Gradle 9.6.1+
  • Docker (optional, for Testcontainers)

Installation & Setup

1. Clone the Repository

git clone https://github.com/rahulsinghfaujdar/ECommerceMicroservice.git
cd ecommerce

2. Configure Environment Variables

Create or update .env file:

SPRING_SECURITY_USER_NAME=admin
SPRING_SECURITY_USER_PASSWORD=12345
DB_URL=jdbc:postgresql://localhost:5432/OrderDB
DB_USERNAME=postgres
DB_PASSWORD=1234

3. Setup Databases

# Create databases
createdb OrderDB
createdb InventoryDB

4. Build the Project

./gradlew clean build

5. Start Services (in order)

Terminal 1 - Discovery Service (Eureka)

cd discovery_service
./gradlew bootRun
# Access: http://localhost:8761

Terminal 2 - Config Server

cd config_server
./gradlew bootRun
# Access: http://localhost:8888

Terminal 3 - Inventory Service

cd inventory_service
./gradlew bootRun
# Access: http://localhost:8081/inventory

Terminal 4 - Order Service

cd order_service
./gradlew bootRun
# Access: http://localhost:8082/orders

Terminal 5 - API Gateway

cd api_gateway
./gradlew bootRun
# Access: http://localhost:8080

💾 Database Schema

Order Service - OrderDB

orders Table

CREATE TABLE orders (
    order_id BIGSERIAL PRIMARY KEY,
    customer_name VARCHAR(255) NOT NULL,
    order_status VARCHAR(50) DEFAULT 'PENDING',
    total_price DECIMAL(10, 2),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

order_items Table

CREATE TABLE order_items (
    item_id BIGSERIAL PRIMARY KEY,
    order_id BIGINT NOT NULL,
    product_id BIGINT NOT NULL,
    quantity INT NOT NULL,
    price DECIMAL(10, 2),
    FOREIGN KEY (order_id) REFERENCES orders(order_id) ON DELETE CASCADE
);

Inventory Service - InventoryDB

products Table

CREATE TABLE products (
    product_id BIGSERIAL PRIMARY KEY,
    product_name VARCHAR(255) NOT NULL,
    price DECIMAL(10, 2) NOT NULL,
    quantity INT NOT NULL,
    description TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

📡 API Documentation

Order Service APIs

Create Order

POST /orders/api/v1/orders
Content-Type: application/json
Authorization: Bearer <JWT_TOKEN>

{
  "customerName": "John Doe",
  "items": [
    {
      "productId": 1,
      "quantity": 2
    },
    {
      "productId": 2,
      "quantity": 1
    }
  ]
}

Response:

{
  "orderId": 1,
  "customerName": "John Doe",
  "orderStatus": "PENDING",
  "totalPrice": 299.99,
  "items": [
    {
      "productId": 1,
      "quantity": 2,
      "price": 149.99
    }
  ]
}

Get Order by ID

GET /orders/api/v1/orders/{orderId}
Authorization: Bearer <JWT_TOKEN>

Get All Orders

GET /orders/api/v1/orders
Authorization: Bearer <JWT_TOKEN>

Inventory Service APIs

Get All Products

GET /inventory/api/v1/products
Authorization: Bearer <JWT_TOKEN>

Response:

{
  "products": [
    {
      "productId": 1,
      "productName": "Laptop",
      "price": 999.99,
      "quantity": 10,
      "description": "High-performance laptop"
    }
  ]
}

Get Product by ID

GET /inventory/api/v1/products/{productId}
Authorization: Bearer <JWT_TOKEN>

Update Product

PUT /inventory/api/v1/products/{productId}
Content-Type: application/json

{
  "quantity": 5,
  "price": 899.99
}

Health & Monitoring Endpoints

Order Service Health

GET /orders/api/v1/actuator/health
GET /orders/api/v1/actuator/metrics

Inventory Service Health

GET /inventory/api/v1/actuator/health
GET /inventory/api/v1/actuator/metrics

Circuit Breaker Status

GET /orders/api/v1/actuator/health/circuitbreakers
GET /inventory/api/v1/actuator/health/circuitbreakers

🔄 Resilience Patterns

1. Circuit Breaker Pattern

The system implements Resilience4j Circuit Breaker to prevent cascading failures:

resilience4j:
  circuitbreaker:
    instances:
      inventoryCircuitBreaker:
        register-health-indicator: true
        sliding-window-size: 3
        sliding-window-type: COUNT_BASED
        minimum-number-of-calls: 10
        failure-rate-threshold: 50
        wait-duration-in-open-state: 1s
        permitted-number-of-calls-in-half-open-state: 3

States:

  • CLOSED: Normal operation, requests pass through
  • OPEN: Service is down, requests fail immediately
  • HALF_OPEN: Testing if service recovered, limited requests allowed

2. Retry Pattern

Automatic retry on transient failures:

resilience4j:
  retry:
    configs:
      default:
        maxRetryAttempts: 3
        waitDuration: 10s
    instances:
      inventoryRetry:
        baseConfig: default
        waitDuration: 200ms

Configuration:

  • Max retry attempts: 3
  • Initial wait duration: 10 seconds
  • Retry wait duration: 200 milliseconds

3. Rate Limiter Pattern

Prevent service overload:

resilience4j:
  ratelimiter:
    instances:
      inventoryRateLimiter:
        limit-refresh-period: 5s
        limit-for-period: 1
        timeout-duration: 1ms

4. Service-to-Service Communication

OpenFeign is used for declarative HTTP communication:

@FeignClient(name = "inventory-service", 
             url = "http://localhost:8081",
             fallback = InventoryFeignClientFallback.class)
public interface InventoryOpenFeignClient {
    @PostMapping("/inventory/api/v1/products/reserve")
    InventoryResponse reserveProducts(@RequestBody OrderRequestDto request);
}

⚙️ Configuration

Application Properties

Order Service (order_service/src/main/resources/application.properties)

# Server Configuration
spring.application.name=order-service
server.servlet.context-path=/orders
server.port=8082

# Eureka Discovery
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
eureka.instance.prefer-ip-address=true

# Database
spring.datasource.url=jdbc:postgresql://localhost:5432/OrderDB
spring.datasource.username=postgres
spring.datasource.password=1234
spring.datasource.driver-class-name=org.postgresql.Driver

# JPA/Hibernate
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect

# Actuator & Monitoring
management.endpoints.web.exposure.include=health,info,metrics,prometheus
management.endpoint.health.show-details=always
management.health.circuitbreakers.enabled=true

# Resilience4j Configuration
resilience4j.retry.configs.default.maxRetryAttempts=3
resilience4j.retry.configs.default.waitDuration=10s
resilience4j.circuitbreaker.instances.inventoryCircuitBreaker.register-health-indicator=true

📊 Monitoring & Health Checks

Actuator Endpoints

All services expose Spring Boot Actuator endpoints:

Endpoint Purpose
/actuator/health Overall service health
/actuator/health/circuitbreakers Circuit breaker status
/actuator/health/diskSpace Disk space availability
/actuator/metrics Prometheus metrics
/actuator/info Application info

Example Health Check Response

{
  "status": "UP",
  "components": {
    "circuitbreakers": {
      "status": "UP",
      "details": {
        "inventoryCircuitBreaker": {
          "status": "CLOSED"
        }
      }
    },
    "db": {
      "status": "UP",
      "details": {
        "database": "PostgreSQL"
      }
    }
  }
}

Eureka Dashboard

Access the Eureka service registry dashboard:

http://localhost:8761

📋 Postman API Collection

Import the provided Postman collection to test all APIs:

Base URL

http://localhost:8080

Authentication

All requests require a Bearer token. Use JWT authentication:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

API Endpoints Collection

Orders

  • POST /orders/api/v1/orders - Create new order
  • GET /orders/api/v1/orders - List all orders
  • GET /orders/api/v1/orders/{orderId} - Get order details
  • PUT /orders/api/v1/orders/{orderId} - Update order status

Products (Inventory)

  • GET /inventory/api/v1/products - List all products
  • GET /inventory/api/v1/products/{productId} - Get product details
  • PUT /inventory/api/v1/products/{productId} - Update product
  • POST /inventory/api/v1/products/reserve - Reserve products for order

Health & Monitoring

  • GET /orders/api/v1/actuator/health - Order service health
  • GET /inventory/api/v1/actuator/health - Inventory service health
  • GET /orders/api/v1/actuator/health/circuitbreakers - Circuit breaker status

Import Steps:

  1. Open Postman
  2. Click "Import" button
  3. Select the Postman collection file
  4. Set environment variables (base_url, token, etc.)
  5. Start testing!

🔐 Security

Authentication Flow

graph LR
    A["Client"] -->|Credentials| B["Auth Filter"]
    B -->|Validates JWT| C["JwtService"]
    C -->|Token Valid| D["Request Proceeds"]
    C -->|Token Invalid| E["401 Unauthorized"]
Loading

JWT Token Components

  • Header: Algorithm (HS256)
  • Payload: User claims, expiry time
  • Signature: HMAC-SHA256 encoded

🧪 Testing

Unit Tests

./gradlew test

Integration Tests

./gradlew integrationTest

Test Coverage

./gradlew test --info

🐛 Troubleshooting

Issue: Services not registering with Eureka

  • Verify Eureka server is running on port 8761
  • Check firewall settings
  • Ensure eureka.client.service-url.defaultZone is correct

Issue: Database connection refused

  • Verify PostgreSQL is running
  • Check database credentials in properties file
  • Ensure OrderDB and InventoryDB are created

Issue: Circuit breaker stuck in OPEN state

  • Check the actual service health
  • Monitor logs for exceptions
  • Adjust waitDurationInOpenState if needed

Issue: OpenFeign calls timing out

  • Check Inventory Service is running
  • Verify network connectivity
  • Review retry and timeout configurations

📚 Additional Resources


👥 Contributing

Contributions are welcome! Please follow these steps:

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

📝 License

This project is licensed under the MIT License - see LICENSE file for details.


📧 Contact & Support

For issues, questions, or suggestions:


Built with ❤️ using Spring Boot & Microservices Architecture

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages