Core distributed microservice micro-engine [customer-service] built by GitHub Actions workflow execu
398
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).
The ecosystem is split into four standalone, business-bounded microservices:
customer-service (Port 8081): Manages onboarding workflows and customer profile registries.shop-service (Port 8082): Coordinates storefront configurations and maps regional geolocations via high-performance spatial queries.product-service (Port 8083): Manages decentralized item catalogs and dynamically localized pricing models.order-service (Port 8080): The core transaction engine managing dynamic line indexing sequences, ticket lifecycles, nested basket checkout validations, and queue balancing algorithms.position_in_queue) of all subsequent records forward in a single atomic transaction.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
The platform architecture implements a Defense-in-Depth structural security layout spanning both application code domains and cloud network fabrics:
Authorization: Bearer <token> request header.${JWT_SECRET} injected via environment context variables rather than static project asset files.bearerAuth security requirement schema, rendering a native "Authorize" padlock window inside the Swagger UI panel.443 (HTTPS).To handle real-time debugging across network boundaries, the platform enforces automated telemetry generation:
Trace ID across multi-hop inter-service calls.2026-06-11 14:15:02.450 | INFO | [order-service,a7b8c9d0e1f2a3b4,f9e8d7c6b5a43u2y] | c.i.o.s.OrderService : Processing order checkout....log.gz archives on the host machine once files touch a 10MB limit, keeping a strict 7-day historical retention cap.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
Once the health indicators transition to a stable execution sequence, use your browser to interactively test endpoints:
http://localhost:8081/swagger-ui/index.htmlhttp://localhost:8082/swagger-ui/index.htmlhttp://localhost:8083/swagger-ui/index.htmlhttp://localhost:8084/http://localhost:8080/swagger-ui/index.html ( Padlock Auth Needed π )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
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:
customer-service node.shop-service to discover nearby storefront nodes based on Haversine coordinates.product-service.order-service to trigger runtime entity cross-checks and auto-allocate the optimal pending line lane.position_in_queue) of subsequent customer positions.Ensure your local host machine has Python 3 installed along with the required HTTP networking package wrapper:
pip install requests
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
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!
======================================================================
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.
[ 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 ]
POST /cancel request to the order-service to void their active ticket mid-line.position_in_queue = position_in_queue - 1) for all subsequent records matching that specific queue path.order-service non-blockingly packages a metadata payload entity (QueueShiftEvent) containing the customerId, orderId, and newPosition.queue-events.notification-service acts as a cluster consumer daemon, continuously pooling incoming messages off the broker stack via specified consumer groups.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.
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
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:
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./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.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
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
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
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 vialocalhost.
Content type
Image
Digest
sha256:5c363d0afβ¦
Size
127.3 MB
Last updated
5 months ago
docker pull hainguyen81/shops.customer-service