Sign inSign up

hainguyen81/shops.order-service

By hainguyen81

β€’Updated 5 months ago

Core distributed microservice micro-engine [order-service] built by GitHub Actions workflow executio

Image
0

331

hainguyen81/shops.order-service repository overview

β β˜• Shops Management Platform β€” Standalone Microservices Architecture Specification

This repository contains the complete production-grade, highly scalable backend ecosystem for a global Shop Placement & Automated Queue Management Platform. The system is engineered using a decoupled, reactive architectural style with Java 17, Spring Boot 3.x, and distributed PostgreSQL persistence modules to eliminate architectural single points of failure (SPOF).


β πŸ—ΊοΈ 1. Architectural Overview & Design Pattern

The ecosystem is split into four standalone, business-bounded microservices:

  1. customer-service (Port 8081): Manages onboarding workflows and customer profile registries.
  2. shop-service (Port 8082): Coordinates storefront configurations and maps regional geolocations via high-performance spatial queries.
  3. product-service (Port 8083): Manages decentralized item catalogs and dynamically localized pricing models.
  4. order-service (Port 8080): The core transaction engine managing dynamic line indexing sequences, ticket lifecycles, nested basket checkout validations, and queue balancing algorithms.
⁠Key Technical Patterns Implemented:
  • Data Isolation: Each microservice maintains its own discrete database instance, preventing structural database coupling.
  • Inter-Service Communication: Handled asynchronously or via declarative REST proxies using Spring Cloud OpenFeign with built-in connection fallback barriers.
  • Dynamic Re-indexing Algorithm: When an active order is voided mid-queue, a transactional cascade routine shifts the positioning indexes (position_in_queue) of all subsequent records forward in a single atomic transaction.

β πŸ“‚ 2. Project Directory Structure

The platform follows a standardized directory mapping structure across all standalone modules:

shops-management/sources/
β”œβ”€β”€ customer-service/               # Manages user accounts & registrations
β”‚   β”œβ”€β”€ src/main/java/.../          # Entities, Controllers, Repositories
β”‚   β”œβ”€β”€ src/test/java/.../          # JUnit 5 & MockMvc Web Layer Tests
β”‚   β”œβ”€β”€ Dockerfile                  # Alpine-based JVM runtime compiler script
β”‚   └── pom.xml                     # Service dependency manager module
β”œβ”€β”€ shop-service/                   # Manages retail stores and geolocations
β”‚   β”œβ”€β”€ Dockerfile
β”‚   └── pom.xml
β”œβ”€β”€ product-service/                # Manages food & beverage item menus
β”‚   β”œβ”€β”€ Dockerfile
β”‚   └── pom.xml
β”œβ”€β”€ notification-service/			# Notify events via Kafka Event-Driven
β”‚   β”œβ”€β”€ Dockerfile
β”‚   └── pom.xml
β”œβ”€β”€ order-service/                  # Orchestrates dynamic queues and nested basket items
β”‚   β”œβ”€β”€ src/main/java/.../client/   # OpenFeign network proxies for cross-checks
β”‚   β”œβ”€β”€ src/main/resources/         # Liquibase master migrations & configuration YAMLs
β”‚   β”œβ”€β”€ Dockerfile
β”‚   └── pom.xml
β”œβ”€β”€ init-scripts/                   # Idempotent PostgreSQL Seed scripts
β”‚   β”œβ”€β”€ 01-customer-seed.sql        # Seeds 10 mock customer nodes
β”‚   β”œβ”€β”€ 02-shop-seed.sql            # Automatically seeds 100 localized shop coordinate nodes
β”‚   β”œβ”€β”€ 03-product-seed.sql     	# Populates dynamic menus for every specific shop
β”‚   └── 04-order-queue-seed.sql     # Pre-populates 300 storefront queue allocation slots
β”œβ”€β”€ docker-compose.yml              # Central multi-container orchestration matrix (every service will use one standalone database)
β”œβ”€β”€ docker-compose-one-db.yml		# Central multi-container orchestration matrix (one database for all services)
β”œβ”€β”€ docker-compose-down.bat			# MS DOS Batch Script to compose docker DOWN using docker-compose.yml
β”œβ”€β”€ docker-compose-up.bat			# MS DOS Batch Script to compose docker UP using docker-compose.yml
β”œβ”€β”€ docker-compose-down-one-db.bat	# MS DOS Batch Script to compose docker DOWN using docker-compose-one-db.yml
└── docker-compose-up-one-db.bat	# MS DOS Batch Script to compose docker UP using docker-compose-one-db.yml

β πŸ”’ 3. Enterprise-Grade Security Architecture

The platform architecture implements a Defense-in-Depth structural security layout spanning both application code domains and cloud network fabrics:

⁠Application Level Security (Spring Security 6.x + JWT)
  • Stateless Authentication: Protected APIs require a cryptographically valid JSON Web Token (JWT) attached to the Authorization: Bearer <token> request header.
  • Zero Hardcoded Secrets: The application runtime decodes signatures using a dynamic parameter ${JWT_SECRET} injected via environment context variables rather than static project asset files.
  • Interactive OpenAPI Validation: The generated OpenAPI 3.0 configuration registers a bearerAuth security requirement schema, rendering a native "Authorize" padlock window inside the Swagger UI panel.
⁠Infrastructure Cloud Security (AWS Topology)
  • Network Isolation: All ECS Fargate containers and RDS database servers operate within completely isolated Private Subnets inside an AWS VPC. They have zero direct internet ingress routes.
  • Least Privilege Security Groups:
    • The Application Load Balancer (ALB) group only admits public connection hooks over port 443 (HTTPS).
    • The ECS Microservice Tasks group accepts ingress execution blocks exclusively routed from the ALB signature ID.
    • The PostgreSQL Database Engine group completely rejects external request queries unless they originate from within the active backend ECS Tasks group boundary.

β πŸ“Š 4. Centralized Logging & Distributed Tracing

To handle real-time debugging across network boundaries, the platform enforces automated telemetry generation:

  • Distributed Tracing: Leverages Micrometer Tracing Bridge (Brave) to automatically propagate a unique Trace ID across multi-hop inter-service calls.
  • Aspect-Oriented Logging: Implements zero-code automated incoming Request/Response payload audit interception using specialized central web filters.
  • Unified Console Format: Log patterns are structured dynamically to identify tracking tokens: 2026-06-11 14:15:02.450 | INFO | [order-service,a7b8c9d0e1f2a3b4,f9e8d7c6b5a43u2y] | c.i.o.s.OrderService : Processing order checkout...
  • Log Rotation: Embedded background Logback rolling policies compress log records into daily .log.gz archives on the host machine once files touch a 10MB limit, keeping a strict 7-day historical retention cap.

β πŸš€ 5. Local Setup & Verification Guide

⁠Prerequisites
  • Docker & Docker Compose (v2.20+ recommended)
  • Java Development Kit (JDK) 17 & Apache Maven 3.8+
⁠Step-by-Step Deployment Execution

Execute a unified multi-container bootstrap initialization process using specific file declarations or default contexts from the root directory:

# Build and run all 4 services and 4 databases concurrently in detached background mode
docker-compose -f docker-compose.yml up --build -d

# Verify all microservice deployment containers are up and running healthily
docker-compose ps

# Stream centralized runtime telemetry logs
docker-compose logs -f
⁠OpenAPI / Interactive Swagger UI Access Locations

Once the health indicators transition to a stable execution sequence, use your browser to interactively test endpoints:

  • Customer Profile APIs: http://localhost:8081/swagger-ui/index.html
  • Storefront Location Discovery APIs: http://localhost:8082/swagger-ui/index.html
  • Product Menu Catalog APIs: http://localhost:8083/swagger-ui/index.html
  • Notification APIs: http://localhost:8084/
  • Core Order Orchestrator APIs: http://localhost:8080/swagger-ui/index.html ( Padlock Auth Needed πŸ”’ )

β πŸ”„ 6. Complete Process Order Flow Architecture

The sequential interaction between the Mobile Client and the decoupled multi-service nodes during the order lifecycle is orchestrated as follows:

sequenceDiagram
    autonumber
    actor Client as Mobile Client App
    participant OrderSvc as Order Service
    participant CustSvc as Customer Service
    participant ShopSvc as Shop Service
    participant ProductSvc as Product Service
    participant NotificationSvc as Notification Service
    participant OrderDB as PostgreSQL Order DB

    Client->>OrderSvc: POST Create Order Request
    Note over Client,OrderSvc: Payload contains customerId, shopId, items with JWT

    OrderSvc->>CustSvc: GET Validate Customer Identity
    CustSvc-->>OrderSvc: Customer Verified Successfully
    
    OrderSvc->>ShopSvc: GET Validate Shop Location
    ShopSvc-->>OrderSvc: Shop Location Verified Successfully

    Note over OrderSvc,ProductSvc: Loop through each ordered item
    OrderSvc->>ProductSvc: GET Fetch Product Details and Price
    ProductSvc-->>OrderSvc: Returns Price Snapshot and Stock Status
    
    Note over OrderSvc: Compute dynamic Total Amount

    OrderSvc->>OrderDB: Query Least Congested Queue Lane
    OrderDB-->>OrderSvc: Returns Available Queue Details

    alt Condition: All storefront queue lines are full
        OrderSvc-->>Client: Return 400 Bad Request QUEUE_FULL
    else Condition: Target queue has slots available
        Note over OrderSvc: Calculate position index
        
        OrderSvc->>OrderDB: INSERT into orders and order_items
        OrderSvc->>OrderDB: UPDATE queues increment current_size
        OrderDB-->>OrderSvc: Transactional Commit Success

		OrderSvc-->>NotificationSvc: Notify via Kafka about creating order

        OrderSvc-->>Client: Return 201 Created with position and waitTime
    end

    Note over Client,OrderSvc: Optional Cycle: Customer cancels active ticket
    Client->>OrderSvc: POST Cancel Order Request
    OrderSvc->>OrderDB: UPDATE order status to CANCELLED
    OrderSvc->>OrderDB: Shift index values minus one for subsequent nodes
    OrderSvc->>OrderDB: UPDATE queues decrement current_size
    OrderDB-->>OrderSvc: Commit Complete
	OrderSvc-->>NotificationSvc: Notify via Kafka about canceling order
    OrderSvc-->>Client: Return 200 OK

⁠πŸ§ͺ 7. Automated End-to-End (E2E) Integration Testing

To evaluate the cross-network functionality of all 4 independent standalone microservices, an automated end-to-end integration test script is engineered using Python.

This pipeline acts as a full black-box validator executing the following distributed workflow synchronously:

  1. Customer Registration: Onboards a new user dynamically via the customer-service node.
  2. Spatial Geolocation Discovery: Queries the shop-service to discover nearby storefront nodes based on Haversine coordinates.
  3. Menu Profiling: Fetches the available product catalog matrix tailored for that distinct shop from the product-service.
  4. Order Processing & Queue Balancing: Submits a complex nested multi-item basket to the order-service to trigger runtime entity cross-checks and auto-allocate the optimal pending line lane.
  5. Live Telemetry Polling: Tracks the ticket state and live queue indexes.
  6. Transactional Cascade Index Shifting: Triggers a ticket cancellation routine to verify the row-indexing math and shift forward (position_in_queue) of subsequent customer positions.
β πŸ“‹ Testing Subsystem Prerequisites

Ensure your local host machine has Python 3 installed along with the required HTTP networking package wrapper:

pip install requests
β πŸš€ Executing the Integration Script

Once the multi-container Docker Compose matrix is fully stabilized (docker-compose ps indicates healthy/started states), fire the automation runner from your project console:

python e2e_test.py
β πŸ“Š Expected Terminal Execution Report

Upon a successful execution cycle, the automated integration test script outputs a clean, unified telemetry diagnostic trace inside your terminal window:

======================================================================
[STEP 1] Testing Customer Registration API...
βœ… Success! Customer Registered ID: d290f1d6-4444-4b51-8b2d-111122223333

[STEP 2] Testing Nearby Shop Discovery (Spatial Geolocation)...
βœ… Success! Found 100 shops nearby. Closest Shop ID: 8f7e6d5c-4b3a-2a1b-0c9d-8e7f6a5b4c3d

[STEP 3] Fetching Menu Catalog Profile for the selected storefront...
βœ… Success! Found 4 items. Selected Product Variant ID: 1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d

[STEP 4] Submitting multi-item order request to assign optimum queue line lane...
βœ… Success! Ticket generated ID: fe3d2c1b-0a9b-8c7d-6e5f-4a3b2c1d0e9f
   Current Assigned Position in Queue: #1
   Calculated Waiting Telemetry: 3 minutes

[STEP 5] Checking real-time line position tracking metrics...
βœ… Success! Live Status: PENDING | Position: #1

[STEP 6] Executing customer ticket cancellation request to optimize queue indices...
βœ… Success! Response Message: Order cancelled and shifted line indices successfully.
======================================================================
πŸŽ‰ CONGRATULATIONS! ALL MICROSERVICES INTEGRATION SCENARIOS PASSED!
======================================================================

β πŸ”„ 8. Event-Driven Notification System Flow Architecture

To decouple heavy notification logic (e.g., triggering external Firebase Push APIs or SMS Gateways) from the core order checkout thread, an Event-Driven Architecture (EDA) is implemented using Apache Kafka. This design handles message passing asynchronously, reducing system latency and ensuring high availability.

β πŸ“ Message Broker Topology
    [ Mobile Client App ]
             β”‚
             β–Ό (POST /cancel Order Execution)
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚          Core Order Service            β”‚ -> Commits state changes to PostgreSQL Order DB
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -> Non-blocking event payload production
             β”‚
             β–Ό (Asynchronous Publish to Topic: "queue-events")
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚     Apache Kafka Message Broker        β”‚ -> Guards message persistence and transaction logs
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
             β”‚
             β–Ό (Asynchronous Concurrent Stream Consumption)
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚       Notification Microservice        β”‚ -> Decodes incoming structural event tokens
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -> Issues live advanced queue push telemetry updates
             β”‚
             β–Ό
    [ Real-Time Push Notification / SMS Gateway ]
β πŸ“‹ Event Transaction Sequence Lifecycle
  1. User Withdrawal Ingress: A client issues a POST /cancel request to the order-service to void their active ticket mid-line.
  2. Dynamic Position Re-Indexing: The database engine runs an atomic cascading query to shift the position indexes (position_in_queue = position_in_queue - 1) for all subsequent records matching that specific queue path.
  3. Async Event Generation: For each impacted user whose place was advanced, the order-service non-blockingly packages a metadata payload entity (QueueShiftEvent) containing the customerId, orderId, and newPosition.
  4. Broker Event Queuing: The event payloads are dispatched as a decoupled batch to the centralized Kafka broker cluster under the partition topic queue-events.
  5. Decoupled Stream Processing: The notification-service acts as a cluster consumer daemon, continuously pooling incoming messages off the broker stack via specified consumer groups.
  6. Delivery Execution: The consumed JSON telemetry string is deserialized back into a native Java Record profile, instantly triggering the network transmission routines to notify advanced queue clients (e.g., "Your position inside the line has been advanced to #2").

⁠☸️ 9. Kubernetes Enterprise Orchestration Specification (Production K8s)

To scale the coffee placement platform linearly across multi-region production clusters, the entire ecosystem is engineered as decentralized Kubernetes resources. Each microservice follows a Component-based separation of concerns pattern, enforced with decoupled networking, resource throttling limits, and automated health synchronization boundaries.

β πŸ“‚ 1. K8s Directory Component Layout

Ensure your deployment resources are unzipped or organized inside a central folder named k8s/ at your repository root context:

k8s/
β”œβ”€β”€ kafka-infrastructure.yml   	# Distributed Event Broker Engine Manifest
β”œβ”€β”€ databases.yml          		# Multi-tenant isolated PostgreSQL persistence modules
β”œβ”€β”€ customer-service.yml       	# Isolated Customer Registry Pods & Cluster IP
β”œβ”€β”€ shop-service.yml           	# Isolated Storefront Registry Pods & Cluster IP
β”œβ”€β”€ product-service.yml        	# Isolated Menu Catalog Pods & Cluster IP
β”œβ”€β”€ order-service.yml          	# Core Orchestrator Pods with InitContainer hooks
β”œβ”€β”€ notification-service.yml   	# Decoupled Async Event Consumer Task Pods
└── ingress-routing.yml        	# External Ingress Nginx API Controller Gateway
⁠⛓️ 2. Resilient Lifecycle Synchronization (Zero-Downtime Dependency Patterns)

Since Kubernetes bypasses the static constraints of Docker Compose (depends_on), legacy microservice clusters often crash during startup if databases or sibling nodes are booting up slowly.

To achieve a bulletproof deployment order, the platform enforces two core synchronization layers:

  • H hαΊ‘ tαΊ§ng Level Isolation (InitContainers): Core orchestrator pods (e.g., order-service) deploy a minimal background busybox probe running loop checks (until nc -z -w 2 <host> <port>). The main Spring Boot application container is strictly locked from initializing until all target network sockets are fully open.
  • Application Level Isolation (ReadinessProbes): Service discovery blocks poll Spring Boot Actuator paths /actuator/health every 10 seconds. Kubernetes will withhold traffic routing to a newly deployed pod until its local CommandLineRunner has safely completed the automated schema synchronization and database seeding cycles.
β πŸš€ 3. Pipeline Deployment Execution Sequence

Navigate to your repository workspace console terminal, connect to your active Kubernetes Cluster context (Minikube, EKS, or GKE), and execute the sequential lifecycle deployment applies:

# Step 1: Provision Core Infrastructure Fabrics (Databases & Event Mesh)
kubectl apply -f k8s/databases.yml
kubectl apply -f k8s/kafka-infrastructure.yml

# Step 2: Spin Up Decentralized Auxiliary Microservice Components
kubectl apply -f k8s/customer-service.yml
kubectl apply -f k8s/shop-service.yml
kubectl apply -f k8s/product-service.yml
kubectl apply -f k8s/notification-service.yml
kubectl apply -f k8s/order-service.yml

# Step 3: Initialize Central Core Engine & Ingress Routing Gateway
kubectl apply -f k8s/ingress-routing.yml
β πŸ” 4. Cluster Telemetry Validation & Verification Traces
⁠Track Active Pod Initialization Sequences

Verify all distributed persistence nodes and microservice pods shift out of Init: states and transition cleanly into the Running (1/1 Ready) parameter state boundary:

kubectl get pods -w
⁠Evaluate Automated Data Seeding Logs

Since the architecture relies on Application-Driven Idempotent Seeding, confirm that cluster nodes have independently negotiated creation tokens without loading volume raw SQL assets:

# Inspect automated database creation and 100-shop geolocated data seed cycles
kubectl logs deployment/shop-service --tail=40

# Inspect automatic multi-lane storefront queue generation triggers
kubectl logs deployment/order-service --tail=40
⁠Public Ingress Perimeter Inspection

Retrieve the public IP address allocated by your cloud load balancer provider or Ingress Controller gateway to test live endpoints through your Postman/cURL script collections:

kubectl get ingress ingress-routing

Tip

### πŸ’‘ Core Rule to Avoid Future Confusion
  • When running with Docker Compose (Local Machine or Production Environment): Containers share an isolated, internal Docker virtual network. Therefore, you must use the service name as the hostname (e.g., postgres://progres-db:5432).
  • When running commands directly from a GitHub Actions Workflow: Commands execute directly on the host runner (outside the container network) and communicate through mapped ports. Consequently, all backing services (postgres, redis, mongodb, etc.) must be accessed via localhost.

Tag summary

Content type

Image

Digest

sha256:8a9ba6815…

Size

141.8 MB

Last updated

5 months ago

docker pull hainguyen81/shops.order-service