Skip to main content

Visla GPS Backend: Complete Data Flow & Communication Analysis

This document provides a comprehensive mapping of all data flows, APIs, protocols, sockets, and communication patterns in the Java monolithic backend (backend.vislagps.com).


πŸ“‹ Table of Contents​

  1. System Architecture
  2. External Access Layer (Nginx Gateway)
  3. Real-time & Device Layer
  4. REST API Inventory
  5. Data Forwarding & Integration Layer
  6. Notificators & External Services
  7. Database Schema
  8. Complete Data Flow Summary

1. πŸ—οΈ System Architecture​

The system is divided into two main communication layers: the HTTP Layer for user applications and the TCP/UDP Layer for GPS devices.

High-Level Architecture Diagram​

                            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ INTERNET β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ β”‚
β–Ό β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Web/Mobile Apps β”‚ β”‚ GPS Devices β”‚
β”‚ (HTTPS/WSS + JWT) β”‚ β”‚ (TCP/UDP :5000+) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚ β”‚
β–Ό β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Nginx Gateway β”‚ β”‚ Java Device Gateway β”‚
β”‚ (Port 443) β”‚ β”‚(backend.vislagps.com)β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚ β”‚
β”‚ ALL requests β”‚ Decode Protocol
β”‚ (HTTP + WebSocket) β”‚
β–Ό β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Unified Auth Flow β”‚ β”‚ Position Handler β”‚
β”‚ β”‚ β”‚ β”‚
β”‚ 1. auth_request to β”‚ β”‚ β€’ Parse Protocol β”‚
β”‚ /auth/validate β”‚ β”‚ β€’ Generate Position β”‚
β”‚ β”‚ β”‚ β€’ Detect Events β”‚
β”‚ 2. Validate JWT β”‚ β”‚ β€’ Trigger Rules β”‚
β”‚ Token β”‚ β”‚ β”‚
β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚ 3. Return 200/401 β”‚ β”‚
β”‚ β”‚ β”‚
β”‚ 4. IF 200: β”‚ β”‚
β”‚ β€’ HTTP API β†’ β”‚ β”‚
β”‚ microservice β”‚ β”‚
β”‚ β€’ WebSocket β†’ β”‚ β”‚
β”‚ upgrade to β”‚ β”‚
β”‚ :8086 β”‚ β”‚
β”‚ β”‚ β”‚
β”‚ 5. IF 401: β”‚ β”‚
β”‚ Reject request β”‚ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ β”‚
β–Ό β–Ό β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ HTTP APIs β”‚ β”‚ WebSocket β”‚ β”‚
β”‚ (after auth) β”‚ β”‚ (after auth) β”‚ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β–Ό β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ Microservices β”‚ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
β”‚ β”‚ Auth :8081 β”‚ β”‚ β”‚
β”‚ β”‚ Device :8082 β”‚ β”‚ β”‚
β”‚ β”‚ Docs :8090 β”‚ β”‚ (dev only) β”‚
β”‚ β”‚ Tracking :8083 β”‚ β”‚ β”‚ β”‚
β”‚ β”‚ Command :8084 β”‚ β”‚ β”‚
β”‚ β”‚ Notif :8085 β”‚ β”‚ β”‚
β”‚ β”‚ Report:8086 │◄─┼────WebSocket───────────┼─────┐
β”‚ β”‚ Config :8087 β”‚ β”‚ (persistent) β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
β”‚ β”‚ β”‚
β”‚ β”‚ β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”
β”‚ β”‚
β–Ό β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ MySQL Database β”‚ β”‚ Redis Instance β”‚
β”‚ β”‚ β”‚ β”‚
β”‚ β€’ positions β”‚ β”‚ β€’ JWT Cache β”‚
β”‚ β€’ events β”‚ β”‚ β€’ Pub/Sub β”‚
β”‚ β€’ devices β”‚ β”‚ - positions β”‚
β”‚ β€’ users β”‚ β”‚ - events β”‚
β”‚ β€’ permissions β”‚ β”‚ - devices β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β”‚ Subscribe
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Notification Service β”‚
β”‚ (Port 8086) β”‚
β”‚ β”‚
β”‚ β€’ Subscribe to Redis β”‚
β”‚ β€’ WebSocket Server β”‚
β”‚ β€’ Push Notifications β”‚
β”‚ β€’ Email/Phone β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ DATA FLOWS β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ [1] HTTP API Flow (Web/Mobile β†’ Microservices) β”‚
β”‚ Client (JWT) β†’ Nginx β†’ /auth/validate β†’ 200 OK β†’ Microservice β”‚
β”‚ β”‚
β”‚ [2] WebSocket Flow (Web/Mobile β†’ Notification Service) β”‚
β”‚ Client (JWT) β†’ Nginx β†’ /auth/validate β†’ 200 OK β†’ WS Upgrade :8086 β”‚
β”‚ β†’ Notification Service establishes persistent WebSocket connection β”‚
β”‚ Note: Auth happens ONCE during handshake, then connection stays open β”‚
β”‚ β”‚
β”‚ [3] Device Ingestion Flow (GPS β†’ Backend) β”‚
β”‚ Device β†’ Java Gateway β†’ MySQL + Redis Pub/Sub + Forwarder β”‚
β”‚ β”‚
β”‚ [4] Real-time Notification Flow (Backend β†’ Client) β”‚
β”‚ Redis Pub/Sub β†’ Notification Service β†’ WebSocket β†’ Client β”‚
β”‚ β”‚
β”‚ [5] Authentication Flow (Login) β”‚
β”‚ Client β†’ Nginx β†’ Auth Service β†’ MySQL β†’ JWT Token β†’ Client β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

2. 🌐 External Access Layer (Nginx Gateway)​

The Nginx Gateway is the only entry point for HTTP/WebSocket traffic. It handles SSL termination, CORS, and routing.

Routing Table​

Path PrefixTarget ServicePortNotes
/api/swaggerSwagger Service8090Unified Swagger UI (dev only)
/api/auth/*Auth Service8081Identity, JWT Auth, OAuth
/api/socketNotification Service8086WebSocket Upgrade
/api/devices, /api/groupsdevice Service8082Asset Management
/api/positions, /api/eventsTracking Service8083Historical Data
/api/commandsCommand Service8084Device Control
/api/reports, /api/statisticsReport Service8085Analytics
/api/notificationsNotification Service8086Rules & Alerts
/api/server, /api/attributesConfig Service8087System Settings

Authentication Flow (Nginx auth_request)​

Nginx performs an internal subrequest to validate ALL requests (both HTTP and WebSocket) before forwarding them to a microservice.

Unified Authentication:

  • HTTP APIs: Validated via auth_request, then forwarded to microservice
  • WebSocket: Validated via auth_request, then upgraded to WebSocket (if valid)
  • Authentication: JWT access token only (stateless, no sessions)
1. Client β†’ Nginx (Request + JWT Access Token in Authorization header)
2. Nginx β†’ Auth Service (/api/auth/validate)
3. Auth Service validates JWT β†’ Returns 200/401/403
4a. HTTP API: Nginx forwards to Target Service (if 200)
4b. WebSocket: Nginx upgrades to WebSocket on :8086 (if 200)
5. If 401/403: Nginx returns Error to client

3. πŸ“‘ Real-time & Device Layer​

This layer handles the high-frequency data ingestion from devices and real-time updates to clients.

A. Device Communication (Java Gateway)​

The Java Gateway (backend.vislagps.com) acts as the Protocol Translator. It listens on specific ports, decodes proprietary GPS protocols into standardized data, and ingests it into the system.

Supported Protocols & Ports: Note: A protocol is only active if configured in traccar.xml.

ProtocolPortModel MapDescription
s21l5052S21LDedicated Huabao for S21L
g11lse5058G11L-SEDedicated GT06 for G11L-SE
c0595059C059Dedicated P5 for C059
p55054P5Dedicated Huabao for P5

B. Real-time Data Flow (The "Live" Loop)​

This flow explains how a position moves from a device to a user's screen in milliseconds.

1. Ingestion
Device -> [TCP/UDP Port] -> Java Gateway
Java Gateway decodes binary data -> Standardized Position Object

2. Broadcasting (Internal)
Java Gateway -> Redis Stream (Channel: "positions")
Java Gateway -> PSQL (Persistence)

3. Delivery (WebSocket)
Redis -> Notification Service (Subscribed to "positions")
Notification Service -> WebSocket Client (User)

C. WebSocket Protocol (/api/socket)​

Connection:

  • Endpoint: wss://backend.vislagps.com/api/socket or ws://localhost:8086/api/socket
  • Handled by: Notification Service (Port 8086)
  • Routing: Nginx Gateway β†’ /auth/validate (JWT validation) β†’ Notification Service :8086
  • Authentication: JWT token validated by Auth Service via auth_request before WebSocket upgrade
  • Protocol: After successful auth, HTTP upgrades to persistent WebSocket connection

Messages Sent to Client:

{
"positions": [{ ... }],
"devices": [{ ... }],
"events": [{ ... }],
"logs": [{ ... }]
}

Messages Received from Client:

{
"logs": true // Enable/disable log streaming
}

Keepalive:

  • Server sends empty {} messages every N seconds
  • Client should respond or maintain connection

4. πŸ“¦ REST API Inventory​

πŸ…°οΈ Auth Service (Port 8081)​

FastAPI-based service responsible for identity, access control, and JWT authentication.

Base path: /api/auth

EndpointMethodAuth RequiredDescription
/api/auth/loginPOST❌Login with email/password. Returns access token (15-min) + refresh token (30-day).
/api/auth/registerPOST❌Register new user (requires terms consent, sends verification email).
/api/auth/verifyPOST❌Verify email with token from registration email.
/api/auth/resend-verificationPOST❌Resend verification email (if not received).
/api/auth/profileGETβœ…Get current authenticated user info from JWT.
/api/auth/logoutDELETEβœ…Logout (revoke all refresh tokens for user).
/api/auth/refreshPOST❌Exchange refresh token for new access token.
/api/auth/validateGET❌Internal JWT validation endpoint (used by Nginx auth_request).
/api/auth/healthGET❌Health check (database connectivity).
/api/auth/deletePOSTβœ…Delete user account (immediate token invalidation).
/api/auth/openid/authGET❌Initiate OAuth flow (Google/Facebook/Apple).
/api/auth/openid/callbackGET/POST❌OAuth callback handler (receives code, returns tokens).
/api/auth/openid/tokenPOST❌Mobile OAuth token exchange (native SDK β†’ JWT tokens).
/api/auth/password/resetPOST❌Request password reset email.
/api/auth/password/updatePOST❌Update password using reset token.
/api/auth/2fa/setupPOSTβœ…Generate TOTP secret and QR code.
/api/auth/2fa/verifyPOSTβœ…Verify TOTP code to enable 2FA.
/api/auth/2fa/disablePOSTβœ…Disable 2FA (requires password).
/api/auth/2fa/backup-codesPOSTβœ…Generate new backup codes.

Authentication:

  • Type: JWT-based (stateless)
  • Access Token: 15-minute expiration, signed with RSA private key
  • Refresh Token: 30-day expiration, stored in database, revocable
  • Token Blacklist: On logout, access tokens are blacklisted in Redis until expiration
  • Header: Authorization: Bearer <access_token> or Cookie: access_token=<token>

Token Response Format:

{
"access_token": "eyJ...",
"refresh_token": "random-64-char-token",
"token_type": "bearer",
"user": { "id": 1, "email": "...", "administrator": false, ... }
}

πŸ…±οΈ Device Service (Port 8082)​

FastAPI-based service responsible for the static inventory of devices.

Base path: /api/devices

EndpointMethodAuth RequiredDescription
/api/devicesGETβœ…List all devices the user has access to.
/api/devicesPOSTβœ…Register a new device.
/api/devices/{id}GETβœ…Get a single device by ID.
/api/devices/{id}PUTβœ…Update device details (name, group, phone).
/api/devices/{id}DELETEβœ…Delete a device.
/api/devices/claimPOSTβœ…Claim a device using a unique token (QR code).
/api/devices/validate-tokenPOST❌Validate a device claim token (public).
/api/devices/healthGET❌Health check (database connectivity).

πŸ“š Swagger Service (Port 8090)​

Lightweight service providing unified API documentation in development mode.

Base path: /api/swagger

EndpointMethodAuth RequiredDescription
/api/swaggerGET❌Unified Swagger UI with dropdown to select Auth, Device, or Tracking service.
/api/swagger/healthGET❌Health check.

Note: This service only runs when ENVIRONMENT=dev. In production, it returns 404.

πŸ“ Tracking Service (Port 8083)​

Responsible for high-volume dynamic data.

EndpointMethodDescription
/api/positionsGETGet latest positions or history (params: from, to).
/api/eventsGETList system events (overspeed, geofence enter/exit).
/api/events/{id}GETGet details of a specific event.
/api/geofencesGETList geofences.
/api/geofencesPOSTCreate a geofence (Circle/Polygon).
/api/geofences/{id}PUTUpdate geofence area.
/api/geofences/{id}DELETEDelete geofence.

βš™οΈ Command Service (Port 8084)​

Responsible for sending instructions to devices.

EndpointMethodDescription
/api/commandsGETList saved command templates.
/api/commandsPOSTCreate a saved command template.
/api/commands/sendPOSTSend a command immediately to a device.
/api/commands/typesGETGet supported command types for a specific device model.

πŸ”” Notification Service (Port 8086)​

Responsible for alerting users and real-time push.

EndpointMethodDescription
/api/notificationsGETList notification rules.
/api/notificationsPOSTCreate a notification rule (link event -> channel).
/api/notifications/testPOST[NEW] Send a test notification.
/api/notifications/test/{notificator}POST[NEW] Test a specific channel (e.g., 'web', 'mail').
/api/notifications/typesGET[NEW] List available notification types.
/api/notifications/notificatorsGET[NEW] List available notificator backends.
/api/socketGET[NEW] WebSocket endpoint for real-time updates.
/api/push-tokenPOSTRegister a Firebase (FCM) token for mobile push.
/api/push-tokenDELETEUnregister a push token.

5. πŸ’Ύ Data Forwarding & Integration Layer​

The Java backend supports multiple data forwarding mechanisms to integrate with external systems.

Position Forwarding (Outbound)​

Configuration: forward.url and forward.type in traccar.xml

TypeDescriptionImplementation
URL (default)HTTP POST to custom endpointPositionForwarderUrl.java
JSONHTTP POST with JSON payload + device enrichmentPositionForwarderJson.java
AMQPRabbitMQ / AMQP exchange publishPositionForwarderAmqp.java
KafkaApache Kafka topic publishPositionForwarderKafka.java
MQTTMQTT broker publishPositionForwarderMqtt.java
RedisRedis Pub/Sub channelPositionForwarderRedis.java
WialonWialon Hosting IPS protocolPositionForwarderWialon.java

Data Flow:

Device -> Java Gateway -> Position Saved to MySQL
-> Position Forwarded via Selected Protocol

Event Forwarding (Outbound)​

Configuration: event.forward.url and event.forward.type in traccar.xml

TypeDescriptionImplementation
JSON (default)HTTP POST with JSON payloadEventForwarderJson.java
AMQPRabbitMQ / AMQP exchange publishEventForwarderAmqp.java
KafkaApache Kafka topic publishEventForwarderKafka.java
MQTTMQTT broker publishEventForwarderMqtt.java

Data Flow:

Device Event (overspeed, geofence, alarm, etc.)
-> Event Saved to MySQL
-> Event Forwarded via Selected Protocol

Current Configuration (traccar.xml):

<entry key='event.forward.enable'>false</entry>
<entry key='event.forward.url'>http://events:8083/events</entry>
<entry key='event.forward.header'>API-KEY: AIzaSyCnk5s9MO9tVpTUiAY9be_qd0ZTB_jOT0I</entry>

Broadcast Service (Internal Synchronization)​

Configuration: broadcast.type in traccar.xml

TypeDescriptionImplementation
MulticastUDP multicast for same-network clusterMulticastBroadcastService.java
RedisRedis Pub/Sub for distributed clusterRedisBroadcastService.java
Null (default)No broadcasting (single instance)NullBroadcastService.java

Purpose: Synchronize cache updates across multiple backend instances in a cluster.


6. πŸ”” Notificators & External Services​

The Java backend forwards notifications to external microservices for processing.

Available Notificator Channels​

Configuration: notificator.types in traccar.xml

Current active channels:

<entry key='notificator.types'>firebase,web,mailExternal,command,phone</entry>
ChannelDescriptionImplementationExternal Endpoint
firebaseFirebase Cloud Messaging (FCM) pushNotificatorFirebase.javaFirebase API
webWebSocket real-time notificationsNotificatorWeb.javaInternal (ConnectionManager)
mailExternalExternal email service (microservice)NotificatorEmailExternal.javahttp://events:8083/emails
commandSend SMS command to deviceNotificatorCommand.javaInternal
phoneExternal phone call service (microservice)NotificatorPhone.javahttp://events:8083/calls
mailInternal SMTP emailNotificatorMail.javaSMTP server
smsSMS gatewayNotificatorSms.javaSMS provider
telegramTelegram botNotificatorTelegram.javaTelegram API
traccarTraccar cloud serviceNotificatorTraccar.javaTraccar cloud
pushoverPushover serviceNotificatorPushover.javaPushover API

External Microservice Integrations​

A. Phone Call Service (NotificatorPhone)​

Endpoint: http://events:8083/calls Method: POST Authentication: API-KEY: AIzaSyCnk5s9MO9tVpTUiAY9be_qd0ZTB_jOT0I

Payload Format:

{
"phone": "+393931952336",
"userId": 123,
"deviceId": 456,
"eventId": 789,
"eventType": "alarm",
"alarmType": "sos",
"title": "SOS Alert",
"body": "Device ABC triggered SOS alarm",
"deviceName": "Vehicle ABC",
"position": {
"latitude": 41.9028,
"longitude": 12.4964,
"accuracy": 10.0
},
"address": "Via Roma, 123, Roma, Italia"
}

Phone Number Sources:

  • device.attributes.alarmPhones (CSV)
  • device.attributes.alarmPhone1
  • device.attributes.alarmPhone2
  • device.attributes.alarmPhone3

Test Configuration:

<entry key='notificator.phone.testNumber'>3931952336</entry>

B. External Email Service (NotificatorEmailExternal)​

Endpoint: http://events:8083/emails Method: POST Authentication: API-KEY: AIzaSyCnk5s9MO9tVpTUiAY9be_qd0ZTB_jOT0I

Payload Format:

{
"to": "user@example.com",
"subject": "Overspeed Alert",
"text": "Device ABC exceeded speed limit",
"userId": 123,
"deviceId": 456,
"eventId": 789,
"eventType": "deviceOverspeed",
"alarmType": null,
"deviceName": "Vehicle ABC",
"position": {
"latitude": 41.9028,
"longitude": 12.4964,
"accuracy": 10.0
},
"address": "Via Roma, 123, Roma, Italia"
}

Email Recipient Sources:

  • device.attributes.alarmEmails (CSV)
  • device.attributes.alarmEmail1
  • device.attributes.alarmEmail2
  • device.attributes.alarmEmail3
  • Fallback: user.email

Test Configuration:

<entry key='notificator.mailExternal.testEmail'>vislasrls@gmail.com</entry>

C. Log Forwarding (ELK Stack)​

Endpoint: http://logstash:8080/ Method: POST Purpose: Forward client-side logs to Logstash for centralized logging

Configuration:

<entry key='logs.forward.url'>http://logstash:8080/</entry>

Triggered by: /api/logs endpoint


7. πŸ’Ύ Database Schema​

All services share a single MySQL instance but own distinct tables.

Table Ownership​

ServiceTables
Authtc_users, tc_keystore, tc_refresh_tokens
devicedevices, groups, drivers, calendars, maintenances, orders
Trackingpositions, events, geofences
Notificationnotifications, notification_rules
Configserver, attributes, computed_attributes
Java GatewayWrites to positions, events (ReadOnly for others)

Cache & Messaging (Redis)​

Usage:

  • Caching: User sessions, device state, config
  • Pub/Sub: Real-time message bus for inter-service communication
    • Channel: "positions" - Position updates from devices
    • Channel: "devices" - Device metadata updates
    • Channel: "events" - System events

8. πŸ” Complete Data Flow Summary​

Data Flow Diagram​

Complete Data Flows​

1️⃣ Device Position Update (Real-time)​

GPS Device 
β†’ TCP/UDP Port (5000+)
β†’ Protocol Decoder (Java)
β†’ Position Handler
β†’ [PARALLEL]
β”œβ”€ MySQL (positions table)
β”œβ”€ Redis Pub/Sub ("positions" channel)
β”œβ”€ Position Forwarder (if configured)
β”‚ └─ External System (HTTP/Kafka/AMQP/MQTT/Redis/Wialon)
└─ Event Generator (if rules triggered)
β”œβ”€ MySQL (events table)
β”œβ”€ Redis Pub/Sub ("events" channel)
β”œβ”€ Event Forwarder (if configured)
β”‚ └─ External System
└─ Notificators (if rules matched)
β”œβ”€ WebSocket β†’ Client
β”œβ”€ Firebase FCM β†’ Mobile App
β”œβ”€ HTTP β†’ Microservice (phone, email)
└─ SMTP β†’ Email

2️⃣ User Login & Authentication​

Client 
β†’ POST /api/auth/login (email, password)
β†’ Auth Service :8081
β†’ LDAP (if configured) OR MySQL users table
β†’ JWT Access Token Created (15-min expiration)
β†’ JWT Refresh Token Created (30-day, stored in DB)
β†’ Response ({ access_token, refresh_token, user })
β†’ Client stores both tokens

Client (authenticated)
β†’ GET /api/devices (Authorization: Bearer <access_token>)
β†’ Nginx Gateway
β†’ Internal: GET /api/auth/validate (validates JWT)
β†’ Auth Service β†’ Returns 200 OK + userId from JWT
β†’ Nginx β†’ Forward to device Service :8082
β†’ device Service β†’ MySQL devices table
β†’ Response to Client

Client (after 15 minutes, access token expired)
β†’ POST /api/auth/refresh (refresh_token)
β†’ Auth Service :8081
β†’ Validate refresh token from DB
β†’ New access token created
β†’ Response ({ access_token })

3️⃣ WebSocket Real-time Updates​

Client 
β†’ WSS /api/socket (with JWT access token in Authorization header)
β†’ Nginx Gateway :443
β†’ Internal: GET /api/auth/validate (validates JWT)
β†’ Auth Service β†’ Returns 200 OK (userId extracted from JWT)
β†’ Nginx β†’ Upgrades to WebSocket connection to :8086
β†’ Notification Service establishes persistent connection
β†’ ConnectionManager.addListener(userId)

[Device sends position]
β†’ ... (flow #1) ...
β†’ Redis Pub/Sub ("positions")
β†’ Notification Service (subscribed)
β†’ ConnectionManager.onUpdatePosition()
β†’ WebSocket β†’ Client receives JSON (real-time)

4️⃣ Device Command Send​

Client 
β†’ POST /api/commands/send
β†’ Command Service :8084
β†’ Device Command Queue
β†’ Device Gateway
β†’ TCP/UDP Connection to Device
β†’ Device executes command
β†’ Device sends ACK (optional)
β†’ Position update with command result

5️⃣ Notification Flow (Alarm)​

Device sends alarm position
β†’ Protocol Decoder
β†’ Position Handler
β†’ Event Generator detects alarm
β†’ MySQL events table
β†’ Notification Rules Matcher
β†’ User has notification rule: alarm β†’ phone
β†’ NotificatorPhone.send()
β†’ HTTP POST http://events:8083/calls
β†’ External Microservice
β†’ Phone call initiated

6️⃣ OpenID Authentication (Google/Facebook/Apple)​

Client 
β†’ GET /api/auth/openid/auth?provider=google
β†’ OpenIdProvider.getAuthUrl()
β†’ Redirect to https://accounts.google.com/...

User authenticates with Google
β†’ Google redirects to /api/auth/openid/callback?code=...
β†’ OpenIdProvider.processCallback()
β†’ Exchange code for access_token
β†’ Fetch user info from Google
β†’ Create or update user in MySQL
β†’ Generate JWT access token + refresh token
β†’ Redirect to frontend with tokens (URL params or POST message)

Mobile App (native SDK)
β†’ Google SDK β†’ id_token
β†’ POST /api/auth/openid/token (id_token)
β†’ Validate Google token
β†’ Create/find user in MySQL
β†’ Generate JWT access token + refresh token
β†’ Response ({ access_token, refresh_token, user })

7️⃣ Report Generation​

Client 
β†’ GET /api/reports/trips?deviceId=123&from=...&to=...
β†’ Report Service :8085
β†’ MySQL positions table (range query)
β†’ Trip Detection Algorithm
β†’ Response: JSON array of trips

Client
β†’ GET /api/reports/route/xlsx?deviceId=123&from=...&to=...
β†’ Report Service :8085
β†’ Generate Excel file
β†’ Response: File download

9. β˜• Java Backend Internal Data Flow​

This section details the internal lifecycle of a data packet within the Java monolith (backend.vislagps.com), from the socket ingress to the database and Redis.

A. Netty Pipeline (Ingestion)​

Every device protocol (e.g., Teltonika, GT06) runs on a dedicated TCP/UDP port using Netty.

Pipeline Stages:

  1. Frame Decoder: Splits the TCP stream into discrete packets (e.g., by length, delimiter).
  2. String Decoder (Optional): Converts bytes to string if the protocol is text-based.
  3. Protocol Decoder: The core logic. Parses the raw bytes/string into a Position object.
    • Extracts: Latitude, Longitude, Speed, Course, Altitude, Battery, Ignition, etc.
    • Normalizes: Converts vendor-specific status codes into standard attributes.
  4. Position Handler: The main business logic processor.

B. Position Handler Logic​

Once a Position object is created, it passes through PositionHandler (and other handlers like FilterHandler, GeocoderHandler).

Processing Steps:

  1. Filtering: Checks if the position should be discarded (e.g., invalid GPS, duplicate, zero speed).
    • Config: filter.enable, filter.invalid, filter.duplicate
  2. Geocoding: If enabled, fetches address from external provider (Google, LocationIQ).
    • Config: geocoder.enable
  3. Computed Attributes: Calculates virtual attributes based on expressions (e.g., fuel = adc1 * 0.5).
    • Config: processing.computedAttributes.enable
  4. Database Persistence: Saves the position to the tc_positions table in MySQL.
    • Update: Updates the tc_devices table with the latest position ID and status.

C. Data Forwarding & Broadcasting​

After persistence, the position is broadcasted to other systems.

  1. Redis Pub/Sub (Real-time)

    • Channel: positions
    • Payload: JSON representation of the Position object.
    • Purpose: Consumed by the Notification Service to push updates to WebSockets.
    • Implementation: PositionForwarderRedis (configured to use publish).
  2. Event Generation

    • Checks for events: Overspeed, Geofence Entry/Exit, Maintenance.
    • If Event Detected:
      • Saved to tc_events table.
      • Published to Redis channel events.
      • Forwarded to configured Notificators (Firebase, Web, Email, Phone).

D. Java Internal Diagram​


πŸ“ Missing Documentation Checklist​

βœ… Documented:

  • All REST API endpoints (22 resources)
  • WebSocket protocol (/api/socket)
  • TCP/UDP device protocols (16 protocols, ports 5000+)
  • Position forwarding (7 types: URL, JSON, AMQP, Kafka, MQTT, Redis, Wialon)
  • Event forwarding (4 types: JSON, AMQP, Kafka, MQTT)
  • Notificators (10 channels: firebase, web, mailExternal, phone, command, mail, sms, telegram, traccar, pushover)
  • External microservice integrations (phone, email, logs)
  • Redis Pub/Sub channels
  • Broadcast service (Multicast, Redis)
  • Database schema ownership
  • Authentication flows (standard, OpenID)
  • Real-time data flows

βœ… All data flows, APIs, protocols, and sockets are now comprehensively documented.


πŸ”„ Migration Notes​

When migrating from the monolithic Java backend to microservices:

  1. Preserve all protocol decoders - These are critical and not easily replaceable
  2. Maintain Redis Pub/Sub - Essential for real-time WebSocket updates
  3. Keep position/event forwarding - External integrations depend on this
  4. Migrate notificators carefully - Complex business logic for phone/email services
  5. Document all custom device attributes - alarmPhones, alarmEmails, etc.
  6. Test WebSocket protocol - Critical for dashboard real-time updates
  7. Validate all API endpoints - 100+ endpoints across 7 services


Last Updated: 2025-12-08
Status: βœ… Complete - All data flows documented