1. Monitoring & Admin Tools
All tools are accessible via Nginx Proxy Manager (PI1) with SSL. Each tool has a travel-tube.com subdomain.
Tool Overview
| Tool | URL | Host | Purpose |
|---|---|---|---|
| Grafana | grafana.travel-tube.com | PI1:3000 | Dashboards — container metrics, Kafka lag, node health |
| Zipkin | zipkin.travel-tube.com | PI1:9411 | Distributed tracing — follow requests across Gateway → Auth → Member → Kafka |
| Kafdrop | kafka.travel-tube.com | PI1:9000 | Kafka web UI — brokers, topics, partitions, messages, consumer groups |
| Eureka | eureka.travel-tube.com | PI2:8761 | Service discovery — see which service instances are registered and healthy |
| pgAdmin | pgadmin.travel-tube.com | PI1:5050 | PostgreSQL admin — query member data, manage tables |
| Mongo Express | PI1:8081 (internal only) | PI1:8081 | MongoDB admin — browse geospatial collections |
| Nginx Proxy Manager | nginx.travel-tube.com | PI1:81 | Reverse proxy — manage SSL certs, proxy hosts, redirects |
| Portainer (PI1) | portainer.travel-tube.com | PI1:9443 | Docker management — containers, images, volumes, networks |
| Portainer (PI2) | portainer2.travel-tube.com | PI2:9443 | Docker management for PI2 |
| Portainer (PI3) | portainer3.travel-tube.com | PI3:9443 | Docker management for PI3 |
| Jenkins | jenkins.travel-tube.com | PI1:8443 | CI/CD — build pipelines, deploy to Pis |
| Swagger UI | api.travel-tube.com/swagger-ui/index.html | PI2:8030 (via Gateway) | API documentation — interactive endpoint testing |
Prometheus Metrics Stack
Prometheus (PI1) scrapes metrics from all 3 Pis. Data feeds into Grafana dashboards.
| Exporter | Runs On | What It Monitors |
|---|---|---|
| node_exporter | PI1, PI2, PI3 | CPU, memory, disk, network per host |
| cadvisor | PI1, PI2, PI3 | Per-container CPU, memory, I/O |
| kafka-exporter | PI1, PI2, PI3 | Kafka broker metrics, topic lag, consumer group offsets |
Zipkin Distributed Tracing
All Spring services are instrumented with Micrometer + Zipkin. Trace flow:
iOS Client → Gateway → Auth Service → Member Service → PostgreSQL
(traceId propagated via headers)
iOS Client → Gateway → Auth Service → Geospatial Service → Kafka Producer
→ Kafka Consumer → MongoDB
(traceId propagated via Kafka headers)
Zipkin URL: zipkin.travel-tube.com
Kafdrop Cluster View
Kafdrop connects to both brokers via INTERNAL listener:
- Bootstrap servers:
192.168.1.199:19092,192.168.1.105:19092 - Shows: 2 brokers, 2 topics (
__consumer_offsets,adventuretube-data), 52 total partitions - 0 under-replicated partitions = healthy cluster
2. API Documentation (Swagger / OpenAPI 3.1)
All services expose OpenAPI specs at /v3/api-docs. Swagger UI available at:
https://api.travel-tube.com/swagger-ui/index.html (select service from dropdown)
Auth Service — api.travel-tube.com/auth-service
The main entry point for all authenticated operations. Auth Service has no database — it proxies requests to Member Service and Geospatial Service.
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /auth/users |
Register new user — creates member + issues JWT tokens | No |
| DELETE | /auth/users |
Delete user and all associated tokens | Yes |
| POST | /auth/token |
Login — authenticate with email/password or Google ID token | No |
| POST | /auth/token/refresh |
Refresh access token using valid refresh token | Bearer {refresh_token} |
| POST | /auth/token/revoke |
Logout — revoke refresh token | Bearer {refresh_token} |
| POST | /auth/adventuretubedata |
Create AdventureTubeData — injects ownerEmail from JWT, forwards to Geospatial Service via Kafka | Bearer {access_token} |
| DELETE | /auth/adventuretubedata/{youtubeContentId} |
Delete AdventureTubeData by YouTube content ID | Bearer {access_token} |
Key Request/Response Types:
MemberRegisterRequest: email, password, username, role (required); googleIdToken, refreshToken, channelId (optional)MemberLoginRequest: email, password (required); googleIdToken (optional)MemberLoginResponse: accessToken, refreshToken, tokenType, expiresInServiceResponse<T>: success, message, errorCode, data, timestamp
Member Service — api.travel-tube.com/member-service
Internal service — called by Auth Service, not directly by clients. Manages user data in PostgreSQL.
| Method | Endpoint | Description |
|---|---|---|
| POST | /member/registerMember |
Create new member record in PostgreSQL |
| POST | /member/findMemberByEmail |
Look up member by email address |
| POST | /member/emailDuplicationCheck |
Check if email already registered |
| POST | /member/storeTokens |
Store refresh token for a user |
| POST | /member/findToken |
Verify if a refresh token exists |
| POST | /member/deleteAllToken |
Delete all tokens for a user (logout) |
| POST | /member/deleteUser |
Delete user and all associated data |
All endpoints return ServiceResponse<T>. Security: Bearer JWT.
Geospatial Service — api.travel-tube.com/geo-service
Manages AdventureTubeData in MongoDB. Produces/consumes Kafka messages for async data processing.
| Method | Endpoint | Description |
|---|---|---|
| GET | /geo/data |
Get all adventure data records |
| GET | /geo/data/{id} |
Get record by MongoDB ID |
| GET | /geo/data/youtube/{youtubeContentID} |
Get record by YouTube content ID |
| GET | /geo/data/type/{contentType} |
Filter records by content type |
| GET | /geo/data/category/{category} |
Filter records by category |
| GET | /geo/data/count |
Get total record count |
| POST | /geo/save |
Save new record — publishes to Kafka topic adventuretube-data |
| PUT | /geo/data/{id} |
Update existing record |
| DELETE | /geo/data/{id} |
Delete record by ID |
| DELETE | /geo/data/delete/adventuretubedata |
Delete by youtubeContentId + ownerEmail (query params) |
Security: Bearer JWT.
Web Service — api.travel-tube.com/web-service
Public read-only proxy to Geospatial Service. No authentication required. Used by the web frontend.
| Method | Endpoint | Description |
|---|---|---|
| GET | /web/geo/data |
Get all adventure data |
| GET | /web/geo/data/{id} |
Get record by ID |
| GET | /web/geo/data/youtube/{youtubeContentID} |
Get record by YouTube content ID |
| GET | /web/geo/data/type/{contentType} |
Filter by content type |
| GET | /web/geo/data/category/{category} |
Filter by category |
| GET | /web/geo/data/count |
Get total count |
All endpoints return ServiceResponse<JsonNode>. No authentication required.
3. API Request Flow
Authenticated Flow (iOS Client)
iOS → Gateway :8030 → Auth Service :8010
│ │
│ JWT validated │ calls via WebClient
│ by Gateway v
│ Member Service :8070 → PostgreSQL
│ │
│ v
│ Geospatial Service :8060 → Kafka → MongoDB
Public Flow (Web Frontend)
Browser → Gateway :8030 → Web Service :8040
│
│ calls via ServiceClient (WebClient)
v
Geospatial Service :8060 → MongoDB
Token Lifecycle
- Register:
POST /auth/users→ returns accessToken + refreshToken - Login:
POST /auth/token→ returns accessToken + refreshToken - Use API: Include
Authorization: Bearer {accessToken}in requests - Refresh: When accessToken expires, call
POST /auth/token/refreshwith refreshToken - Logout:
POST /auth/token/revoke→ deletes refreshToken from store
