refactor: centralize default history protocols
This commit is contained in:
@@ -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<String> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,7 +21,6 @@ import org.springframework.web.server.ResponseStatusException;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@ConditionalOnProperty(prefix = "lingniu.ingest.event-history", name = "enabled", havingValue = "true")
|
@ConditionalOnProperty(prefix = "lingniu.ingest.event-history", name = "enabled", havingValue = "true")
|
||||||
@@ -64,7 +63,8 @@ public final class LocationHistoryController {
|
|||||||
@RequestParam(required = false) String cursorTs,
|
@RequestParam(required = false) String cursorTs,
|
||||||
@Parameter(description = "上一页返回的 nextCursor.id。", example = "location-xxx")
|
@Parameter(description = "上一页返回的 nextCursor.id。", example = "location-xxx")
|
||||||
@RequestParam(required = false) String cursorId) throws IOException {
|
@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);
|
QueryTimeRange range = QueryTimeRange.parse(dateFrom, dateTo);
|
||||||
TdenginePage<TdengineLocationRow> page = reader.queryLocations(new TdengineLocationQuery(
|
TdenginePage<TdengineLocationRow> page = reader.queryLocations(new TdengineLocationQuery(
|
||||||
normalizedProtocol,
|
normalizedProtocol,
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import java.util.LinkedHashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@ConditionalOnProperty(prefix = "lingniu.ingest.event-history", name = "enabled", havingValue = "true")
|
@ConditionalOnProperty(prefix = "lingniu.ingest.event-history", name = "enabled", havingValue = "true")
|
||||||
@@ -42,11 +41,6 @@ public final class RawFrameHistoryController {
|
|||||||
private static final TypeReference<Map<String, Object>> MAP_TYPE = new TypeReference<>() {};
|
private static final TypeReference<Map<String, Object>> MAP_TYPE = new TypeReference<>() {};
|
||||||
private static final int LOCATION_ENRICH_LIMIT = 1;
|
private static final int LOCATION_ENRICH_LIMIT = 1;
|
||||||
private static final int TELEMETRY_ENRICH_LIMIT = 500;
|
private static final int TELEMETRY_ENRICH_LIMIT = 500;
|
||||||
private static final Set<String> DEFAULT_PRODUCTION_PROTOCOLS = Set.of(
|
|
||||||
"GB32960",
|
|
||||||
"JT808",
|
|
||||||
"MQTT_YUTONG");
|
|
||||||
|
|
||||||
private final TdengineHistoryReader reader;
|
private final TdengineHistoryReader reader;
|
||||||
|
|
||||||
public RawFrameHistoryController(TdengineHistoryReader reader) {
|
public RawFrameHistoryController(TdengineHistoryReader reader) {
|
||||||
@@ -93,11 +87,7 @@ public final class RawFrameHistoryController {
|
|||||||
throw new ResponseStatusException(HttpStatus.BAD_REQUEST,
|
throw new ResponseStatusException(HttpStatus.BAD_REQUEST,
|
||||||
"vehicleKey, vin, phone, messageId or parseStatus is required for raw frame query");
|
"vehicleKey, vin, phone, messageId or parseStatus is required for raw frame query");
|
||||||
}
|
}
|
||||||
String normalizedProtocol = normalize(protocol).toUpperCase(Locale.ROOT);
|
String normalizedProtocol = DefaultProductionProtocols.requireSupported(protocol);
|
||||||
if (!DEFAULT_PRODUCTION_PROTOCOLS.contains(normalizedProtocol)) {
|
|
||||||
throw new ResponseStatusException(HttpStatus.BAD_REQUEST,
|
|
||||||
"protocol must be one of GB32960, JT808, MQTT_YUTONG");
|
|
||||||
}
|
|
||||||
QueryTimeRange range = QueryTimeRange.parse(dateFrom, dateTo);
|
QueryTimeRange range = QueryTimeRange.parse(dateFrom, dateTo);
|
||||||
TdenginePage<TdengineRawFrameRow> page = reader.queryRawFrames(new TdengineRawFrameQuery(
|
TdenginePage<TdengineRawFrameRow> page = reader.queryRawFrames(new TdengineRawFrameQuery(
|
||||||
normalizedProtocol,
|
normalizedProtocol,
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import com.lingniu.ingest.tdenginehistory.TdenginePage;
|
|||||||
import com.lingniu.ingest.tdenginehistory.TdenginePageCursor;
|
import com.lingniu.ingest.tdenginehistory.TdenginePageCursor;
|
||||||
import com.lingniu.ingest.tdenginehistory.TdengineQueryOrder;
|
import com.lingniu.ingest.tdenginehistory.TdengineQueryOrder;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.web.server.ResponseStatusException;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -14,6 +16,7 @@ import java.util.Optional;
|
|||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
|
|
||||||
class LocationHistoryControllerTest {
|
class LocationHistoryControllerTest {
|
||||||
|
|
||||||
@@ -66,6 +69,28 @@ class LocationHistoryControllerTest {
|
|||||||
assertThat(captured.get().vehicleKey()).isEqualTo("jt808:g7gps");
|
assertThat(captured.get().vehicleKey()).isEqualTo("jt808:g7gps");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void rejectsLegacyXindaProtocolOnDefaultLocationApi() {
|
||||||
|
AtomicReference<TdengineLocationQuery> 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) {
|
private static TdengineLocationRow row(String factId) {
|
||||||
Instant ts = Instant.parse("2026-06-29T05:00:00Z");
|
Instant ts = Instant.parse("2026-06-29T05:00:00Z");
|
||||||
return new TdengineLocationRow(
|
return new TdengineLocationRow(
|
||||||
|
|||||||
Reference in New Issue
Block a user