From d4c54b5d0f37331b689902ca5231bd3958794f29 Mon Sep 17 00:00:00 2001 From: lingniu Date: Wed, 1 Jul 2026 11:28:16 +0800 Subject: [PATCH] refactor: centralize default history protocols --- .../DefaultProductionProtocols.java | 27 +++++++++++++++++++ .../LocationHistoryController.java | 4 +-- .../RawFrameHistoryController.java | 12 +-------- .../LocationHistoryControllerTest.java | 25 +++++++++++++++++ 4 files changed, 55 insertions(+), 13 deletions(-) create mode 100644 modules/services/event-history-service/src/main/java/com/lingniu/ingest/eventhistory/DefaultProductionProtocols.java diff --git a/modules/services/event-history-service/src/main/java/com/lingniu/ingest/eventhistory/DefaultProductionProtocols.java b/modules/services/event-history-service/src/main/java/com/lingniu/ingest/eventhistory/DefaultProductionProtocols.java new file mode 100644 index 00000000..eb532833 --- /dev/null +++ b/modules/services/event-history-service/src/main/java/com/lingniu/ingest/eventhistory/DefaultProductionProtocols.java @@ -0,0 +1,27 @@ +package com.lingniu.ingest.eventhistory; + +import org.springframework.http.HttpStatus; +import org.springframework.web.server.ResponseStatusException; + +import java.util.Locale; +import java.util.Set; + +final class DefaultProductionProtocols { + + private static final Set SUPPORTED = Set.of( + "GB32960", + "JT808", + "MQTT_YUTONG"); + private static final String SUPPORTED_MESSAGE = "protocol must be one of GB32960, JT808, MQTT_YUTONG"; + + private DefaultProductionProtocols() { + } + + static String requireSupported(String protocol) { + String normalized = protocol == null ? "" : protocol.trim().toUpperCase(Locale.ROOT); + if (!SUPPORTED.contains(normalized)) { + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, SUPPORTED_MESSAGE); + } + return normalized; + } +} diff --git a/modules/services/event-history-service/src/main/java/com/lingniu/ingest/eventhistory/LocationHistoryController.java b/modules/services/event-history-service/src/main/java/com/lingniu/ingest/eventhistory/LocationHistoryController.java index abeb17f4..f346a9d5 100644 --- a/modules/services/event-history-service/src/main/java/com/lingniu/ingest/eventhistory/LocationHistoryController.java +++ b/modules/services/event-history-service/src/main/java/com/lingniu/ingest/eventhistory/LocationHistoryController.java @@ -21,7 +21,6 @@ import org.springframework.web.server.ResponseStatusException; import java.io.IOException; import java.time.Instant; import java.util.List; -import java.util.Locale; @RestController @ConditionalOnProperty(prefix = "lingniu.ingest.event-history", name = "enabled", havingValue = "true") @@ -64,7 +63,8 @@ public final class LocationHistoryController { @RequestParam(required = false) String cursorTs, @Parameter(description = "上一页返回的 nextCursor.id。", example = "location-xxx") @RequestParam(required = false) String cursorId) throws IOException { - String normalizedProtocol = require(protocol, "protocol is required for location query").toUpperCase(Locale.ROOT); + String normalizedProtocol = DefaultProductionProtocols.requireSupported( + require(protocol, "protocol is required for location query")); QueryTimeRange range = QueryTimeRange.parse(dateFrom, dateTo); TdenginePage page = reader.queryLocations(new TdengineLocationQuery( normalizedProtocol, diff --git a/modules/services/event-history-service/src/main/java/com/lingniu/ingest/eventhistory/RawFrameHistoryController.java b/modules/services/event-history-service/src/main/java/com/lingniu/ingest/eventhistory/RawFrameHistoryController.java index 6c076e43..8854bd60 100644 --- a/modules/services/event-history-service/src/main/java/com/lingniu/ingest/eventhistory/RawFrameHistoryController.java +++ b/modules/services/event-history-service/src/main/java/com/lingniu/ingest/eventhistory/RawFrameHistoryController.java @@ -29,7 +29,6 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.Set; @RestController @ConditionalOnProperty(prefix = "lingniu.ingest.event-history", name = "enabled", havingValue = "true") @@ -42,11 +41,6 @@ public final class RawFrameHistoryController { private static final TypeReference> MAP_TYPE = new TypeReference<>() {}; private static final int LOCATION_ENRICH_LIMIT = 1; private static final int TELEMETRY_ENRICH_LIMIT = 500; - private static final Set DEFAULT_PRODUCTION_PROTOCOLS = Set.of( - "GB32960", - "JT808", - "MQTT_YUTONG"); - private final TdengineHistoryReader reader; public RawFrameHistoryController(TdengineHistoryReader reader) { @@ -93,11 +87,7 @@ public final class RawFrameHistoryController { throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "vehicleKey, vin, phone, messageId or parseStatus is required for raw frame query"); } - String normalizedProtocol = normalize(protocol).toUpperCase(Locale.ROOT); - if (!DEFAULT_PRODUCTION_PROTOCOLS.contains(normalizedProtocol)) { - throw new ResponseStatusException(HttpStatus.BAD_REQUEST, - "protocol must be one of GB32960, JT808, MQTT_YUTONG"); - } + String normalizedProtocol = DefaultProductionProtocols.requireSupported(protocol); QueryTimeRange range = QueryTimeRange.parse(dateFrom, dateTo); TdenginePage page = reader.queryRawFrames(new TdengineRawFrameQuery( normalizedProtocol, diff --git a/modules/services/event-history-service/src/test/java/com/lingniu/ingest/eventhistory/LocationHistoryControllerTest.java b/modules/services/event-history-service/src/test/java/com/lingniu/ingest/eventhistory/LocationHistoryControllerTest.java index 050ba86b..0bce2b69 100644 --- a/modules/services/event-history-service/src/test/java/com/lingniu/ingest/eventhistory/LocationHistoryControllerTest.java +++ b/modules/services/event-history-service/src/test/java/com/lingniu/ingest/eventhistory/LocationHistoryControllerTest.java @@ -7,6 +7,8 @@ import com.lingniu.ingest.tdenginehistory.TdenginePage; import com.lingniu.ingest.tdenginehistory.TdenginePageCursor; import com.lingniu.ingest.tdenginehistory.TdengineQueryOrder; import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; +import org.springframework.web.server.ResponseStatusException; import java.time.Instant; import java.util.List; @@ -14,6 +16,7 @@ import java.util.Optional; import java.util.concurrent.atomic.AtomicReference; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; class LocationHistoryControllerTest { @@ -66,6 +69,28 @@ class LocationHistoryControllerTest { assertThat(captured.get().vehicleKey()).isEqualTo("jt808:g7gps"); } + @Test + void rejectsLegacyXindaProtocolOnDefaultLocationApi() { + AtomicReference captured = new AtomicReference<>(); + LocationHistoryController controller = new LocationHistoryController( + new StubReader(captured, new TdenginePage<>(List.of(), null))); + + assertThatThrownBy(() -> controller.locations( + "XINDA_PUSH", + null, + "LB9A32A24P0LS1270", + null, + "2026-06-29T13:00:00", + "2026-06-29T13:10:00", + TdengineQueryOrder.DESC, + 100, + null, + null)) + .isInstanceOfSatisfying(ResponseStatusException.class, ex -> + assertThat(ex.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST)); + assertThat(captured).hasValue(null); + } + private static TdengineLocationRow row(String factId) { Instant ts = Instant.parse("2026-06-29T05:00:00Z"); return new TdengineLocationRow(