| | |
| | | import java.time.ZoneId; |
| | | import java.util.List; |
| | | import java.util.Locale; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.dao.DuplicateKeyException; |
| | | import org.springframework.stereotype.Service; |
| | | import com.alibaba.fastjson2.JSON; |
| | |
| | | @Service |
| | | public class DeviceAdapterServiceImpl implements IDeviceAdapterService |
| | | { |
| | | private static final Logger log = LoggerFactory.getLogger(DeviceAdapterServiceImpl.class); |
| | | private static final String ENABLED = "0"; |
| | | private static final String DISABLED = "1"; |
| | | private static final String READ_ONLY_CAPABILITIES = |
| | |
| | | TDeviceAdapter adapter = selectById(adapterId); |
| | | String status = enabled ? ENABLED : DISABLED; |
| | | if (status.equals(adapter.getStatus())) return 1; |
| | | int rows = mapper.updateDeviceAdapterStatus(adapterId, status, updateBy); |
| | | adapter.setStatus(status); |
| | | // 先装配运行时实例:装配失败(例如缺少口令环境变量)时不把状态写成"已启用", |
| | | // 免得留下"库里启用、运行时没有实例"的假状态。 |
| | | registry.synchronize(toRuntimeConfig(adapter)); |
| | | return rows; |
| | | return mapper.updateDeviceAdapterStatus(adapterId, status, updateBy); |
| | | } |
| | | |
| | | /** 执行一次发现和实时观测,将未登记设备写入 Redis 候选。 */ |
| | |
| | | @Override |
| | | public void synchronizeEnabledAdapters() |
| | | { |
| | | mapper.selectEnabledDeviceAdapters().forEach(adapter -> registry.synchronize(toRuntimeConfig(adapter))); |
| | | for (TDeviceAdapter adapter : mapper.selectEnabledDeviceAdapters()) |
| | | { |
| | | try |
| | | { |
| | | registry.synchronize(toRuntimeConfig(adapter)); |
| | | } |
| | | catch (RuntimeException exception) |
| | | { |
| | | // 单行配置有问题(例如缺少口令环境变量)不得拦住后端启动: |
| | | // 记下原因,由发现轮询按周期重试并把失败持久化到这一行。 |
| | | log.warn("设备适配器实例装配失败 adapterCode={}:{}", adapter.getAdapterCode(), exception.getMessage()); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** 轮询达到周期的已启用适配器,并持久化失败状态后继续调度。 */ |