| Requirement | Mechanism | Verification |
|---|---|---|
Load balancer |
Nginx round-robin | /whoami alternates instances |
API |
Spring Cloud Gateway | all traffic via :8000 |
Multiple instances |
event-service-1/-2 | both healthy, both serve |
Async communication |
RabbitMQ topic exchange | order.confirmed -> notification |
Concurrency control |
atomic DB UPDATE | 2nd reserve on qty=1 -> 409 |
Resilience |
Resilience4j CB+retry | breaker opens at failureRate=1.0 |
Idempotency |
gateway key + consumer PK + status guard | kill-test: one charge/ticket/email |
Observability |
JSON logs + Prometheus + Grafana | dashboard panels + structured logs |
Mocked payment/email |
standalone mock + log/DB notification | admin/mode flips, /notifications |
docker compose up --build
curl http://localhost:8000/whoami
curl http://localhost:8000/whoami
curl -X POST http://localhost:8000/users -H "Content-Type: application/json" -d "{\"email\":\"leo@test.com\",\"name\":\"Leonardo\"}"
curl -X POST http://localhost:8000/events -H "Content-Type: application/json" -d "{\"name\":\"Show D\",\"eventDate\":\"2026-11-01T20:00:00\",\"price\":120.00,\"availableQuantity\":3}"
curl http://localhost:8000/events
curl -X POST http://localhost:8000/orders -H "Content-Type: application/json" -d "{\"userId\":1,\"eventId\":1}"
curl -X POST http://localhost:8000/orders/1/pay -H "Content-Type: application/json" -d "{\"paymentMethod\":\"CREDIT_CARD\",\"amount\":120.00}"
curl http://localhost:8000/notifications
100% failure
curl -X POST http://localhost:8090/admin/mode -H "Content-Type: application/json" -d "{\"failureRate\":1.0}"
watch retries then breaker opening in logs
curl -X POST http://localhost:8000/orders/1/pay -H "Content-Type: application/json" -d "{\"paymentMethod\":\"CREDIT_CARD\",\"amount\":120.00}"
recover
curl -X POST http://localhost:8090/admin/mode -H "Content-Type: application/json" -d "{\"failureRate\":0.0}"
curl -X POST http://localhost:8000/events -H "Content-Type: application/json" -d "{\"name\":\"Soldout\",\"eventDate\":\"2026-12-01T20:00:00\",\"price\":50.00,\"availableQuantity\":1}"
curl -X POST http://localhost:8000/orders -H "Content-Type: application/json" -d "{\"userId\":1,\"eventId\":1}"
curl -X POST http://localhost:8000/orders -H "Content-Type: application/json" -d "{\"userId\":1,\"eventId\":1}"
http://localhost:8000 -> API Gateway (all app traffic)
http://localhost:9090/targets -> Prometheus (confirm all targets UP)
http://localhost:3000 -> Grafana (admin/admin)
http://localhost:15672 -> RabbitMQ management (tickets/tickets)
docker compose psㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ ㅤ# status of all containers
docker compose logs -f order-serviceㅤ ㅤㅤ# follow one service's logs
docker compose logs -f payment-gateway-mock
docker compose downㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ # stop everything
docker compose down -vㅤㅤㅤㅤㅤㅤㅤ ㅤ ㅤ # stop + wipe volumes (fresh DB)
Grafana -> Dashboards -> New -> Add visualization -> Select Prometheus -> Paste The Query -> Set a Title -> Apply
rate(http_server_requests_seconds_count[1m])
histogram_quantile(0.95, rate(http_server_requests_seconds_bucket[1m]))
rate(http_server_requests_seconds_count{status=~"5.."}[1m])
tickets_sold_total