FleetPulse

Luglio 2026 — in corso

Tecnologie principali

FleetPulse è un progetto personale che uso per approfondire sviluppo backend, networking, concorrenza e sistemi distribuiti. Simula la raccolta della telemetria di una flotta di veicoli, senza utilizzare dati reali o protocolli automotive proprietari.

Nel repository pubblico raccolgo il codice, le scelte architetturali, i contratti tra i servizi e i relativi test.

Architettura

FleetPulse è diviso in servizi con responsabilità diverse. Il gateway si occupa delle connessioni TCP, Kafka fa da coda tra acquisizione ed elaborazione, il processor applica le regole e aggiorna i dati, mentre Fleet API è il punto di accesso per dashboard e client esterni.

Nel diagramma è rappresentato il progetto completo. Le frecce continue indicano le parti già implementate, quelle tratteggiate ciò che deve ancora essere completato.

Architettura e flusso applicativo di FleetPulse

PostgreSQL conserva veicoli, storico della telemetria e alert. Redis mantiene invece l'ultima rilevazione di ogni veicolo, così da rendere più veloce la consultazione dello stato corrente. Se Redis non è disponibile, Fleet API può ricostruire la risposta partendo dallo storico in PostgreSQL.

Protocollo TCP

Il protocollo applicativo utilizza framing length-prefixed:

4 byte payload length, big-endian
+
JSON UTF-8 payload

La libreria condivisa tcp-protocol contiene il framing e le costanti usate sia dal gateway sia dal simulator.

Il gateway mantiene connessioni persistenti e gestisce più client in parallelo tramite virtual threads. Un Semaphore limita il numero di connessioni attive; sono presenti anche timeout di lettura e arresto controllato delle connessioni ancora aperte.

Dopo la validazione, il gateway converte il messaggio in un TelemetryEvent e lo pubblica su Kafka usando l'ID del veicolo come chiave. In questo modo gli eventi dello stesso veicolo restano ordinati. Il gateway invia l'ACK ACCEPTED solo dopo la conferma del broker; in caso di timeout o errore di pubblicazione invia invece un NACK. La lettura degli ACK da parte del simulator non è ancora collegata al suo ciclo di invio.

Fleet API

La Fleet API espone le operazioni REST di gestione della flotta e utilizza Spring Boot, JPA/Hibernate, PostgreSQL e Flyway.

Le richieste vengono validate e gli errori applicativi o di database restituiscono risposte coerenti. I vincoli principali sono applicati anche a livello di schema.

Vehicle Simulator

Il simulator è un'applicazione Spring Boot senza server web. Crea e recupera i veicoli tramite Fleet API, senza accedere direttamente al database.

I veicoli usano codici prevedibili, da FP-SIM-001 in poi. A ogni avvio il simulator recupera quelli già presenti e crea solo quelli mancanti; gestisce anche il caso in cui due istanze provino a creare lo stesso veicolo contemporaneamente.

Ogni veicolo mantiene il proprio stato e genera campioni con profilo NORMAL, numero di sequenza crescente e ID univoco. La connessione TCP resta aperta tra un invio e l'altro e, se cade, il client prova a ristabilirla aumentando gradualmente l'attesa tra i tentativi.

Telemetry Processor

Il processor legge gli eventi da telemetry.raw.v1, controlla che il veicolo esista e sia attivo e salva il campione in PostgreSQL. Dopo il salvataggio aggiorna lo stato corrente in Redis e valuta le regole di manutenzione, per esempio una temperatura del motore troppo alta o il raggiungimento della soglia chilometrica del tagliando.

Sample e alert vengono salvati nella stessa transazione. Ogni alert mantiene tipo, severità e stato; il flusso previsto consente di passare da OPEN ad ACKNOWLEDGED e infine a CLOSED. Redis non è la fonte principale dei dati: può essere svuotato e ricostruito dallo storico.

La consegna Kafka è at-least-once. L'offset viene confermato solo al termine dell'elaborazione e il messageId impedisce che una riconsegna generi due campioni. Anche gli alert sono protetti dai duplicati tramite la coppia composta dal messaggio sorgente e dal tipo di alert.

Gli errori temporanei vengono ritentati con attese progressivamente più lunghe. Gli eventi relativi a veicoli sconosciuti o disabilitati finiscono su telemetry.rejected.v1; i messaggi non leggibili o ancora in errore dopo tutti i tentativi vengono pubblicati su telemetry.dead-letter.v1. Prima di confermare l'offset originale, il processor aspetta che Kafka abbia ricevuto anche questi eventi.

Consultazione della flotta

Fleet API raccoglie tutte le funzioni usate dagli operatori e dai client esterni. Oltre alla registrazione e all'abilitazione dei veicoli, il progetto prevede endpoint per:

Il Fleet Dashboard usa soltanto queste API. Mostra il numero e lo stato dei veicoli, quelli che hanno trasmesso di recente, gli alert aperti e il dettaglio della telemetria. I dati vengono aggiornati periodicamente tramite chiamate REST; il frontend non accede direttamente a Kafka, PostgreSQL o Redis.

Osservabilità e avvio locale

Gateway, processor e Fleet API espongono health check e metriche. Prometheus raccoglie dati come connessioni attive, frame rifiutati, tempi di pubblicazione, duplicati, retry e latenza di elaborazione; Grafana è riservato al monitoraggio tecnico e rimane separato dalla dashboard usata dagli operatori.

L'intera topologia locale è descritta con Docker Compose e comprende i servizi applicativi, PostgreSQL, Redis, Kafka, Prometheus e Grafana. Le migration Flyway vengono applicate prima dell'avvio dei servizi che usano il database.

Affidabilità e test

Ho dedicato particolare attenzione ai casi di errore:

Oltre ai test unitari, ci sono test con socket reali e container Kafka/PostgreSQL avviati tramite Testcontainers. Un test d'integrazione copre l'intero percorso, dalla ricezione del frame TCP fino al salvataggio del campione nel database.

Stato del progetto

Oggi è funzionante il flusso che parte dal simulator, passa per il gateway e Kafka e arriva al processor, che salva la telemetria in PostgreSQL. Sono già presenti anche la gestione dei veicoli tramite Fleet API, le migration Flyway, i contratti condivisi, le metriche dei servizi e la gestione di retry, eventi rifiutati e dead-letter topic.

Il test di pipeline copre socket TCP, ACK del gateway, pubblicazione Kafka, ordinamento per veicolo, consumo, persistenza e riconsegna dello stesso messaggio senza duplicati.

Restano da completare la lettura degli ACK nel simulator, l'aggiornamento di Redis, la generazione degli alert, gli endpoint di consultazione della Fleet API e il Fleet Dashboard.

Repository: github.com/val3riot/FleetPulse