| | |
| | | public interface BtsSimulatorStateStore |
| | | { |
| | | int CURRENT_VERSION = 1; |
| | | int MAX_HISTORY_BATCH_SIZE = 1000; |
| | | /** 开发演示只保留有限历史,避免 Redis 随运行时间无限增长。 */ |
| | | long MAX_HISTORY_RECORDS = 20_000L; |
| | | |
| | | /** 读取已有状态;仅在状态不存在时原子写入并返回默认状态。 */ |
| | | SimulatorState loadOrInitialize(SimulatorState defaultState); |
| | | |
| | | /** 开发模拟器启动时清理上一轮演示历史;正式业务存储不需要实现该动作。 */ |
| | | default SimulatorState resetHistoryForDemoStartup(SimulatorState state) { return state; } |
| | | |
| | | /** 完整保存下一版模拟器状态。 */ |
| | | void save(SimulatorState state); |
| | | |
| | | /** 状态和独立历史全部校验通过后,提交兼容旧格式所需的迁移。 */ |
| | | default void completeValidatedRestore(SimulatorState state) { } |
| | | |
| | | /** 原子保存主状态并追加本轮新产生的原始历史。 */ |
| | | default void save(SimulatorState state, List<CollectorHistoryAppend> historyAppends) |
| | | { |
| | | if (!historyAppends.isEmpty()) |
| | | throw new UnsupportedOperationException("Collector history append is not supported"); |
| | | save(state); |
| | | } |
| | | |
| | | /** 按原始写入顺序或反向顺序读取有界历史批次。 */ |
| | | default CollectorHistoryBatch loadCollectorHistoryPage(String collectorCode, long offset, int limit, |
| | | boolean reverse) |
| | | { |
| | | if (offset < 0) throw new IllegalArgumentException("offset must not be negative"); |
| | | if (limit < 1 || limit > MAX_HISTORY_BATCH_SIZE) |
| | | throw new IllegalArgumentException("limit must be between 1 and " + MAX_HISTORY_BATCH_SIZE); |
| | | return new CollectorHistoryBatch(offset, 0, false, 0, List.of()); |
| | | } |
| | | |
| | | /** 原子保存删除采集器后的主状态,并删除该采集器的独立历史。 */ |
| | | default void saveAndDeleteCollectorHistory(SimulatorState state, String collectorCode) |
| | | { |
| | | throw new UnsupportedOperationException("Atomic collector deletion is not supported"); |
| | | } |
| | | |
| | | /** 读取短期保留的最近请求。 */ |
| | | List<RecentRequest> loadRecentRequests(); |
| | |
| | | } |
| | | } |
| | | |
| | | record DeviceState(int deviceId, String ip, boolean online, List<ChannelState> channels) |
| | | record DeviceState(int deviceId, String ip, boolean online, List<ChannelState> channels, |
| | | BtsDeviceProfile profile) |
| | | { |
| | | public DeviceState { channels = List.copyOf(channels); } |
| | | public DeviceState |
| | | { |
| | | channels = List.copyOf(channels); |
| | | profile = profile == null ? BtsDeviceProfile.virtual(channels.size()) : profile; |
| | | } |
| | | |
| | | /** 兼容旧版只保存拓扑和通道状态的模拟设备。 */ |
| | | public DeviceState(int deviceId, String ip, boolean online, List<ChannelState> channels) |
| | | { |
| | | this(deviceId, ip, online, channels, BtsDeviceProfile.virtual(channels.size())); |
| | | } |
| | | } |
| | | |
| | | record CollectorState(int collectorId, String deviceCode, String ip, String mac, String name, |
| | | String manufacturer, String model, int channelCount, boolean online, int sampleIntervalMs, |
| | | long nextSequence, Instant lastSampledAt, List<CollectorChannelState> channels, |
| | | List<CollectorRealtimeMeasurement> latestMeasurements, |
| | | List<CollectorMeasurementRecord> history, CollectorHistoryFaults historyFaults) |
| | | long historyRecordCount, CollectorHistoryFaults historyFaults) |
| | | { |
| | | public CollectorState |
| | | { |
| | | channels = List.copyOf(channels); |
| | | latestMeasurements = List.copyOf(latestMeasurements); |
| | | history = List.copyOf(history); |
| | | historyFaults = historyFaults == null ? CollectorHistoryFaults.none() : historyFaults; |
| | | } |
| | | |
| | |
| | | { |
| | | this(collectorId, deviceCode, ip, mac, name, manufacturer, model, channelCount, online, |
| | | DevelopmentCollectorSimulation.DEFAULT_SAMPLE_INTERVAL_MS, 1L, null, |
| | | DevelopmentCollectorSimulation.defaultChannels(channelCount), List.of(), List.of(), |
| | | DevelopmentCollectorSimulation.defaultChannels(channelCount), List.of(), 0L, |
| | | CollectorHistoryFaults.none()); |
| | | } |
| | | } |
| | |
| | | long sequenceId, Instant deviceTime, String deviceTimeRaw, Instant serverReceivedAt, |
| | | String metricCode, BigDecimal value, String unit) { } |
| | | |
| | | record CollectorHistoryAppend(String collectorCode, List<CollectorMeasurementRecord> records) |
| | | { |
| | | public CollectorHistoryAppend { records = List.copyOf(records); } |
| | | } |
| | | |
| | | record CollectorHistoryBatch(long offset, long nextOffset, boolean hasMore, long total, |
| | | List<CollectorMeasurementRecord> records) |
| | | { |
| | | public CollectorHistoryBatch { records = List.copyOf(records); } |
| | | } |
| | | |
| | | record CollectorHistoryFaults(List<Long> missingSequences, Long duplicateSequence, |
| | | Long conflictingSequence, boolean outOfOrder) |
| | | { |
| | |
| | | |
| | | record ChannelState(int channelId, boolean online, DeviceWorkStatus workStatus) { } |
| | | |
| | | /** BTS 检测柜的可配置厂商 profile;参数用于发现展示和边界内的演示数据生成。 */ |
| | | record BtsDeviceProfile(int devtype, int subDeviceId, String name, String manufacturer, String model, |
| | | String serialNumber, String firmwareVersion, int channelCount, BigDecimal currentMinA, |
| | | BigDecimal currentMaxA, BigDecimal voltageMinV, BigDecimal voltageMaxV, int sampleIntervalMs) |
| | | { |
| | | public BtsDeviceProfile |
| | | { |
| | | if (devtype < 0 || subDeviceId < 0 || channelCount < 1 || sampleIntervalMs < 1) |
| | | throw new IllegalArgumentException("Invalid BTS device profile limits"); |
| | | if (name == null || name.isBlank() || manufacturer == null || manufacturer.isBlank() |
| | | || model == null || model.isBlank() || serialNumber == null || serialNumber.isBlank() |
| | | || firmwareVersion == null || firmwareVersion.isBlank()) |
| | | throw new IllegalArgumentException("BTS device profile metadata must not be blank"); |
| | | if (currentMinA == null || currentMaxA == null || voltageMinV == null || voltageMaxV == null |
| | | || currentMinA.compareTo(currentMaxA) > 0 || voltageMinV.compareTo(voltageMaxV) > 0) |
| | | throw new IllegalArgumentException("Invalid BTS device profile ranges"); |
| | | } |
| | | |
| | | public static BtsDeviceProfile virtual(int channelCount) |
| | | { |
| | | return new BtsDeviceProfile(22, 1, "dev-sim 设备", "开发模拟器", "BTS Virtual Cabinet", |
| | | "SIM-VIRTUAL", "dev-sim", channelCount, new BigDecimal("-6.000"), |
| | | new BigDecimal("6.000"), BigDecimal.ZERO, new BigDecimal("5.000"), 100); |
| | | } |
| | | } |
| | | |
| | | record ChannelTombstone(int deviceId, String ip, int channelId, int remainingDiscoveries) { } |
| | | |
| | | record RecentRequest(Instant receivedAt, String command, String request) { } |