refactor: remove file identity runtime

This commit is contained in:
lingniu
2026-07-01 02:18:27 +08:00
parent f0c1983867
commit 356be9fc98
6 changed files with 17 additions and 153 deletions

View File

@@ -1,106 +0,0 @@
package com.lingniu.ingest.identity;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lingniu.ingest.api.ProtocolId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
/**
* 文件型车辆身份绑定表。
*
* <p>写入采用 append-only JSONL启动时顺序重放到内存索引。这样协议层只依赖 identity SPI
* 不直接耦合业务库;后续替换成 DB/配置中心时只需新增同接口实现。
*/
public final class FileVehicleIdentityService implements VehicleIdentityResolver, VehicleIdentityRegistry {
private static final Logger log = LoggerFactory.getLogger(FileVehicleIdentityService.class);
private final Path path;
private final ObjectMapper mapper;
private final InMemoryVehicleIdentityService delegate = new InMemoryVehicleIdentityService();
private final Object writeLock = new Object();
public FileVehicleIdentityService(Path path) {
this(path, new ObjectMapper());
}
public FileVehicleIdentityService(Path path, ObjectMapper mapper) {
this.path = path.toAbsolutePath();
this.mapper = mapper;
load();
}
@Override
public void bind(VehicleIdentityBinding binding) {
if (binding == null || !binding.hasResolvedVin()) {
return;
}
delegate.bind(binding);
synchronized (writeLock) {
try {
Files.createDirectories(path.getParent());
try (BufferedWriter writer = Files.newBufferedWriter(path, StandardCharsets.UTF_8,
StandardOpenOption.CREATE, StandardOpenOption.APPEND, StandardOpenOption.WRITE)) {
// append-only 允许运行时新增绑定;重启时按文件顺序 replay后写覆盖内存索引中的旧映射。
writer.write(mapper.writeValueAsString(BindingLine.from(binding)));
writer.newLine();
}
} catch (IOException e) {
throw new IllegalStateException("vehicle identity binding persist failed: " + path, e);
}
}
}
@Override
public VehicleIdentity resolve(VehicleIdentityLookup lookup) {
return delegate.resolve(lookup);
}
private void load() {
if (!Files.exists(path)) {
return;
}
try (BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
String line;
while ((line = reader.readLine()) != null) {
if (line.isBlank()) {
continue;
}
try {
BindingLine binding = mapper.readValue(line, BindingLine.class);
// 单行损坏不影响其它绑定加载,避免一个坏配置拖垮全部接入。
delegate.bind(binding.toBinding());
} catch (Exception e) {
log.warn("skip invalid vehicle identity binding line path={} line={}", path, line, e);
}
}
} catch (IOException e) {
throw new IllegalStateException("vehicle identity binding load failed: " + path, e);
}
}
private record BindingLine(
ProtocolId protocol,
String vin,
String phone,
String deviceId,
String plate
) {
private static BindingLine from(VehicleIdentityBinding binding) {
return new BindingLine(
binding.protocol(), binding.vin(), binding.phone(), binding.deviceId(), binding.plate());
}
private VehicleIdentityBinding toBinding() {
return new VehicleIdentityBinding(protocol, vin, phone, deviceId, plate);
}
}
}

View File

@@ -1,41 +0,0 @@
package com.lingniu.ingest.identity;
import com.lingniu.ingest.api.ProtocolId;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import java.nio.file.Files;
import java.nio.file.Path;
import static org.assertj.core.api.Assertions.assertThat;
class FileVehicleIdentityServiceTest {
@TempDir
Path tempDir;
@Test
void persistsBindingsAndReloadsThemAfterRestart() throws Exception {
Path store = tempDir.resolve("vehicle-identity.jsonl");
FileVehicleIdentityService first = new FileVehicleIdentityService(store);
first.bind(new VehicleIdentityBinding(
ProtocolId.JT808, "LNVIN000000000099", "13900000099", "DEV099", "粤B09999"));
FileVehicleIdentityService restarted = new FileVehicleIdentityService(store);
VehicleIdentity byPhone = restarted.resolve(new VehicleIdentityLookup(
ProtocolId.JT808, "", "13900000099", "", ""));
VehicleIdentity byDevice = restarted.resolve(new VehicleIdentityLookup(
ProtocolId.JT808, "", "", "DEV099", ""));
VehicleIdentity byPlate = restarted.resolve(new VehicleIdentityLookup(
ProtocolId.JT808, "", "", "", "粤B09999"));
assertThat(byPhone.vin()).isEqualTo("LNVIN000000000099");
assertThat(byPhone.resolved()).isTrue();
assertThat(byPhone.source()).isEqualTo(VehicleIdentitySource.BOUND_PHONE);
assertThat(byDevice.vin()).isEqualTo("LNVIN000000000099");
assertThat(byPlate.vin()).isEqualTo("LNVIN000000000099");
assertThat(Files.readString(store)).contains("\"vin\":\"LNVIN000000000099\"");
}
}