| | |
| | | private static final String DISABLED = "1"; |
| | | private static final String READ_ONLY_CAPABILITIES = |
| | | "{\"discovery\":true,\"realtimeObservation\":true,\"historyDownload\":true,\"control\":false}"; |
| | | /** 适配器类型按存储形态划分;BTS 保留给开发模拟器与将来的协议路线(ADR-0065)。 */ |
| | | private static final List<String> SUPPORTED_TYPES = List.of("BTS", "NEWARE_MYSQL"); |
| | | /** 直连厂商存储的来源,其通道登记清单是长期事实,候选不按时间过期。 */ |
| | | private static final List<String> PERSISTENT_CANDIDATE_TYPES = List.of("NEWARE_MYSQL"); |
| | | /** |
| | | * 适配器类型按存储形态划分;BTS 保留给开发模拟器与将来的协议路线(ADR-0065)。 |
| | | * `NEWARE_MYSQL` 只能写字面量:battery-business 不依赖 battery-device-neware, |
| | | * 拿不到那边的常量;推式来源的实现就在本模块,所以用它的常量。 |
| | | */ |
| | | private static final List<String> SUPPORTED_TYPES = List.of("BTS", "NEWARE_MYSQL", PushIngestAdapter.ADAPTER_TYPE); |
| | | /** |
| | | * 通道清单长期存在的来源,候选不按时间过期:直连厂商存储的来源读的是厂商的登记表, |
| | | * 推式来源读的是取数程序上报的拓扑——两者都不是"轮询发现"的结果。 |
| | | */ |
| | | private static final List<String> PERSISTENT_CANDIDATE_TYPES = |
| | | List.of("NEWARE_MYSQL", PushIngestAdapter.ADAPTER_TYPE); |
| | | |
| | | private final TDeviceAdapterMapper mapper; |
| | | private final DeviceAdapterRegistry registry; |
| | |
| | | value.setDevid(channel.identity().devid()); |
| | | value.setSubdevid(channel.identity().subdevid()); |
| | | value.setChlid(channel.identity().chlid()); |
| | | value.setDisplayNo(channel.identity().subdevid() + "-" + channel.identity().chlid()); |
| | | value.setDisplayNo(TDetectionCabinetServiceImpl.channelDisplayNo(channel)); |
| | | value.setOnlineStatus(channel.online() ? "ONLINE" : "OFFLINE"); |
| | | value.setWorkStatus(channel.workStatus().name()); |
| | | value.setLastSeenAtUtc(channel.observedAt()); |
| | |
| | | } |
| | | catch (RuntimeException exception) |
| | | { |
| | | // 单行配置有问题(例如缺少口令环境变量)不得拦住后端启动: |
| | | // 记下原因,由发现轮询按周期重试并把失败持久化到这一行。 |
| | | // 单行配置有问题(例如没放凭据文件、口令键名写错)不得拦住后端启动: |
| | | // 既写日志,也按发现失败的同一路径落到这一行,使"忘了配"在启动后立刻是列表里可见的一行。 |
| | | log.warn("设备适配器实例装配失败 adapterCode={}:{}", adapter.getAdapterCode(), exception.getMessage()); |
| | | mapper.updateDiscoveryFailure(adapter.getAdapterId(), startupFailureCode(exception), |
| | | exception.getMessage()); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 装配失败写进实例行的错误码:适配器自己给出分类(例如凭据缺失、连接失败)时用它, |
| | | * 否则记为配置问题——启动阶段的装配失败基本都是配置造成的。 |
| | | */ |
| | | private static String startupFailureCode(RuntimeException exception) |
| | | { |
| | | return exception instanceof DeviceAdapterException deviceFailure && !deviceFailure.failureCode().isBlank() |
| | | ? deviceFailure.failureCode() : "INVALID_CONFIG"; |
| | | } |
| | | |
| | | /** 轮询达到周期的已启用适配器,并持久化失败状态后继续调度。 */ |
| | | @Override |
| | | public void pollDueAdapters() |