From 81cbc61f3cee7ef67e37865d491d9052047035bf Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 31 May 2025 10:21:17 +0800 Subject: [PATCH] =?UTF-8?q?reactor=EF=BC=9A=E3=80=90IoT=20=E7=89=A9?= =?UTF-8?q?=E8=81=94=E7=BD=91=E3=80=91=E7=A7=BB=E9=99=A4=20plugin=20?= =?UTF-8?q?=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/device/IoTDeviceUpstreamApiImpl.java | 1 - .../admin/plugin/PluginConfigController.java | 90 --------- .../vo/config/PluginConfigImportReqVO.java | 19 -- .../vo/config/PluginConfigPageReqVO.java | 20 -- .../plugin/vo/config/PluginConfigRespVO.java | 54 ----- .../vo/config/PluginConfigSaveReqVO.java | 56 ------ .../vo/config/PluginConfigStatusReqVO.java | 19 -- .../vo/instance/PluginInstancePageReqVO.java | 35 ---- .../vo/instance/PluginInstanceRespVO.java | 34 ---- .../dataobject/plugin/IotPluginConfigDO.java | 93 --------- .../plugin/IotPluginInstanceDO.java | 70 ------- .../mysql/plugin/IotPluginConfigMapper.java | 33 ---- .../mysql/plugin/IotPluginInstanceMapper.java | 24 --- .../iot/dal/redis/RedisKeyConstants.java | 10 - .../plugin/DevicePluginProcessIdRedisDAO.java | 25 --- .../iot/job/plugin/IotPluginInstancesJob.java | 39 ---- .../IotDeviceDownstreamServiceImpl.java | 61 ++---- .../control/IotDeviceUpstreamServiceImpl.java | 6 +- .../plugin/IotPluginConfigService.java | 100 ---------- .../plugin/IotPluginConfigServiceImpl.java | 187 ------------------ .../plugin/IotPluginInstanceService.java | 71 ------- .../plugin/IotPluginInstanceServiceImpl.java | 171 ---------------- .../src/main/resources/application-dev.yaml | 26 +-- .../src/main/resources/application-local.yaml | 7 +- .../src/main/resources/application.yaml | 5 +- 25 files changed, 17 insertions(+), 1239 deletions(-) delete mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/PluginConfigController.java delete mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/config/PluginConfigImportReqVO.java delete mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/config/PluginConfigPageReqVO.java delete mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/config/PluginConfigRespVO.java delete mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/config/PluginConfigSaveReqVO.java delete mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/config/PluginConfigStatusReqVO.java delete mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/instance/PluginInstancePageReqVO.java delete mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/instance/PluginInstanceRespVO.java delete mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/plugin/IotPluginConfigDO.java delete mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/plugin/IotPluginInstanceDO.java delete mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/plugin/IotPluginConfigMapper.java delete mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/plugin/IotPluginInstanceMapper.java delete mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/redis/plugin/DevicePluginProcessIdRedisDAO.java delete mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/job/plugin/IotPluginInstancesJob.java delete mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/IotPluginConfigService.java delete mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/IotPluginConfigServiceImpl.java delete mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/IotPluginInstanceService.java delete mode 100644 yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/IotPluginInstanceServiceImpl.java diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/api/device/IoTDeviceUpstreamApiImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/api/device/IoTDeviceUpstreamApiImpl.java index 6672fcf734..ca9641563e 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/api/device/IoTDeviceUpstreamApiImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/api/device/IoTDeviceUpstreamApiImpl.java @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.iot.api.device; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.*; import cn.iocoder.yudao.module.iot.service.device.control.IotDeviceUpstreamService; -import cn.iocoder.yudao.module.iot.service.plugin.IotPluginInstanceService; import jakarta.annotation.Resource; import org.springframework.context.annotation.Primary; import org.springframework.validation.annotation.Validated; diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/PluginConfigController.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/PluginConfigController.java deleted file mode 100644 index e21b102410..0000000000 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/PluginConfigController.java +++ /dev/null @@ -1,90 +0,0 @@ -package cn.iocoder.yudao.module.iot.controller.admin.plugin; - -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config.PluginConfigImportReqVO; -import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config.PluginConfigPageReqVO; -import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config.PluginConfigRespVO; -import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config.PluginConfigSaveReqVO; -import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config.PluginConfigStatusReqVO; -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginConfigDO; -import cn.iocoder.yudao.module.iot.service.plugin.IotPluginConfigService; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.tags.Tag; -import jakarta.annotation.Resource; -import jakarta.validation.Valid; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; - -@Tag(name = "管理后台 - IoT 插件配置") -@RestController -@RequestMapping("/iot/plugin-config") -@Validated -public class PluginConfigController { - - @Resource - private IotPluginConfigService pluginConfigService; - - @PostMapping("/create") - @Operation(summary = "创建插件配置") - @PreAuthorize("@ss.hasPermission('iot:plugin-config:create')") - public CommonResult createPluginConfig(@Valid @RequestBody PluginConfigSaveReqVO createReqVO) { - return success(pluginConfigService.createPluginConfig(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新插件配置") - @PreAuthorize("@ss.hasPermission('iot:plugin-config:update')") - public CommonResult updatePluginConfig(@Valid @RequestBody PluginConfigSaveReqVO updateReqVO) { - pluginConfigService.updatePluginConfig(updateReqVO); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除插件配置") - @Parameter(name = "id", description = "编号", required = true) - @PreAuthorize("@ss.hasPermission('iot:plugin-config:delete')") - public CommonResult deletePluginConfig(@RequestParam("id") Long id) { - pluginConfigService.deletePluginConfig(id); - return success(true); - } - - @GetMapping("/get") - @Operation(summary = "获得插件配置") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('iot:plugin-config:query')") - public CommonResult getPluginConfig(@RequestParam("id") Long id) { - IotPluginConfigDO pluginConfig = pluginConfigService.getPluginConfig(id); - return success(BeanUtils.toBean(pluginConfig, PluginConfigRespVO.class)); - } - - @GetMapping("/page") - @Operation(summary = "获得插件配置分页") - @PreAuthorize("@ss.hasPermission('iot:plugin-config:query')") - public CommonResult> getPluginConfigPage(@Valid PluginConfigPageReqVO pageReqVO) { - PageResult pageResult = pluginConfigService.getPluginConfigPage(pageReqVO); - return success(BeanUtils.toBean(pageResult, PluginConfigRespVO.class)); - } - - @PostMapping("/upload-file") - @Operation(summary = "上传插件文件") - @PreAuthorize("@ss.hasPermission('iot:plugin-config:update')") - public CommonResult uploadFile(@Valid PluginConfigImportReqVO reqVO) { - pluginConfigService.uploadFile(reqVO.getId(), reqVO.getFile()); - return success(true); - } - - @PutMapping("/update-status") - @Operation(summary = "修改插件状态") - @PreAuthorize("@ss.hasPermission('iot:plugin-config:update')") - public CommonResult updatePluginConfigStatus(@Valid @RequestBody PluginConfigStatusReqVO reqVO) { - pluginConfigService.updatePluginStatus(reqVO.getId(), reqVO.getStatus()); - return success(true); - } - -} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/config/PluginConfigImportReqVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/config/PluginConfigImportReqVO.java deleted file mode 100644 index b9b277a542..0000000000 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/config/PluginConfigImportReqVO.java +++ /dev/null @@ -1,19 +0,0 @@ -package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config; - -import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.NotNull; -import lombok.Data; -import org.springframework.web.multipart.MultipartFile; - -@Schema(description = "管理后台 - IoT 插件上传 Request VO") -@Data -public class PluginConfigImportReqVO { - - @Schema(description = "主键 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "11546") - private Long id; - - @Schema(description = "插件文件", requiredMode = Schema.RequiredMode.REQUIRED) - @NotNull(message = "插件文件不能为空") - private MultipartFile file; - -} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/config/PluginConfigPageReqVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/config/PluginConfigPageReqVO.java deleted file mode 100644 index 1666d5d6bc..0000000000 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/config/PluginConfigPageReqVO.java +++ /dev/null @@ -1,20 +0,0 @@ -package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config; - -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -@Schema(description = "管理后台 - IoT 插件配置分页 Request VO") -@Data -public class PluginConfigPageReqVO extends PageParam { - - @Schema(description = "插件名称", example = "http") - private String name; - - @Schema(description = "状态", example = "1") - @InEnum(IotPluginStatusEnum.class) - private Integer status; - -} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/config/PluginConfigRespVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/config/PluginConfigRespVO.java deleted file mode 100644 index 2b8c4dcde8..0000000000 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/config/PluginConfigRespVO.java +++ /dev/null @@ -1,54 +0,0 @@ -package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import java.time.LocalDateTime; - -@Schema(description = "管理后台 - IoT 插件配置 Response VO") -@Data -public class PluginConfigRespVO { - - @Schema(description = "主键 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "11546") - private Long id; - - @Schema(description = "插件包标识符", requiredMode = Schema.RequiredMode.REQUIRED, example = "24627") - private String pluginKey; - - @Schema(description = "插件名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六") - private String name; - - @Schema(description = "描述", example = "你猜") - private String description; - - @Schema(description = "部署方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") - private Integer deployType; - - @Schema(description = "插件包文件名", requiredMode = Schema.RequiredMode.REQUIRED) - private String fileName; - - @Schema(description = "插件版本", requiredMode = Schema.RequiredMode.REQUIRED) - private String version; - - @Schema(description = "插件类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") - private Integer type; - - @Schema(description = "设备插件协议类型") - private String protocol; - - @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED) - private Integer status; - - @Schema(description = "插件配置项描述信息") - private String configSchema; - - @Schema(description = "插件配置信息") - private String config; - - @Schema(description = "插件脚本") - private String script; - - @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) - private LocalDateTime createTime; - -} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/config/PluginConfigSaveReqVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/config/PluginConfigSaveReqVO.java deleted file mode 100644 index e48869d645..0000000000 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/config/PluginConfigSaveReqVO.java +++ /dev/null @@ -1,56 +0,0 @@ -package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config; - -import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -@Schema(description = "管理后台 - IoT 插件配置新增/修改 Request VO") -@Data -public class PluginConfigSaveReqVO { - - // TODO @haohao:新增的字段有点多,每个都需要哇? - - // TODO @haohao:一些枚举字段,需要加枚举校验。例如说,deployType、status、type 等 - - @Schema(description = "主键编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11546") - private Long id; - - @Schema(description = "插件包标识符", requiredMode = Schema.RequiredMode.REQUIRED, example = "24627") - private String pluginKey; - - @Schema(description = "插件名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六") - private String name; - - @Schema(description = "描述", example = "你猜") - private String description; - - @Schema(description = "部署方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") - private Integer deployType; - - @Schema(description = "插件包文件名", requiredMode = Schema.RequiredMode.REQUIRED) - private String fileName; - - @Schema(description = "插件版本", requiredMode = Schema.RequiredMode.REQUIRED) - private String version; - - @Schema(description = "插件类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") - private Integer type; - - @Schema(description = "设备插件协议类型") - private String protocol; - - @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED) - @InEnum(IotPluginStatusEnum.class) - private Integer status; - - @Schema(description = "插件配置项描述信息") - private String configSchema; - - @Schema(description = "插件配置信息") - private String config; - - @Schema(description = "插件脚本") - private String script; - -} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/config/PluginConfigStatusReqVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/config/PluginConfigStatusReqVO.java deleted file mode 100644 index eae4aa0a2e..0000000000 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/config/PluginConfigStatusReqVO.java +++ /dev/null @@ -1,19 +0,0 @@ -package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config; - -import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -@Schema(description = "管理后台 - IoT 插件配置状态 Request VO") -@Data -public class PluginConfigStatusReqVO { - - @Schema(description = "主键编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11546") - private Long id; - - @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED) - @InEnum(IotPluginStatusEnum.class) - private Integer status; - -} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/instance/PluginInstancePageReqVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/instance/PluginInstancePageReqVO.java deleted file mode 100644 index e58b88856e..0000000000 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/instance/PluginInstancePageReqVO.java +++ /dev/null @@ -1,35 +0,0 @@ -package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.instance; - -import lombok.*; -import io.swagger.v3.oas.annotations.media.Schema; -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import org.springframework.format.annotation.DateTimeFormat; -import java.time.LocalDateTime; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -// TODO @haohao:后续需要使用下 -@Schema(description = "管理后台 - IoT 插件实例分页 Request VO") -@Data -public class PluginInstancePageReqVO extends PageParam { - - @Schema(description = "插件主程序编号", example = "23738") - private String mainId; - - @Schema(description = "插件id", example = "26498") - private Long pluginId; - - @Schema(description = "插件主程序所在ip") - private String ip; - - @Schema(description = "插件主程序端口") - private Integer port; - - @Schema(description = "心跳时间,心路时间超过30秒需要剔除") - private Long heartbeatAt; - - @Schema(description = "创建时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private LocalDateTime[] createTime; - -} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/instance/PluginInstanceRespVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/instance/PluginInstanceRespVO.java deleted file mode 100644 index cba59fdaf5..0000000000 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/instance/PluginInstanceRespVO.java +++ /dev/null @@ -1,34 +0,0 @@ -package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.instance; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import java.time.LocalDateTime; - -// TODO @haohao:后续需要使用下 -@Schema(description = "管理后台 - IoT 插件实例 Response VO") -@Data -public class PluginInstanceRespVO { - - @Schema(description = "主键编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23864") - private Long id; - - @Schema(description = "插件主程序id", requiredMode = Schema.RequiredMode.REQUIRED, example = "23738") - private String mainId; - - @Schema(description = "插件id", requiredMode = Schema.RequiredMode.REQUIRED, example = "26498") - private Long pluginId; - - @Schema(description = "插件主程序所在ip", requiredMode = Schema.RequiredMode.REQUIRED) - private String ip; - - @Schema(description = "插件主程序端口", requiredMode = Schema.RequiredMode.REQUIRED) - private Integer port; - - @Schema(description = "心跳时间,心路时间超过30秒需要剔除", requiredMode = Schema.RequiredMode.REQUIRED) - private Long heartbeatAt; - - @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) - private LocalDateTime createTime; - -} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/plugin/IotPluginConfigDO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/plugin/IotPluginConfigDO.java deleted file mode 100644 index cb247fc30b..0000000000 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/plugin/IotPluginConfigDO.java +++ /dev/null @@ -1,93 +0,0 @@ -package cn.iocoder.yudao.module.iot.dal.dataobject.plugin; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; -import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginDeployTypeEnum; -import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginTypeEnum; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.*; - -/** - * IoT 插件配置 DO - * - * @author 芋道源码 - */ -@TableName("iot_plugin_config") -@KeySequence("iot_plugin_config_seq") -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class IotPluginConfigDO extends TenantBaseDO { - - /** - * 主键 ID - */ - @TableId - private Long id; - /** - * 插件包标识符 - */ - private String pluginKey; - /** - * 插件名称 - */ - private String name; - /** - * 插件描述 - */ - private String description; - /** - * 部署方式 - *

- * 枚举 {@link IotPluginDeployTypeEnum} - */ - private Integer deployType; - // TODO @芋艿:如果是外置的插件,fileName 和 version 的选择~ - /** - * 插件包文件名 - */ - private String fileName; - /** - * 插件版本 - */ - private String version; - // TODO @芋艿:type 字典的定义 - /** - * 插件类型 - *

- * 枚举 {@link IotPluginTypeEnum} - */ - private Integer type; - /** - * 设备插件协议类型 - */ - // TODO @芋艿:枚举字段 - private String protocol; - // TODO @haohao:这个字段,是不是直接用 CommonStatus,开启、禁用;然后插件实例那,online 是否在线 - /** - * 状态 - *

- * 枚举 {@link CommonStatusEnum} - */ - private Integer status; - - // TODO @芋艿:configSchema、config 示例字段 - /** - * 插件配置项描述信息 - */ - private String configSchema; - /** - * 插件配置信息 - */ - private String config; - - // TODO @芋艿:script 后续的使用 - /** - * 插件脚本 - */ - private String script; - -} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/plugin/IotPluginInstanceDO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/plugin/IotPluginInstanceDO.java deleted file mode 100644 index 34abe893e8..0000000000 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/plugin/IotPluginInstanceDO.java +++ /dev/null @@ -1,70 +0,0 @@ -package cn.iocoder.yudao.module.iot.dal.dataobject.plugin; - -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.*; - -import java.time.LocalDateTime; - -/** - * IoT 插件实例 DO - * - * @author 芋道源码 - */ -@TableName("iot_plugin_instance") -@KeySequence("iot_plugin_instance_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class IotPluginInstanceDO extends TenantBaseDO { - - /** - * 主键 - */ - @TableId - private Long id; - /** - * 插件编号 - *

- * 关联 {@link IotPluginConfigDO#getId()} - */ - private Long pluginId; - /** - * 插件进程编号 - * - * 一般格式是:hostIp@processId@${uuid} - */ - private String processId; - - /** - * 插件实例所在 IP - */ - private String hostIp; - /** - * 设备下行端口 - */ - private Integer downstreamPort; - - /** - * 是否在线 - */ - private Boolean online; - /** - * 在线时间 - */ - private LocalDateTime onlineTime; - /** - * 离线时间 - */ - private LocalDateTime offlineTime; - /** - * 心跳时间 - * - * 目的:心路时间超过一定时间后,会被进行下线处理 - */ - private LocalDateTime heartbeatTime; - -} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/plugin/IotPluginConfigMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/plugin/IotPluginConfigMapper.java deleted file mode 100644 index 0e2163a3fa..0000000000 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/plugin/IotPluginConfigMapper.java +++ /dev/null @@ -1,33 +0,0 @@ -package cn.iocoder.yudao.module.iot.dal.mysql.plugin; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config.PluginConfigPageReqVO; -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginConfigDO; -import org.apache.ibatis.annotations.Mapper; - -import java.util.List; - -@Mapper -public interface IotPluginConfigMapper extends BaseMapperX { - - default PageResult selectPage(PluginConfigPageReqVO reqVO) { - return selectPage(reqVO, new LambdaQueryWrapperX() - .likeIfPresent(IotPluginConfigDO::getName, reqVO.getName()) - .eqIfPresent(IotPluginConfigDO::getStatus, reqVO.getStatus()) - .orderByDesc(IotPluginConfigDO::getId)); - } - - default List selectListByStatusAndDeployType(Integer status, Integer deployType) { - return selectList(new LambdaQueryWrapperX() - .eq(IotPluginConfigDO::getStatus, status) - .eq(IotPluginConfigDO::getDeployType, deployType) - .orderByAsc(IotPluginConfigDO::getId)); - } - - default IotPluginConfigDO selectByPluginKey(String pluginKey) { - return selectOne(IotPluginConfigDO::getPluginKey, pluginKey); - } - -} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/plugin/IotPluginInstanceMapper.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/plugin/IotPluginInstanceMapper.java deleted file mode 100644 index 93ffe87283..0000000000 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/plugin/IotPluginInstanceMapper.java +++ /dev/null @@ -1,24 +0,0 @@ -package cn.iocoder.yudao.module.iot.dal.mysql.plugin; - -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInstanceDO; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import org.apache.ibatis.annotations.Mapper; - -import java.time.LocalDateTime; -import java.util.List; - -// TODO @li:参考 IotOtaUpgradeRecordMapper 的写法 -@Mapper -public interface IotPluginInstanceMapper extends BaseMapperX { - - default IotPluginInstanceDO selectByProcessId(String processId) { - return selectOne(IotPluginInstanceDO::getProcessId, processId); - } - - default List selectListByHeartbeatTimeLt(LocalDateTime heartbeatTime) { - return selectList(new LambdaQueryWrapper() - .lt(IotPluginInstanceDO::getHeartbeatTime, heartbeatTime)); - } - -} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/redis/RedisKeyConstants.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/redis/RedisKeyConstants.java index d09dac72de..0c267517ef 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/redis/RedisKeyConstants.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/redis/RedisKeyConstants.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.iot.dal.redis; import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO; -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInstanceDO; /** * IoT Redis Key 枚举类 @@ -43,13 +42,4 @@ public interface RedisKeyConstants { */ String THING_MODEL_LIST = "iot:thing_model_list"; - /** - * 设备插件的插件进程编号的映射,采用 HASH 结构 - * - * KEY 格式:device_plugin_instance_process_ids - * HASH KEY:${deviceKey} - * VALUE:插件进程编号,对应 {@link IotPluginInstanceDO#getProcessId()} 字段 - */ - String DEVICE_PLUGIN_INSTANCE_PROCESS_IDS = "iot:device_plugin_instance_process_ids"; - } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/redis/plugin/DevicePluginProcessIdRedisDAO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/redis/plugin/DevicePluginProcessIdRedisDAO.java deleted file mode 100644 index 32559d7036..0000000000 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/redis/plugin/DevicePluginProcessIdRedisDAO.java +++ /dev/null @@ -1,25 +0,0 @@ -package cn.iocoder.yudao.module.iot.dal.redis.plugin; - -import cn.iocoder.yudao.module.iot.dal.redis.RedisKeyConstants; -import jakarta.annotation.Resource; -import org.springframework.data.redis.core.StringRedisTemplate; -import org.springframework.stereotype.Repository; - -/** - * 设备插件的插件进程编号的缓存的 Redis DAO - */ -@Repository -public class DevicePluginProcessIdRedisDAO { - - @Resource - private StringRedisTemplate stringRedisTemplate; - - public void put(String deviceKey, String processId) { - stringRedisTemplate.opsForHash().put(RedisKeyConstants.DEVICE_PLUGIN_INSTANCE_PROCESS_IDS, deviceKey, processId); - } - - public String get(String deviceKey) { - return (String) stringRedisTemplate.opsForHash().get(RedisKeyConstants.DEVICE_PLUGIN_INSTANCE_PROCESS_IDS, deviceKey); - } - -} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/job/plugin/IotPluginInstancesJob.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/job/plugin/IotPluginInstancesJob.java deleted file mode 100644 index ff93dc8db0..0000000000 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/job/plugin/IotPluginInstancesJob.java +++ /dev/null @@ -1,39 +0,0 @@ -package cn.iocoder.yudao.module.iot.job.plugin; - -import cn.hutool.core.util.StrUtil; -import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler; -import cn.iocoder.yudao.framework.tenant.core.job.TenantJob; -import cn.iocoder.yudao.module.iot.service.plugin.IotPluginInstanceService; -import org.springframework.stereotype.Component; - -import jakarta.annotation.Resource; -import java.time.Duration; -import java.time.LocalDateTime; - -/** - * IoT 插件实例离线检查 Job - * - * @author 芋道源码 - */ -@Component -public class IotPluginInstancesJob implements JobHandler { - - /** - * 插件离线超时时间 - * - * TODO 芋艿:暂定 10 分钟,后续看要不要做配置 - */ - public static final Duration OFFLINE_TIMEOUT = Duration.ofMinutes(10); - - @Resource - private IotPluginInstanceService pluginInstanceService; - - @Override - @TenantJob - public String execute(String param) { - int count = pluginInstanceService.offlineTimeoutPluginInstance( - LocalDateTime.now().minus(OFFLINE_TIMEOUT)); - return StrUtil.format("离线超时插件实例数量为: {}", count); - } - -} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/control/IotDeviceDownstreamServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/control/IotDeviceDownstreamServiceImpl.java index dcf540ef89..d568d7a42b 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/control/IotDeviceDownstreamServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/control/IotDeviceDownstreamServiceImpl.java @@ -1,25 +1,23 @@ package cn.iocoder.yudao.module.iot.service.device.control; -import cn.hutool.core.exceptions.ExceptionUtil; import cn.hutool.core.lang.Assert; -import cn.hutool.core.util.IdUtil; import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; -import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.*; +import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDeviceConfigSetReqDTO; +import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDeviceOtaUpgradeReqDTO; +import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDevicePropertyGetReqDTO; +import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDeviceServiceInvokeReqDTO; import cn.iocoder.yudao.module.iot.controller.admin.device.vo.control.IotDeviceDownstreamReqVO; import cn.iocoder.yudao.module.iot.core.mq.producer.IotDeviceMessageProducer; import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInstanceDO; import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum; import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageTypeEnum; import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; import cn.iocoder.yudao.module.iot.mq.producer.device.IotDeviceProducer; import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; -import cn.iocoder.yudao.module.iot.service.plugin.IotPluginInstanceService; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; -import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import org.springframework.web.client.RestTemplate; @@ -45,8 +43,6 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic @Resource private IotDeviceService deviceService; - @Resource - private IotPluginInstanceService pluginInstanceService; @Resource private RestTemplate restTemplate; @@ -118,7 +114,8 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic downstreamReqVO.getIdentifier()); IotDeviceServiceInvokeReqDTO reqDTO = new IotDeviceServiceInvokeReqDTO() .setParams((Map) downstreamReqVO.getData()); - CommonResult result = requestPlugin(url, reqDTO, device); +// CommonResult result = requestPlugin(url, reqDTO, device); + CommonResult result = null; // 3. 发送设备消息 IotDeviceMessage message = new IotDeviceMessage().setRequestId(reqDTO.getRequestId()) @@ -187,7 +184,8 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic getProductKey(device, parentDevice), getDeviceName(device, parentDevice)); IotDevicePropertyGetReqDTO reqDTO = new IotDevicePropertyGetReqDTO() .setIdentifiers((List) downstreamReqVO.getData()); - CommonResult result = requestPlugin(url, reqDTO, device); +// CommonResult result = requestPlugin(url, reqDTO, device); + CommonResult result = null; // 3. 发送设备消息 IotDeviceMessage message = new IotDeviceMessage().setRequestId(reqDTO.getRequestId()) @@ -224,7 +222,8 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic getProductKey(device, parentDevice), getDeviceName(device, parentDevice)); IotDeviceConfigSetReqDTO reqDTO = new IotDeviceConfigSetReqDTO() .setConfig(config); - CommonResult result = requestPlugin(url, reqDTO, device); +// CommonResult result = requestPlugin(url, reqDTO, device); + CommonResult result = null; // 3. 发送设备消息 IotDeviceMessage message = new IotDeviceMessage().setRequestId(reqDTO.getRequestId()) @@ -261,7 +260,8 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic String url = String.format("ota/%s/%s/upgrade", getProductKey(device, parentDevice), getDeviceName(device, parentDevice)); IotDeviceOtaUpgradeReqDTO reqDTO = IotDeviceOtaUpgradeReqDTO.build(data); - CommonResult result = requestPlugin(url, reqDTO, device); +// CommonResult result = requestPlugin(url, reqDTO, device); + CommonResult result = null; // 3. 发送设备消息 IotDeviceMessage message = new IotDeviceMessage().setRequestId(reqDTO.getRequestId()) @@ -279,43 +279,6 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic return message; } - /** - * 请求插件 - * - * @param url URL - * @param reqDTO 请求参数,只需要设置子类的参数! - * @param device 设备 - * @return 响应结果 - */ - @SuppressWarnings({ "unchecked", "HttpUrlsUsage" }) - private CommonResult requestPlugin(String url, IotDeviceDownstreamAbstractReqDTO reqDTO, - IotDeviceDO device) { - // 获得设备对应的插件实例 - IotPluginInstanceDO pluginInstance = pluginInstanceService.getPluginInstanceByDeviceKey(device.getDeviceKey()); - if (pluginInstance == null) { - throw exception(DEVICE_DOWNSTREAM_FAILED, "设备找不到对应的插件实例"); - } - - // 补充通用参数 - reqDTO.setRequestId(IdUtil.fastSimpleUUID()); - - // 执行请求 - ResponseEntity> responseEntity; - try { - responseEntity = restTemplate.postForEntity( - String.format("http://%s:%d/%s", pluginInstance.getHostIp(), pluginInstance.getDownstreamPort(), - url), - reqDTO, (Class>) (Class) CommonResult.class); - Assert.isTrue(responseEntity.getStatusCode().is2xxSuccessful(), - "HTTP 状态码不是 2xx,而是" + responseEntity.getStatusCode()); - Assert.notNull(responseEntity.getBody(), "响应结果不能为空"); - } catch (Exception ex) { - log.error("[requestPlugin][设备({}) url({}) 下行消息失败,请求参数({})]", device.getDeviceKey(), url, reqDTO, ex); - throw exception(DEVICE_DOWNSTREAM_FAILED, ExceptionUtil.getMessage(ex)); - } - return responseEntity.getBody(); - } - private void sendDeviceMessage(IotDeviceMessage message, IotDeviceDO device, Integer code) { // 1. 完善消息 message.setProductKey(device.getProductKey()).setDeviceName(device.getDeviceName()) diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/control/IotDeviceUpstreamServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/control/IotDeviceUpstreamServiceImpl.java index 6c80e75ace..329c98b89f 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/control/IotDeviceUpstreamServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/control/IotDeviceUpstreamServiceImpl.java @@ -19,7 +19,6 @@ import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; import cn.iocoder.yudao.module.iot.mq.producer.device.IotDeviceProducer; import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; import cn.iocoder.yudao.module.iot.service.device.data.IotDevicePropertyService; -import cn.iocoder.yudao.module.iot.service.plugin.IotPluginInstanceService; import cn.iocoder.yudao.module.iot.util.MqttSignUtils; import cn.iocoder.yudao.module.iot.util.MqttSignUtils.MqttSignResult; import jakarta.annotation.Resource; @@ -45,8 +44,6 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { private IotDeviceService deviceService; @Resource private IotDevicePropertyService devicePropertyService; - @Resource - private IotPluginInstanceService pluginInstanceService; @Resource private IotDeviceProducer deviceProducer; @@ -315,7 +312,8 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { private void updateDeviceLastTime(IotDeviceDO device, IotDeviceUpstreamAbstractReqDTO reqDTO) { // 1. 【异步】记录设备与插件实例的映射 - pluginInstanceService.updateDevicePluginInstanceProcessIdAsync(device.getDeviceKey(), reqDTO.getProcessId()); +// pluginInstanceService.updateDevicePluginInstanceProcessIdAsync(device.getDeviceKey(), reqDTO.getProcessId()); + // TODO @芋艿:需要单独补充下; // 2. 【异步】更新设备的最后时间 devicePropertyService.updateDeviceReportTimeAsync(device.getDeviceKey(), LocalDateTime.now()); diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/IotPluginConfigService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/IotPluginConfigService.java deleted file mode 100644 index 8b6610f150..0000000000 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/IotPluginConfigService.java +++ /dev/null @@ -1,100 +0,0 @@ -package cn.iocoder.yudao.module.iot.service.plugin; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config.PluginConfigPageReqVO; -import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config.PluginConfigSaveReqVO; -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginConfigDO; -import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginDeployTypeEnum; -import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotEmpty; -import org.springframework.web.multipart.MultipartFile; - -import java.util.List; - -/** - * IoT 插件配置 Service 接口 - * - * @author haohao - */ -public interface IotPluginConfigService { - - /** - * 创建插件配置 - * - * @param createReqVO 创建信息 - * @return 编号 - */ - Long createPluginConfig(@Valid PluginConfigSaveReqVO createReqVO); - - /** - * 更新插件配置 - * - * @param updateReqVO 更新信息 - */ - void updatePluginConfig(@Valid PluginConfigSaveReqVO updateReqVO); - - /** - * 删除插件配置 - * - * @param id 编号 - */ - void deletePluginConfig(Long id); - - /** - * 获得插件配置 - * - * @param id 编号 - * @return 插件配置 - */ - IotPluginConfigDO getPluginConfig(Long id); - - /** - * 获得插件配置分页 - * - * @param pageReqVO 分页查询 - * @return 插件配置分页 - */ - PageResult getPluginConfigPage(PluginConfigPageReqVO pageReqVO); - - /** - * 上传插件的 JAR 包 - * - * @param id 插件id - * @param file 文件 - */ - void uploadFile(Long id, MultipartFile file); - - /** - * 更新插件的状态 - * - * @param id 插件id - * @param status 状态 {@link IotPluginStatusEnum} - */ - void updatePluginStatus(Long id, Integer status); - - /** - * 获得插件配置列表 - * - * @return 插件配置列表 - */ - List getPluginConfigList(); - - /** - * 根据状态和部署类型获得插件配置列表 - * - * @param status 状态 {@link IotPluginStatusEnum} - * @param deployType 部署类型 {@link IotPluginDeployTypeEnum} - * @return 插件配置列表 - */ - List getPluginConfigListByStatusAndDeployType(Integer status, Integer deployType); - - /** - * 根据插件包标识符获取插件配置 - * - * @param pluginKey 插件包标识符 - * @return 插件配置 - */ - IotPluginConfigDO getPluginConfigByPluginKey(@NotEmpty(message = "插件包标识符不能为空") String pluginKey); - -} diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/IotPluginConfigServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/IotPluginConfigServiceImpl.java deleted file mode 100644 index f7cb0972ae..0000000000 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/IotPluginConfigServiceImpl.java +++ /dev/null @@ -1,187 +0,0 @@ -package cn.iocoder.yudao.module.iot.service.plugin; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config.PluginConfigPageReqVO; -import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config.PluginConfigSaveReqVO; -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginConfigDO; -import cn.iocoder.yudao.module.iot.dal.mysql.plugin.IotPluginConfigMapper; -import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum; -import jakarta.annotation.Resource; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.multipart.MultipartFile; - -import java.util.List; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*; - -/** - * IoT 插件配置 Service 实现类 - * - * @author haohao - */ -@Service -@Validated -@Slf4j -public class IotPluginConfigServiceImpl implements IotPluginConfigService { - - @Resource - private IotPluginConfigMapper pluginConfigMapper; - - @Resource - private IotPluginInstanceService pluginInstanceService; - -// @Resource -// private SpringPluginManager springPluginManager; - - @Override - public Long createPluginConfig(PluginConfigSaveReqVO createReqVO) { - // 1. 校验插件标识唯一性:确保没有其他配置使用相同的 pluginKey(新建时 id 为 null) - validatePluginKeyUnique(null, createReqVO.getPluginKey()); - IotPluginConfigDO pluginConfig = BeanUtils.toBean(createReqVO, IotPluginConfigDO.class); - // 2. 插入插件配置到数据库 - pluginConfigMapper.insert(pluginConfig); - return pluginConfig.getId(); - } - - @Override - public void updatePluginConfig(PluginConfigSaveReqVO updateReqVO) { - // 1. 校验插件配置是否存在:根据传入 ID 判断记录是否存在 - validatePluginConfigExists(updateReqVO.getId()); - // 2. 校验插件标识唯一性:确保更新后的 pluginKey 没有被其他记录占用 - validatePluginKeyUnique(updateReqVO.getId(), updateReqVO.getPluginKey()); - // 3. 将更新请求对象转换为插件配置数据对象 - IotPluginConfigDO updateObj = BeanUtils.toBean(updateReqVO, IotPluginConfigDO.class); - pluginConfigMapper.updateById(updateObj); - } - - /** - * 校验插件标识唯一性 - * - * @param id 当前插件配置的 ID(如果为 null 则说明为新建操作) - * @param pluginKey 待校验的插件标识 - */ - private void validatePluginKeyUnique(Long id, String pluginKey) { - // 1. 根据 pluginKey 从数据库中查询已有的插件配置 - IotPluginConfigDO pluginConfig = pluginConfigMapper.selectByPluginKey(pluginKey); - // 2. 如果查询到记录且记录的 ID 与当前 ID 不相同,则认为存在重复,抛出异常 - if (pluginConfig != null && !pluginConfig.getId().equals(id)) { - throw exception(PLUGIN_CONFIG_KEY_DUPLICATE); - } - } - - @Override - public void deletePluginConfig(Long id) { - // 1. 校验存在 - IotPluginConfigDO pluginConfigDO = validatePluginConfigExists(id); - // 2. 未开启状态,才允许删除 - if (IotPluginStatusEnum.RUNNING.getStatus().equals(pluginConfigDO.getStatus())) { - throw exception(PLUGIN_CONFIG_DELETE_FAILED_RUNNING); - } - - // 3. 卸载插件 - pluginInstanceService.stopAndUnloadPlugin(pluginConfigDO.getPluginKey()); - // 4. 删除插件文件 - pluginInstanceService.deletePluginFile(pluginConfigDO); - - // 5. 删除插件配置 - pluginConfigMapper.deleteById(id); - } - - /** - * 校验插件配置是否存在 - * - * @param id 插件配置编号 - * @return 插件配置 - */ - private IotPluginConfigDO validatePluginConfigExists(Long id) { - IotPluginConfigDO pluginConfig = pluginConfigMapper.selectById(id); - if (pluginConfig == null) { - throw exception(PLUGIN_CONFIG_NOT_EXISTS); - } - return pluginConfig; - } - - @Override - public IotPluginConfigDO getPluginConfig(Long id) { - return pluginConfigMapper.selectById(id); - } - - @Override - public PageResult getPluginConfigPage(PluginConfigPageReqVO pageReqVO) { - return pluginConfigMapper.selectPage(pageReqVO); - } - - @Override - public void uploadFile(Long id, MultipartFile file) { - // 1. 校验插件配置是否存在 - IotPluginConfigDO pluginConfigDO = validatePluginConfigExists(id); - - // 2.1 停止并卸载旧的插件 - pluginInstanceService.stopAndUnloadPlugin(pluginConfigDO.getPluginKey()); - // 2.2 上传新的插件文件,更新插件启用状态文件 - String pluginKeyNew = pluginInstanceService.uploadAndLoadNewPlugin(file); - - // 3. 校验 file 相关参数,是否完整 - validatePluginConfigFile(pluginKeyNew); - - // 4. 更新插件配置 -// IotPluginConfigDO updatedPluginConfig = new IotPluginConfigDO() -// .setId(pluginConfigDO.getId()) -// .setPluginKey(pluginKeyNew) -// .setStatus(IotPluginStatusEnum.STOPPED.getStatus()) // TODO @haohao:这个状态,是不是非 stop 哈? -// .setFileName(file.getOriginalFilename()) -// .setScript("") // TODO @haohao:这个设置为 "" 会不会覆盖数据里的哈?应该从插件里读取?未来? -// .setConfigSchema(springPluginManager.getPlugin(pluginKeyNew).getDescriptor().getPluginDescription()) -// .setVersion(springPluginManager.getPlugin(pluginKeyNew).getDescriptor().getVersion()) -// .setDescription(springPluginManager.getPlugin(pluginKeyNew).getDescriptor().getPluginDescription()); -// pluginConfigMapper.updateById(updatedPluginConfig); - } - - /** - * 校验 file 相关参数 - * - * @param pluginKeyNew 插件标识符 - */ - private void validatePluginConfigFile(String pluginKeyNew) { - // TODO @haohao:校验 file 相关参数,是否完整,类似:version 之类是不是可以解析到 -// PluginWrapper plugin = springPluginManager.getPlugin(pluginKeyNew); -// if (plugin == null) { -// throw exception(PLUGIN_INSTALL_FAILED); -// } -// if (plugin.getDescriptor().getVersion() == null) { -// throw exception(PLUGIN_INSTALL_FAILED); -// } - } - - @Override - public void updatePluginStatus(Long id, Integer status) { - // 1. 校验插件配置是否存在 - IotPluginConfigDO pluginConfigDo = validatePluginConfigExists(id); - - // 2. 更新插件状态 - pluginInstanceService.updatePluginStatus(pluginConfigDo, status); - - // 3. 更新数据库中的插件状态 - pluginConfigMapper.updateById(new IotPluginConfigDO().setId(id).setStatus(status)); - } - - @Override - public List getPluginConfigList() { - return pluginConfigMapper.selectList(); - } - - @Override - public List getPluginConfigListByStatusAndDeployType(Integer status, Integer deployType) { - return pluginConfigMapper.selectListByStatusAndDeployType(status, deployType); - } - - @Override - public IotPluginConfigDO getPluginConfigByPluginKey(String pluginKey) { - return pluginConfigMapper.selectByPluginKey(pluginKey); - } - -} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/IotPluginInstanceService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/IotPluginInstanceService.java deleted file mode 100644 index 49351930fc..0000000000 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/IotPluginInstanceService.java +++ /dev/null @@ -1,71 +0,0 @@ -package cn.iocoder.yudao.module.iot.service.plugin; - -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginConfigDO; -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInstanceDO; -import org.springframework.web.multipart.MultipartFile; - -import java.time.LocalDateTime; - -/** - * IoT 插件实例 Service 接口 - * - * @author 芋道源码 - */ -public interface IotPluginInstanceService { - - /** - * 离线超时插件实例 - * - * @param maxHeartbeatTime 最大心跳时间 - */ - int offlineTimeoutPluginInstance(LocalDateTime maxHeartbeatTime); - - /** - * 停止并卸载插件 - * - * @param pluginKey 插件标识符 - */ - void stopAndUnloadPlugin(String pluginKey); - - /** - * 删除插件文件 - * - * @param pluginConfigDO 插件配置 - */ - void deletePluginFile(IotPluginConfigDO pluginConfigDO); - - /** - * 上传并加载新的插件文件 - * - * @param file 插件文件 - * @return 插件标识符 - */ - String uploadAndLoadNewPlugin(MultipartFile file); - - /** - * 更新插件状态 - * - * @param pluginConfigDO 插件配置 - * @param status 新状态 - */ - void updatePluginStatus(IotPluginConfigDO pluginConfigDO, Integer status); - - // ========== 设备与插件的映射操作 ========== - - /** - * 更新设备对应的插件实例的进程编号 - * - * @param deviceKey 设备 Key - * @param processId 进程编号 - */ - void updateDevicePluginInstanceProcessIdAsync(String deviceKey, String processId); - - /** - * 获得设备对应的插件实例 - * - * @param deviceKey 设备 Key - * @return 插件实例 - */ - IotPluginInstanceDO getPluginInstanceByDeviceKey(String deviceKey); - -} \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/IotPluginInstanceServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/IotPluginInstanceServiceImpl.java deleted file mode 100644 index ead0fa86d3..0000000000 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/IotPluginInstanceServiceImpl.java +++ /dev/null @@ -1,171 +0,0 @@ -package cn.iocoder.yudao.module.iot.service.plugin; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.util.StrUtil; -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginConfigDO; -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInstanceDO; -import cn.iocoder.yudao.module.iot.dal.mysql.plugin.IotPluginInstanceMapper; -import cn.iocoder.yudao.module.iot.dal.redis.plugin.DevicePluginProcessIdRedisDAO; -import jakarta.annotation.Resource; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.multipart.MultipartFile; - -import java.io.File; -import java.time.LocalDateTime; -import java.util.List; -import java.util.concurrent.TimeUnit; - -/** - * IoT 插件实例 Service 实现类 - * - * @author 芋道源码 - */ -@Service -@Validated -@Slf4j -public class IotPluginInstanceServiceImpl implements IotPluginInstanceService { - - @Resource - private IotPluginInstanceMapper pluginInstanceMapper; - - @Resource - private DevicePluginProcessIdRedisDAO devicePluginProcessIdRedisDAO; - -// @Resource -// private SpringPluginManager pluginManager; - - @Value("${pf4j.pluginsDir}") - private String pluginsDir; - - @Override - public int offlineTimeoutPluginInstance(LocalDateTime maxHeartbeatTime) { - List list = pluginInstanceMapper.selectListByHeartbeatTimeLt(maxHeartbeatTime); - if (CollUtil.isEmpty(list)) { - return 0; - } - - // 更新插件实例为离线 - int count = 0; - for (IotPluginInstanceDO instance : list) { - pluginInstanceMapper.updateById(IotPluginInstanceDO.builder().id(instance.getId()) - .online(false).offlineTime(LocalDateTime.now()).build()); - count++; - } - return count; - } - - @Override - public void stopAndUnloadPlugin(String pluginKey) { -// PluginWrapper plugin = pluginManager.getPlugin(pluginKey); -// if (plugin == null) { -// log.warn("插件不存在或已卸载: {}", pluginKey); -// return; -// } -// if (plugin.getPluginState().equals(PluginState.STARTED)) { -// pluginManager.stopPlugin(pluginKey); // 停止插件 -// log.info("已停止插件: {}", pluginKey); -// } -// pluginManager.unloadPlugin(pluginKey); // 卸载插件 -// log.info("已卸载插件: {}", pluginKey); - } - - @Override - public void deletePluginFile(IotPluginConfigDO pluginConfigDO) { - File file = new File(pluginsDir, pluginConfigDO.getFileName()); - if (!file.exists()) { - return; - } - try { - TimeUnit.SECONDS.sleep(1); // 等待 1 秒,避免插件未卸载完毕 - if (!file.delete()) { - log.error("[deletePluginFile][删除插件文件({}) 失败]", pluginConfigDO.getFileName()); - } - } catch (InterruptedException e) { - log.error("[deletePluginFile][删除插件文件({}) 失败]", pluginConfigDO.getFileName(), e); - } - } - - @Override - public String uploadAndLoadNewPlugin(MultipartFile file) { -// String pluginKeyNew; -// // TODO @haohao:多节点,是不是要上传 s3 之类的存储器;然后定时去加载 -// Path pluginsPath = Paths.get(pluginsDir); -// try { -// FileUtil.mkdir(pluginsPath.toFile()); // 创建插件目录 -// String filename = file.getOriginalFilename(); -// if (filename != null) { -// Path jarPath = pluginsPath.resolve(filename); -// Files.copy(file.getInputStream(), jarPath, StandardCopyOption.REPLACE_EXISTING); // 保存上传的 JAR 文件 -//// pluginKeyNew = pluginManager.loadPlugin(jarPath.toAbsolutePath()); // 加载插件 -//// log.info("已加载插件: {}", pluginKeyNew); -// } else { -// throw exception(ErrorCodeConstants.PLUGIN_INSTALL_FAILED); -// } -// } catch (IOException e) { -// log.error("[uploadAndLoadNewPlugin][上传插件文件失败]", e); -// throw exception(ErrorCodeConstants.PLUGIN_INSTALL_FAILED, e); -// } catch (Exception e) { -// log.error("[uploadAndLoadNewPlugin][加载插件失败]", e); -// throw exception(ErrorCodeConstants.PLUGIN_INSTALL_FAILED, e); -// } -// return pluginKeyNew; - return null; - } - - @Override - public void updatePluginStatus(IotPluginConfigDO pluginConfigDO, Integer status) { -// String pluginKey = pluginConfigDO.getPluginKey(); -// PluginWrapper plugin = pluginManager.getPlugin(pluginKey); -// -// if (plugin == null) { -// // 插件不存在且状态为停止,抛出异常 -// if (IotPluginStatusEnum.STOPPED.getStatus().equals(pluginConfigDO.getStatus())) { -// throw exception(ErrorCodeConstants.PLUGIN_STATUS_INVALID); -// } -// return; -// } -// -// // 启动插件 -// if (status.equals(IotPluginStatusEnum.RUNNING.getStatus()) -// && plugin.getPluginState() != PluginState.STARTED) { -// try { -// pluginManager.startPlugin(pluginKey); -// } catch (Exception e) { -// log.error("[updatePluginStatus][启动插件({}) 失败]", pluginKey, e); -// throw exception(ErrorCodeConstants.PLUGIN_START_FAILED, e); -// } -// log.info("已启动插件: {}", pluginKey); -// } -// // 停止插件 -// else if (status.equals(IotPluginStatusEnum.STOPPED.getStatus()) -// && plugin.getPluginState() == PluginState.STARTED) { -// try { -// pluginManager.stopPlugin(pluginKey); -// } catch (Exception e) { -// log.error("[updatePluginStatus][停止插件({}) 失败]", pluginKey, e); -// throw exception(ErrorCodeConstants.PLUGIN_STOP_FAILED, e); -// } -// log.info("已停止插件: {}", pluginKey); -// } - } - - // ========== 设备与插件的映射操作 ========== - - @Override - public void updateDevicePluginInstanceProcessIdAsync(String deviceKey, String processId) { - devicePluginProcessIdRedisDAO.put(deviceKey, processId); - } - - @Override - public IotPluginInstanceDO getPluginInstanceByDeviceKey(String deviceKey) { - String processId = devicePluginProcessIdRedisDAO.get(deviceKey); - if (StrUtil.isEmpty(processId)) { - return null; - } - return pluginInstanceMapper.selectByProcessId(processId); - } - -} \ No newline at end of file diff --git a/yudao-server/src/main/resources/application-dev.yaml b/yudao-server/src/main/resources/application-dev.yaml index db07245c63..b1b9b1592e 100644 --- a/yudao-server/src/main/resources/application-dev.yaml +++ b/yudao-server/src/main/resources/application-dev.yaml @@ -198,28 +198,4 @@ justauth: cache: type: REDIS prefix: 'social_auth_state:' # 缓存前缀,目前只对 Redis 缓存生效,默认 JUSTAUTH::STATE:: - timeout: 24h # 超时时长,目前只对 Redis 缓存生效,默认 3 分钟 - - ---- #################### iot相关配置 TODO 芋艿:再瞅瞅 #################### -iot: - emq: - # 账号 - username: anhaohao - # 密码 - password: ahh@123456 - # 主机地址 - hostUrl: tcp://chaojiniu.top:1883 - # 客户端Id,不能相同,采用随机数 ${random.value} - client-id: ${random.int} - # 默认主题 - default-topic: test - # 保持连接 - keepalive: 60 - # 清除会话(设置为false,断开连接,重连后使用原来的会话 保留订阅的主题,能接收离线期间的消息) - clearSession: true - - -# 插件配置 -pf4j: - pluginsDir: ${user.home}/plugins # 插件目录 \ No newline at end of file + timeout: 24h # 超时时长,目前只对 Redis 缓存生效,默认 3 分钟 \ No newline at end of file diff --git a/yudao-server/src/main/resources/application-local.yaml b/yudao-server/src/main/resources/application-local.yaml index 85e385ce94..9ecb5dd446 100644 --- a/yudao-server/src/main/resources/application-local.yaml +++ b/yudao-server/src/main/resources/application-local.yaml @@ -265,9 +265,4 @@ justauth: cache: type: REDIS prefix: 'social_auth_state:' # 缓存前缀,目前只对 Redis 缓存生效,默认 JUSTAUTH::STATE:: - timeout: 24h # 超时时长,目前只对 Redis 缓存生效,默认 3 分钟 - ---- #################### iot相关配置 TODO 芋艿【IOT】:再瞅瞅 #################### -pf4j: -# pluginsDir: /tmp/ - pluginsDir: ../plugins \ No newline at end of file + timeout: 24h # 超时时长,目前只对 Redis 缓存生效,默认 3 分钟 \ No newline at end of file diff --git a/yudao-server/src/main/resources/application.yaml b/yudao-server/src/main/resources/application.yaml index b702244061..1fcb2df444 100644 --- a/yudao-server/src/main/resources/application.yaml +++ b/yudao-server/src/main/resources/application.yaml @@ -315,7 +315,4 @@ yudao: message-bus: type: rocketmq # 消息总线的类型 -debug: false -# 插件配置 TODO 芋艿:【IOT】需要处理下 -pf4j: - pluginsDir: /Users/anhaohao/code/gitee/ruoyi-vue-pro/plugins # 插件目录 \ No newline at end of file +debug: false \ No newline at end of file