chore: enforce kafka-only stat path
This commit is contained in:
@@ -4,6 +4,8 @@
|
||||
|
||||
The analytics app can calculate daily mileage from JT808 telemetry only. It consumes `vehicle.event.jt808.v1` and saves the current daily result into the common `vehicle-stat` metric repository.
|
||||
|
||||
Only supported message backbone: Kafka.
|
||||
|
||||
## Storage
|
||||
|
||||
Runtime state: none outside `vehicle_stat_metric`. There is no separate JT808 daily-mileage table. The derived value is stored as one `daily_mileage_km` metric row in the common JDBC/MySQL table `vehicle_stat_metric`; the local-day minimum and maximum GPS total mileage values are kept on that same row as calculation source columns.
|
||||
|
||||
@@ -6,6 +6,7 @@ Consume JT808 Kafka location events and write the derived daily mileage into the
|
||||
|
||||
## Current Design
|
||||
|
||||
- Only supported message backbone: Kafka.
|
||||
- Source topic: `vehicle.event.jt808.v1`
|
||||
- Runtime app: `vehicle-analytics-app`
|
||||
- Runtime state: none outside `vehicle_stat_metric`
|
||||
@@ -42,4 +43,4 @@ MYSQL_PASSWORD=<password>
|
||||
|
||||
## Notes
|
||||
|
||||
Do not create or write a protocol-specific JT808 daily-mileage table. Do not add distance accumulation, integral calculation, Redis state, or memory state back into this path unless the mileage definition changes again.
|
||||
Do not create or write a protocol-specific JT808 daily-mileage table. Do not add MQ, distance accumulation, integral calculation, Redis state, or memory state back into this path unless the mileage definition changes again.
|
||||
|
||||
@@ -5,6 +5,8 @@ The project should stay small at runtime: protocol apps ingest and publish,
|
||||
history consumes and indexes, analytics derives metrics, and business systems
|
||||
read through explicit APIs or Kafka.
|
||||
|
||||
Only supported message backbone: Kafka.
|
||||
|
||||
## Active Scope
|
||||
|
||||
Active production protocols:
|
||||
|
||||
@@ -79,8 +79,6 @@ lingniu:
|
||||
group-id: ${KAFKA_GROUP_HISTORY_YUTONG_MQTT_RAW:${KAFKA_GROUP_HISTORY:vehicle-history}-yutong-mqtt-raw}
|
||||
topics:
|
||||
- ${KAFKA_TOPIC_YUTONG_MQTT_RAW:vehicle.raw.mqtt-yutong.v1}
|
||||
archive:
|
||||
enabled: false
|
||||
tdengine-history:
|
||||
enabled: ${TDENGINE_HISTORY_ENABLED:false}
|
||||
database: ${TDENGINE_HISTORY_DATABASE:vehicle_history}
|
||||
|
||||
@@ -4,7 +4,9 @@ import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
@@ -14,7 +16,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
class VehicleHistoryAppDefaultsTest {
|
||||
|
||||
@Test
|
||||
void applicationDefaultsKeepHistoryAsDecoderConsumerAndStorageRuntime() {
|
||||
void applicationDefaultsKeepHistoryAsDecoderConsumerAndStorageRuntime() throws IOException {
|
||||
Properties properties = applicationProperties();
|
||||
|
||||
assertThat(properties)
|
||||
@@ -25,7 +27,6 @@ class VehicleHistoryAppDefaultsTest {
|
||||
.containsEntry("spring.cloud.nacos.config.server-addr", "${NACOS_SERVER_ADDR:127.0.0.1:8848}")
|
||||
.containsEntry("lingniu.ingest.gb32960.enabled", true)
|
||||
.containsEntry("lingniu.ingest.gb32960.server.enabled", false)
|
||||
.containsEntry("lingniu.ingest.sink.archive.enabled", false)
|
||||
.containsEntry("lingniu.ingest.tdengine-history.enabled", "${TDENGINE_HISTORY_ENABLED:false}")
|
||||
.containsEntry("lingniu.ingest.tdengine-history.database", "${TDENGINE_HISTORY_DATABASE:vehicle_history}")
|
||||
.containsEntry(
|
||||
@@ -104,12 +105,13 @@ class VehicleHistoryAppDefaultsTest {
|
||||
assertThat(properties.stringPropertyNames())
|
||||
.noneMatch(name -> name.startsWith("lingniu.ingest.vehicle-state."))
|
||||
.noneMatch(name -> name.startsWith("lingniu.ingest.vehicle-stat."))
|
||||
.noneMatch(name -> name.startsWith("lingniu.ingest.sink.archive."))
|
||||
.noneMatch(name -> name.startsWith("lingniu.ingest.event-file-store."));
|
||||
assertThat(properties.stringPropertyNames())
|
||||
.noneMatch(name -> name.equals("lingniu.ingest.tdengine-history.telemetry-fields-enabled"));
|
||||
assertThat(properties.stringPropertyNames())
|
||||
.noneMatch(name -> name.equals("lingniu.ingest.sink.archive.type")
|
||||
|| name.equals("lingniu.ingest.sink.archive.path"));
|
||||
assertThat(applicationYaml())
|
||||
.doesNotContain("\n archive:\n")
|
||||
.doesNotContain("sink.archive");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -134,4 +136,9 @@ class VehicleHistoryAppDefaultsTest {
|
||||
assertThat(properties).isNotNull();
|
||||
return properties;
|
||||
}
|
||||
|
||||
private static String applicationYaml() throws IOException {
|
||||
return new String(new ClassPathResource("application.yml").getInputStream().readAllBytes(),
|
||||
StandardCharsets.UTF_8);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ class VehicleStatRepositoryContractTest {
|
||||
.resolve("docs/superpowers/plans/2026-06-30-kafka-streaming-mileage.md"));
|
||||
|
||||
assertThat(plan)
|
||||
.contains("Only supported message backbone: Kafka.")
|
||||
.contains("Runtime state: none outside `vehicle_stat_metric`")
|
||||
.contains("daily_mileage_km = max_total_mileage_km - min_total_mileage_km")
|
||||
.contains("Do not create or write a protocol-specific JT808 daily-mileage table.")
|
||||
@@ -40,6 +41,7 @@ class VehicleStatRepositoryContractTest {
|
||||
String architecture = Files.readString(repositoryRoot().resolve("docs/target-architecture.md"));
|
||||
|
||||
assertThat(architecture)
|
||||
.contains("Only supported message backbone: Kafka.")
|
||||
.contains("Runtime state: none outside `vehicle_stat_metric`")
|
||||
.contains("Restart recovery reads the same metric row")
|
||||
.contains("JT808 daily mileage is stored only in `vehicle_stat_metric`")
|
||||
@@ -54,6 +56,7 @@ class VehicleStatRepositoryContractTest {
|
||||
.resolve("docs/operations/jt808-daily-mileage-runbook.md"));
|
||||
|
||||
assertThat(runbook)
|
||||
.contains("Only supported message backbone: Kafka.")
|
||||
.contains("Runtime state: none outside `vehicle_stat_metric`")
|
||||
.contains("Restart recovery reads the same `daily_mileage_km` metric row")
|
||||
.doesNotContain("Redis mileage state")
|
||||
|
||||
Reference in New Issue
Block a user