From 6bc36eb5a8f7564e7d8882933562c4bd9e5749e7 Mon Sep 17 00:00:00 2001 From: lingniu Date: Wed, 1 Jul 2026 06:15:43 +0800 Subject: [PATCH] docs: clarify analytics runtime scope --- docs/operations/gb32960-service-split-runbook.md | 7 +++---- .../PortainerComposeResourceLimitsTest.java | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/docs/operations/gb32960-service-split-runbook.md b/docs/operations/gb32960-service-split-runbook.md index b71ac8c2..7888e29c 100644 --- a/docs/operations/gb32960-service-split-runbook.md +++ b/docs/operations/gb32960-service-split-runbook.md @@ -9,7 +9,7 @@ This runbook covers the split GB32960 ingest, history, and analytics runtimes. K | GB32960 ingest | `:gb32960-ingest-app` | Accept GB32960 TCP connections, decode/authenticate frames, produce raw and normalized records to Kafka, and send protocol ACKs after required Kafka production succeeds. | TCP `32960`, HTTP `20100` | | JT808 ingest | `:jt808-ingest-app` | Accept JT/T 808 TCP connections on the production receive port, parse raw frames, archive frame bytes, and produce raw/event envelopes to Kafka. | TCP `808`, HTTP `20482` | | Vehicle history | `:vehicle-history-app` | Consume GB32960/JT808 raw/event Kafka records, store compact history rows plus TDengine `raw_frames` `parsedJson`/`metadataJson`/`rawUri`, and expose TDengine-backed history APIs. | HTTP `20200` | -| Vehicle analytics | `:vehicle-analytics-app` | Consume GB32960 event Kafka records and update analytics outputs such as daily vehicle statistics. Vehicle state can also be enabled from this runtime. | HTTP `20300` | +| Vehicle analytics | `:vehicle-analytics-app` | Consume JT808 event Kafka records, calculate daily mileage from reported GPS total mileage, and write metrics to `vehicle_stat_metric`. | HTTP `20300` | ## Kafka Contract @@ -25,7 +25,6 @@ This runbook covers the split GB32960 ingest, history, and analytics runtimes. K Default local consumer groups: - History: `vehicle-history` -- Analytics state: `vehicle-state` when `VEHICLE_STATE_ENABLED=true` - Analytics statistics: `vehicle-stat` ## ACK Semantics @@ -132,7 +131,7 @@ java --sun-misc-unsafe-memory-access=allow \ -jar modules/apps/vehicle-analytics-app/target/vehicle-analytics-app.jar ``` -To enable the latest-state API in analytics, also set `VEHICLE_STATE_ENABLED=true` and configure the state repository requirements used by `vehicle-state-service`. +`vehicle-analytics-app` is intentionally a metric runtime only. Latest-state APIs belong to `vehicle-state-service` and should be deployed as a separate consumer if that surface is needed. ## Health Verification @@ -189,7 +188,7 @@ Expected E2E result when Kafka and all services are running: - `vehicle.raw.gb32960.v1` receives a raw archive reference envelope. - `vehicle.event.gb32960.v1` receives one or more normalized records. - `target/split-event-store` receives event-store files after the history service flushes consumed Kafka records, including raw archive reference records. -- `target/split-vehicle-stat` receives stat output after analytics consumes applicable event records. +- JT808 analytics writes daily mileage rows to MySQL `vehicle_stat_metric` after consuming applicable `vehicle.event.jt808.v1` records. Do not expect `vehicle-history-app` to create raw `.bin` archive files from Kafka raw records in the current implementation. `RawArchiveEventSink` can write archive files only when it receives `VehicleEvent.RawArchive.rawBytes()` inside the same JVM; the Kafka envelope carries only `RawArchiveRef` metadata. diff --git a/modules/apps/vehicle-history-app/src/test/java/com/lingniu/ingest/historyapp/PortainerComposeResourceLimitsTest.java b/modules/apps/vehicle-history-app/src/test/java/com/lingniu/ingest/historyapp/PortainerComposeResourceLimitsTest.java index de50985c..d13e5695 100644 --- a/modules/apps/vehicle-history-app/src/test/java/com/lingniu/ingest/historyapp/PortainerComposeResourceLimitsTest.java +++ b/modules/apps/vehicle-history-app/src/test/java/com/lingniu/ingest/historyapp/PortainerComposeResourceLimitsTest.java @@ -93,6 +93,20 @@ class PortainerComposeResourceLimitsTest { .doesNotContain("shared volume mounted to all three services"); } + @Test + void splitRunbookKeepsAnalyticsAsJt808MetricRuntimeOnly() throws IOException { + String splitRunbook = Files.readString(repositoryRoot() + .resolve("docs/operations/gb32960-service-split-runbook.md")); + + assertThat(splitRunbook) + .contains("Consume JT808 event Kafka records") + .contains("vehicle_stat_metric") + .doesNotContain("Analytics state:") + .doesNotContain("VEHICLE_STATE_ENABLED") + .doesNotContain("latest-state API in analytics") + .doesNotContain("Vehicle state can also be enabled from this runtime"); + } + @Test void vehicleAnalyticsComposeOnlyExposesStatConsumerEnvironment() throws IOException { String compose = Files.readString(repositoryRoot().resolve("deploy/portainer/docker-compose.yml"));