feat: productionize raw history ingestion
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
package com.lingniu.ingest.core.dispatcher;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.json.JsonMapper;
|
||||
import com.lingniu.ingest.api.event.RawArchiveKeys;
|
||||
import com.lingniu.ingest.api.event.VehicleEvent;
|
||||
import com.lingniu.ingest.api.pipeline.IngestContext;
|
||||
@@ -36,6 +39,9 @@ public final class Dispatcher {
|
||||
private static final Logger log = LoggerFactory.getLogger(Dispatcher.class);
|
||||
private static final AtomicLong RAW_ARCHIVE_SEQUENCE = new AtomicLong();
|
||||
private static final String REQUIRED_DURABLE_SINK = "kafka";
|
||||
private static final ObjectMapper RAW_ARCHIVE_JSON = JsonMapper.builder()
|
||||
.findAndAddModules()
|
||||
.build();
|
||||
|
||||
private final HandlerRegistry registry;
|
||||
private final InterceptorChain interceptors;
|
||||
@@ -167,7 +173,10 @@ public final class Dispatcher {
|
||||
byte[] bytes = frame.rawBytes();
|
||||
if (bytes == null || bytes.length == 0) return RawArchiveLookup.empty();
|
||||
|
||||
Map<String, String> meta = frame.sourceMeta() == null ? Map.of() : frame.sourceMeta();
|
||||
Map<String, String> meta = frame.sourceMeta() == null
|
||||
? Map.of()
|
||||
: new LinkedHashMap<>(frame.sourceMeta());
|
||||
String parsedJson = parsedJson(frame.payload(), meta.remove(RawArchiveKeys.META_PARSED_JSON));
|
||||
String vin = meta.getOrDefault("vin", "");
|
||||
Instant ingestTime = frame.receivedAt() != null ? frame.receivedAt() : Instant.now();
|
||||
String eventId = nextRawArchiveEventId(ingestTime);
|
||||
@@ -184,11 +193,34 @@ public final class Dispatcher {
|
||||
archiveMeta,
|
||||
frame.command(),
|
||||
frame.infoType(),
|
||||
bytes);
|
||||
bytes,
|
||||
parsedJson);
|
||||
out.add(raw);
|
||||
return new RawArchiveLookup(eventId, key, RawArchiveKeys.logicalUri(key));
|
||||
}
|
||||
|
||||
private static String parsedJson(Object payload, String explicitParsedJson) {
|
||||
if (explicitParsedJson != null && !explicitParsedJson.isBlank()) {
|
||||
return explicitParsedJson;
|
||||
}
|
||||
if (payload == null) {
|
||||
return "{}";
|
||||
}
|
||||
try {
|
||||
return RAW_ARCHIVE_JSON.writeValueAsString(payload);
|
||||
} catch (JsonProcessingException ex) {
|
||||
return "{\"serializationError\":\"" + escapeJson(ex.getMessage()) + "\",\"payloadType\":\""
|
||||
+ escapeJson(payload.getClass().getName()) + "\"}";
|
||||
}
|
||||
}
|
||||
|
||||
private static String escapeJson(String value) {
|
||||
if (value == null) {
|
||||
return "";
|
||||
}
|
||||
return value.replace("\\", "\\\\").replace("\"", "\\\"");
|
||||
}
|
||||
|
||||
private static String nextRawArchiveEventId(Instant ingestTime) {
|
||||
// 文件名需要可排序且单进程内唯一:毫秒时间放大到微秒量级,再用 AtomicLong 递增兜底。
|
||||
long base = (ingestTime == null ? Instant.now() : ingestTime).toEpochMilli() * 1000L;
|
||||
|
||||
Reference in New Issue
Block a user