diff --git a/docs/operations/gb32960-service-split-runbook.md b/docs/operations/gb32960-service-split-runbook.md index 4f47fbff..4e6fe0f9 100644 --- a/docs/operations/gb32960-service-split-runbook.md +++ b/docs/operations/gb32960-service-split-runbook.md @@ -7,14 +7,14 @@ This runbook covers the split GB32960 ingest, history, and analytics runtimes. K | Service | Module | Role | Local ports | | --- | --- | --- | --- | | 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` | -| Vehicle history | `:vehicle-history-app` | Consume GB32960 raw/event Kafka records, write local raw archives and event-store records, and expose event/history/GB32960 query APIs. | HTTP `20200` | +| Vehicle history | `:vehicle-history-app` | Consume GB32960 raw/event Kafka records, store event-history records and raw archive references, and expose event/history/GB32960 query APIs. Kafka raw envelopes carry archive URI/size metadata, not raw frame bytes. | 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` | ## Kafka Contract | Topic | Producer | Consumers | Purpose | | --- | --- | --- | --- | -| `vehicle.raw.gb32960.v1` | `gb32960-ingest-app` | `vehicle-history-app` | Raw GB32960 frame archive records. | +| `vehicle.raw.gb32960.v1` | `gb32960-ingest-app` | `vehicle-history-app` | Raw archive reference records. The envelope contains URI/size metadata, not the raw `.bin` payload. | | `vehicle.event.gb32960.v1` | `gb32960-ingest-app` | `vehicle-history-app`, `vehicle-analytics-app` | Normalized vehicle events keyed by VIN when available. | | `vehicle.dlq.gb32960.v1` | Kafka producer/consumer error paths | Operators/replay tooling | Dead-letter records for failed production or consumer processing. | @@ -95,11 +95,12 @@ Vehicle history: KAFKA_BROKERS=127.0.0.1:9092 \ HTTP_PORT=20200 \ EVENT_FILE_STORE_PATH=./target/split-event-store \ -SINK_ARCHIVE_PATH=./target/split-archive \ java --sun-misc-unsafe-memory-access=allow \ -jar modules/apps/vehicle-history-app/target/vehicle-history-app.jar ``` +`SINK_ARCHIVE_PATH` is intentionally omitted in the split-service Kafka verification path. Current Kafka raw envelopes contain `RawArchiveRef` URI/size metadata only; they do not contain raw bytes that `RawArchiveEventSink` could materialize into `.bin` files in the history JVM. + Vehicle analytics: ```bash @@ -132,33 +133,44 @@ Example send command: xxd -r -p modules/protocols/protocol-gb32960/src/test/resources/samples/gb32960/realtime_001.hex | nc 127.0.0.1 32960 ``` +To capture and inspect the binary ACK, write the response to a file: + +```bash +rm -f /tmp/gb32960-ack.bin +xxd -r -p modules/protocols/protocol-gb32960/src/test/resources/samples/gb32960/realtime_001.hex \ + | nc -w 3 127.0.0.1 32960 > /tmp/gb32960-ack.bin +xxd -p /tmp/gb32960-ack.bin +``` + +Expected: the ACK file is non-empty and the decoded bytes begin with the GB32960 frame marker `2323`. Treat the ACK as verified only after checking the response bytes from your run. + Verify only what was actually run in your environment: ```bash kafka-console-consumer --bootstrap-server 127.0.0.1:9092 --topic vehicle.raw.gb32960.v1 --from-beginning --max-messages 1 --timeout-ms 10000 kafka-console-consumer --bootstrap-server 127.0.0.1:9092 --topic vehicle.event.gb32960.v1 --from-beginning --max-messages 1 --timeout-ms 10000 -find target/split-archive -type f | head find target/split-event-store -type f | head find target/split-vehicle-stat -type f | head ``` -Useful HTTP query checks after events are consumed: +Useful HTTP query checks after events are consumed. For `realtime_001.hex`, the fixture VIN is `LTEST000000000001`; replace ``, ``, and `` with values that cover the consumed record's event time: ```bash -curl -sS 'http://127.0.0.1:20200/api/event-history/records?protocol=GB32960&dateFrom=2026-06-23&dateTo=2026-06-24&limit=10' +curl -sS 'http://127.0.0.1:20200/api/event-history/records?protocol=GB32960&dateFrom=&dateTo=&vin=LTEST000000000001&limit=10' curl -sS 'http://127.0.0.1:20200/api/event-history/gb32960/dictionary' -curl -sS 'http://127.0.0.1:20300/api/vehicle-stat/LB9A32A20P0LS1257/daily?date=2026-06-23' +curl -sS 'http://127.0.0.1:20300/api/vehicle-stat/LTEST000000000001/daily?date=' ``` Expected E2E result when Kafka and all services are running: -- A GB32960 client receives a success ACK only after required Kafka production succeeds. -- `vehicle.raw.gb32960.v1` receives a raw record. +- A GB32960 client receives a binary success ACK only after required Kafka production succeeds, and the captured ACK bytes are inspected. +- `vehicle.raw.gb32960.v1` receives a raw archive reference envelope. - `vehicle.event.gb32960.v1` receives one or more normalized records. -- `target/split-archive` receives raw archive files after the history service consumes raw records. -- `target/split-event-store` receives event-store files after the history service flushes 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. +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. + Do not mark any of these as verified unless the matching command was run and the output was inspected. ## Rollback Guidance