Commit 81cbc61f3cee7ef67e37865d491d9052047035bf
1 parent
cf52a16f
reactor:【IoT 物联网】移除 plugin 机制
Showing
25 changed files
with
17 additions
and
1239 deletions
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; | @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.iot.api.device; | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.*; | 4 | import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.*; |
| 5 | import cn.iocoder.yudao.module.iot.service.device.control.IotDeviceUpstreamService; | 5 | import cn.iocoder.yudao.module.iot.service.device.control.IotDeviceUpstreamService; |
| 6 | -import cn.iocoder.yudao.module.iot.service.plugin.IotPluginInstanceService; | ||
| 7 | import jakarta.annotation.Resource; | 6 | import jakarta.annotation.Resource; |
| 8 | import org.springframework.context.annotation.Primary; | 7 | import org.springframework.context.annotation.Primary; |
| 9 | import org.springframework.validation.annotation.Validated; | 8 | import org.springframework.validation.annotation.Validated; |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/PluginConfigController.java deleted
| 1 | -package cn.iocoder.yudao.module.iot.controller.admin.plugin; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||
| 4 | -import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 5 | -import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | ||
| 6 | -import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config.PluginConfigImportReqVO; | ||
| 7 | -import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config.PluginConfigPageReqVO; | ||
| 8 | -import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config.PluginConfigRespVO; | ||
| 9 | -import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config.PluginConfigSaveReqVO; | ||
| 10 | -import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config.PluginConfigStatusReqVO; | ||
| 11 | -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginConfigDO; | ||
| 12 | -import cn.iocoder.yudao.module.iot.service.plugin.IotPluginConfigService; | ||
| 13 | -import io.swagger.v3.oas.annotations.Operation; | ||
| 14 | -import io.swagger.v3.oas.annotations.Parameter; | ||
| 15 | -import io.swagger.v3.oas.annotations.tags.Tag; | ||
| 16 | -import jakarta.annotation.Resource; | ||
| 17 | -import jakarta.validation.Valid; | ||
| 18 | -import org.springframework.security.access.prepost.PreAuthorize; | ||
| 19 | -import org.springframework.validation.annotation.Validated; | ||
| 20 | -import org.springframework.web.bind.annotation.*; | ||
| 21 | - | ||
| 22 | -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | ||
| 23 | - | ||
| 24 | -@Tag(name = "管理后台 - IoT 插件配置") | ||
| 25 | -@RestController | ||
| 26 | -@RequestMapping("/iot/plugin-config") | ||
| 27 | -@Validated | ||
| 28 | -public class PluginConfigController { | ||
| 29 | - | ||
| 30 | - @Resource | ||
| 31 | - private IotPluginConfigService pluginConfigService; | ||
| 32 | - | ||
| 33 | - @PostMapping("/create") | ||
| 34 | - @Operation(summary = "创建插件配置") | ||
| 35 | - @PreAuthorize("@ss.hasPermission('iot:plugin-config:create')") | ||
| 36 | - public CommonResult<Long> createPluginConfig(@Valid @RequestBody PluginConfigSaveReqVO createReqVO) { | ||
| 37 | - return success(pluginConfigService.createPluginConfig(createReqVO)); | ||
| 38 | - } | ||
| 39 | - | ||
| 40 | - @PutMapping("/update") | ||
| 41 | - @Operation(summary = "更新插件配置") | ||
| 42 | - @PreAuthorize("@ss.hasPermission('iot:plugin-config:update')") | ||
| 43 | - public CommonResult<Boolean> updatePluginConfig(@Valid @RequestBody PluginConfigSaveReqVO updateReqVO) { | ||
| 44 | - pluginConfigService.updatePluginConfig(updateReqVO); | ||
| 45 | - return success(true); | ||
| 46 | - } | ||
| 47 | - | ||
| 48 | - @DeleteMapping("/delete") | ||
| 49 | - @Operation(summary = "删除插件配置") | ||
| 50 | - @Parameter(name = "id", description = "编号", required = true) | ||
| 51 | - @PreAuthorize("@ss.hasPermission('iot:plugin-config:delete')") | ||
| 52 | - public CommonResult<Boolean> deletePluginConfig(@RequestParam("id") Long id) { | ||
| 53 | - pluginConfigService.deletePluginConfig(id); | ||
| 54 | - return success(true); | ||
| 55 | - } | ||
| 56 | - | ||
| 57 | - @GetMapping("/get") | ||
| 58 | - @Operation(summary = "获得插件配置") | ||
| 59 | - @Parameter(name = "id", description = "编号", required = true, example = "1024") | ||
| 60 | - @PreAuthorize("@ss.hasPermission('iot:plugin-config:query')") | ||
| 61 | - public CommonResult<PluginConfigRespVO> getPluginConfig(@RequestParam("id") Long id) { | ||
| 62 | - IotPluginConfigDO pluginConfig = pluginConfigService.getPluginConfig(id); | ||
| 63 | - return success(BeanUtils.toBean(pluginConfig, PluginConfigRespVO.class)); | ||
| 64 | - } | ||
| 65 | - | ||
| 66 | - @GetMapping("/page") | ||
| 67 | - @Operation(summary = "获得插件配置分页") | ||
| 68 | - @PreAuthorize("@ss.hasPermission('iot:plugin-config:query')") | ||
| 69 | - public CommonResult<PageResult<PluginConfigRespVO>> getPluginConfigPage(@Valid PluginConfigPageReqVO pageReqVO) { | ||
| 70 | - PageResult<IotPluginConfigDO> pageResult = pluginConfigService.getPluginConfigPage(pageReqVO); | ||
| 71 | - return success(BeanUtils.toBean(pageResult, PluginConfigRespVO.class)); | ||
| 72 | - } | ||
| 73 | - | ||
| 74 | - @PostMapping("/upload-file") | ||
| 75 | - @Operation(summary = "上传插件文件") | ||
| 76 | - @PreAuthorize("@ss.hasPermission('iot:plugin-config:update')") | ||
| 77 | - public CommonResult<Boolean> uploadFile(@Valid PluginConfigImportReqVO reqVO) { | ||
| 78 | - pluginConfigService.uploadFile(reqVO.getId(), reqVO.getFile()); | ||
| 79 | - return success(true); | ||
| 80 | - } | ||
| 81 | - | ||
| 82 | - @PutMapping("/update-status") | ||
| 83 | - @Operation(summary = "修改插件状态") | ||
| 84 | - @PreAuthorize("@ss.hasPermission('iot:plugin-config:update')") | ||
| 85 | - public CommonResult<Boolean> updatePluginConfigStatus(@Valid @RequestBody PluginConfigStatusReqVO reqVO) { | ||
| 86 | - pluginConfigService.updatePluginStatus(reqVO.getId(), reqVO.getStatus()); | ||
| 87 | - return success(true); | ||
| 88 | - } | ||
| 89 | - | ||
| 90 | -} | ||
| 91 | \ No newline at end of file | 0 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/config/PluginConfigImportReqVO.java deleted
| 1 | -package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config; | ||
| 2 | - | ||
| 3 | -import io.swagger.v3.oas.annotations.media.Schema; | ||
| 4 | -import jakarta.validation.constraints.NotNull; | ||
| 5 | -import lombok.Data; | ||
| 6 | -import org.springframework.web.multipart.MultipartFile; | ||
| 7 | - | ||
| 8 | -@Schema(description = "管理后台 - IoT 插件上传 Request VO") | ||
| 9 | -@Data | ||
| 10 | -public class PluginConfigImportReqVO { | ||
| 11 | - | ||
| 12 | - @Schema(description = "主键 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "11546") | ||
| 13 | - private Long id; | ||
| 14 | - | ||
| 15 | - @Schema(description = "插件文件", requiredMode = Schema.RequiredMode.REQUIRED) | ||
| 16 | - @NotNull(message = "插件文件不能为空") | ||
| 17 | - private MultipartFile file; | ||
| 18 | - | ||
| 19 | -} | ||
| 20 | \ No newline at end of file | 0 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/config/PluginConfigPageReqVO.java deleted
| 1 | -package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.framework.common.pojo.PageParam; | ||
| 4 | -import cn.iocoder.yudao.framework.common.validation.InEnum; | ||
| 5 | -import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum; | ||
| 6 | -import io.swagger.v3.oas.annotations.media.Schema; | ||
| 7 | -import lombok.Data; | ||
| 8 | - | ||
| 9 | -@Schema(description = "管理后台 - IoT 插件配置分页 Request VO") | ||
| 10 | -@Data | ||
| 11 | -public class PluginConfigPageReqVO extends PageParam { | ||
| 12 | - | ||
| 13 | - @Schema(description = "插件名称", example = "http") | ||
| 14 | - private String name; | ||
| 15 | - | ||
| 16 | - @Schema(description = "状态", example = "1") | ||
| 17 | - @InEnum(IotPluginStatusEnum.class) | ||
| 18 | - private Integer status; | ||
| 19 | - | ||
| 20 | -} | ||
| 21 | \ No newline at end of file | 0 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/config/PluginConfigRespVO.java deleted
| 1 | -package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config; | ||
| 2 | - | ||
| 3 | -import io.swagger.v3.oas.annotations.media.Schema; | ||
| 4 | -import lombok.Data; | ||
| 5 | - | ||
| 6 | -import java.time.LocalDateTime; | ||
| 7 | - | ||
| 8 | -@Schema(description = "管理后台 - IoT 插件配置 Response VO") | ||
| 9 | -@Data | ||
| 10 | -public class PluginConfigRespVO { | ||
| 11 | - | ||
| 12 | - @Schema(description = "主键 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "11546") | ||
| 13 | - private Long id; | ||
| 14 | - | ||
| 15 | - @Schema(description = "插件包标识符", requiredMode = Schema.RequiredMode.REQUIRED, example = "24627") | ||
| 16 | - private String pluginKey; | ||
| 17 | - | ||
| 18 | - @Schema(description = "插件名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六") | ||
| 19 | - private String name; | ||
| 20 | - | ||
| 21 | - @Schema(description = "描述", example = "你猜") | ||
| 22 | - private String description; | ||
| 23 | - | ||
| 24 | - @Schema(description = "部署方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") | ||
| 25 | - private Integer deployType; | ||
| 26 | - | ||
| 27 | - @Schema(description = "插件包文件名", requiredMode = Schema.RequiredMode.REQUIRED) | ||
| 28 | - private String fileName; | ||
| 29 | - | ||
| 30 | - @Schema(description = "插件版本", requiredMode = Schema.RequiredMode.REQUIRED) | ||
| 31 | - private String version; | ||
| 32 | - | ||
| 33 | - @Schema(description = "插件类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") | ||
| 34 | - private Integer type; | ||
| 35 | - | ||
| 36 | - @Schema(description = "设备插件协议类型") | ||
| 37 | - private String protocol; | ||
| 38 | - | ||
| 39 | - @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED) | ||
| 40 | - private Integer status; | ||
| 41 | - | ||
| 42 | - @Schema(description = "插件配置项描述信息") | ||
| 43 | - private String configSchema; | ||
| 44 | - | ||
| 45 | - @Schema(description = "插件配置信息") | ||
| 46 | - private String config; | ||
| 47 | - | ||
| 48 | - @Schema(description = "插件脚本") | ||
| 49 | - private String script; | ||
| 50 | - | ||
| 51 | - @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) | ||
| 52 | - private LocalDateTime createTime; | ||
| 53 | - | ||
| 54 | -} | ||
| 55 | \ No newline at end of file | 0 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/config/PluginConfigSaveReqVO.java deleted
| 1 | -package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.framework.common.validation.InEnum; | ||
| 4 | -import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum; | ||
| 5 | -import io.swagger.v3.oas.annotations.media.Schema; | ||
| 6 | -import lombok.Data; | ||
| 7 | - | ||
| 8 | -@Schema(description = "管理后台 - IoT 插件配置新增/修改 Request VO") | ||
| 9 | -@Data | ||
| 10 | -public class PluginConfigSaveReqVO { | ||
| 11 | - | ||
| 12 | - // TODO @haohao:新增的字段有点多,每个都需要哇? | ||
| 13 | - | ||
| 14 | - // TODO @haohao:一些枚举字段,需要加枚举校验。例如说,deployType、status、type 等 | ||
| 15 | - | ||
| 16 | - @Schema(description = "主键编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11546") | ||
| 17 | - private Long id; | ||
| 18 | - | ||
| 19 | - @Schema(description = "插件包标识符", requiredMode = Schema.RequiredMode.REQUIRED, example = "24627") | ||
| 20 | - private String pluginKey; | ||
| 21 | - | ||
| 22 | - @Schema(description = "插件名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六") | ||
| 23 | - private String name; | ||
| 24 | - | ||
| 25 | - @Schema(description = "描述", example = "你猜") | ||
| 26 | - private String description; | ||
| 27 | - | ||
| 28 | - @Schema(description = "部署方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") | ||
| 29 | - private Integer deployType; | ||
| 30 | - | ||
| 31 | - @Schema(description = "插件包文件名", requiredMode = Schema.RequiredMode.REQUIRED) | ||
| 32 | - private String fileName; | ||
| 33 | - | ||
| 34 | - @Schema(description = "插件版本", requiredMode = Schema.RequiredMode.REQUIRED) | ||
| 35 | - private String version; | ||
| 36 | - | ||
| 37 | - @Schema(description = "插件类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") | ||
| 38 | - private Integer type; | ||
| 39 | - | ||
| 40 | - @Schema(description = "设备插件协议类型") | ||
| 41 | - private String protocol; | ||
| 42 | - | ||
| 43 | - @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED) | ||
| 44 | - @InEnum(IotPluginStatusEnum.class) | ||
| 45 | - private Integer status; | ||
| 46 | - | ||
| 47 | - @Schema(description = "插件配置项描述信息") | ||
| 48 | - private String configSchema; | ||
| 49 | - | ||
| 50 | - @Schema(description = "插件配置信息") | ||
| 51 | - private String config; | ||
| 52 | - | ||
| 53 | - @Schema(description = "插件脚本") | ||
| 54 | - private String script; | ||
| 55 | - | ||
| 56 | -} | ||
| 57 | \ No newline at end of file | 0 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/config/PluginConfigStatusReqVO.java deleted
| 1 | -package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.framework.common.validation.InEnum; | ||
| 4 | -import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum; | ||
| 5 | -import io.swagger.v3.oas.annotations.media.Schema; | ||
| 6 | -import lombok.Data; | ||
| 7 | - | ||
| 8 | -@Schema(description = "管理后台 - IoT 插件配置状态 Request VO") | ||
| 9 | -@Data | ||
| 10 | -public class PluginConfigStatusReqVO { | ||
| 11 | - | ||
| 12 | - @Schema(description = "主键编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11546") | ||
| 13 | - private Long id; | ||
| 14 | - | ||
| 15 | - @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED) | ||
| 16 | - @InEnum(IotPluginStatusEnum.class) | ||
| 17 | - private Integer status; | ||
| 18 | - | ||
| 19 | -} | ||
| 20 | \ No newline at end of file | 0 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/instance/PluginInstancePageReqVO.java deleted
| 1 | -package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.instance; | ||
| 2 | - | ||
| 3 | -import lombok.*; | ||
| 4 | -import io.swagger.v3.oas.annotations.media.Schema; | ||
| 5 | -import cn.iocoder.yudao.framework.common.pojo.PageParam; | ||
| 6 | -import org.springframework.format.annotation.DateTimeFormat; | ||
| 7 | -import java.time.LocalDateTime; | ||
| 8 | - | ||
| 9 | -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | ||
| 10 | - | ||
| 11 | -// TODO @haohao:后续需要使用下 | ||
| 12 | -@Schema(description = "管理后台 - IoT 插件实例分页 Request VO") | ||
| 13 | -@Data | ||
| 14 | -public class PluginInstancePageReqVO extends PageParam { | ||
| 15 | - | ||
| 16 | - @Schema(description = "插件主程序编号", example = "23738") | ||
| 17 | - private String mainId; | ||
| 18 | - | ||
| 19 | - @Schema(description = "插件id", example = "26498") | ||
| 20 | - private Long pluginId; | ||
| 21 | - | ||
| 22 | - @Schema(description = "插件主程序所在ip") | ||
| 23 | - private String ip; | ||
| 24 | - | ||
| 25 | - @Schema(description = "插件主程序端口") | ||
| 26 | - private Integer port; | ||
| 27 | - | ||
| 28 | - @Schema(description = "心跳时间,心路时间超过30秒需要剔除") | ||
| 29 | - private Long heartbeatAt; | ||
| 30 | - | ||
| 31 | - @Schema(description = "创建时间") | ||
| 32 | - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | ||
| 33 | - private LocalDateTime[] createTime; | ||
| 34 | - | ||
| 35 | -} | ||
| 36 | \ No newline at end of file | 0 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/vo/instance/PluginInstanceRespVO.java deleted
| 1 | -package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.instance; | ||
| 2 | - | ||
| 3 | -import io.swagger.v3.oas.annotations.media.Schema; | ||
| 4 | -import lombok.Data; | ||
| 5 | - | ||
| 6 | -import java.time.LocalDateTime; | ||
| 7 | - | ||
| 8 | -// TODO @haohao:后续需要使用下 | ||
| 9 | -@Schema(description = "管理后台 - IoT 插件实例 Response VO") | ||
| 10 | -@Data | ||
| 11 | -public class PluginInstanceRespVO { | ||
| 12 | - | ||
| 13 | - @Schema(description = "主键编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23864") | ||
| 14 | - private Long id; | ||
| 15 | - | ||
| 16 | - @Schema(description = "插件主程序id", requiredMode = Schema.RequiredMode.REQUIRED, example = "23738") | ||
| 17 | - private String mainId; | ||
| 18 | - | ||
| 19 | - @Schema(description = "插件id", requiredMode = Schema.RequiredMode.REQUIRED, example = "26498") | ||
| 20 | - private Long pluginId; | ||
| 21 | - | ||
| 22 | - @Schema(description = "插件主程序所在ip", requiredMode = Schema.RequiredMode.REQUIRED) | ||
| 23 | - private String ip; | ||
| 24 | - | ||
| 25 | - @Schema(description = "插件主程序端口", requiredMode = Schema.RequiredMode.REQUIRED) | ||
| 26 | - private Integer port; | ||
| 27 | - | ||
| 28 | - @Schema(description = "心跳时间,心路时间超过30秒需要剔除", requiredMode = Schema.RequiredMode.REQUIRED) | ||
| 29 | - private Long heartbeatAt; | ||
| 30 | - | ||
| 31 | - @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) | ||
| 32 | - private LocalDateTime createTime; | ||
| 33 | - | ||
| 34 | -} | ||
| 35 | \ No newline at end of file | 0 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/plugin/IotPluginConfigDO.java deleted
| 1 | -package cn.iocoder.yudao.module.iot.dal.dataobject.plugin; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | ||
| 4 | -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; | ||
| 5 | -import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginDeployTypeEnum; | ||
| 6 | -import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginTypeEnum; | ||
| 7 | -import com.baomidou.mybatisplus.annotation.KeySequence; | ||
| 8 | -import com.baomidou.mybatisplus.annotation.TableId; | ||
| 9 | -import com.baomidou.mybatisplus.annotation.TableName; | ||
| 10 | -import lombok.*; | ||
| 11 | - | ||
| 12 | -/** | ||
| 13 | - * IoT 插件配置 DO | ||
| 14 | - * | ||
| 15 | - * @author 芋道源码 | ||
| 16 | - */ | ||
| 17 | -@TableName("iot_plugin_config") | ||
| 18 | -@KeySequence("iot_plugin_config_seq") | ||
| 19 | -@Data | ||
| 20 | -@Builder | ||
| 21 | -@NoArgsConstructor | ||
| 22 | -@AllArgsConstructor | ||
| 23 | -public class IotPluginConfigDO extends TenantBaseDO { | ||
| 24 | - | ||
| 25 | - /** | ||
| 26 | - * 主键 ID | ||
| 27 | - */ | ||
| 28 | - @TableId | ||
| 29 | - private Long id; | ||
| 30 | - /** | ||
| 31 | - * 插件包标识符 | ||
| 32 | - */ | ||
| 33 | - private String pluginKey; | ||
| 34 | - /** | ||
| 35 | - * 插件名称 | ||
| 36 | - */ | ||
| 37 | - private String name; | ||
| 38 | - /** | ||
| 39 | - * 插件描述 | ||
| 40 | - */ | ||
| 41 | - private String description; | ||
| 42 | - /** | ||
| 43 | - * 部署方式 | ||
| 44 | - * <p> | ||
| 45 | - * 枚举 {@link IotPluginDeployTypeEnum} | ||
| 46 | - */ | ||
| 47 | - private Integer deployType; | ||
| 48 | - // TODO @芋艿:如果是外置的插件,fileName 和 version 的选择~ | ||
| 49 | - /** | ||
| 50 | - * 插件包文件名 | ||
| 51 | - */ | ||
| 52 | - private String fileName; | ||
| 53 | - /** | ||
| 54 | - * 插件版本 | ||
| 55 | - */ | ||
| 56 | - private String version; | ||
| 57 | - // TODO @芋艿:type 字典的定义 | ||
| 58 | - /** | ||
| 59 | - * 插件类型 | ||
| 60 | - * <p> | ||
| 61 | - * 枚举 {@link IotPluginTypeEnum} | ||
| 62 | - */ | ||
| 63 | - private Integer type; | ||
| 64 | - /** | ||
| 65 | - * 设备插件协议类型 | ||
| 66 | - */ | ||
| 67 | - // TODO @芋艿:枚举字段 | ||
| 68 | - private String protocol; | ||
| 69 | - // TODO @haohao:这个字段,是不是直接用 CommonStatus,开启、禁用;然后插件实例那,online 是否在线 | ||
| 70 | - /** | ||
| 71 | - * 状态 | ||
| 72 | - * <p> | ||
| 73 | - * 枚举 {@link CommonStatusEnum} | ||
| 74 | - */ | ||
| 75 | - private Integer status; | ||
| 76 | - | ||
| 77 | - // TODO @芋艿:configSchema、config 示例字段 | ||
| 78 | - /** | ||
| 79 | - * 插件配置项描述信息 | ||
| 80 | - */ | ||
| 81 | - private String configSchema; | ||
| 82 | - /** | ||
| 83 | - * 插件配置信息 | ||
| 84 | - */ | ||
| 85 | - private String config; | ||
| 86 | - | ||
| 87 | - // TODO @芋艿:script 后续的使用 | ||
| 88 | - /** | ||
| 89 | - * 插件脚本 | ||
| 90 | - */ | ||
| 91 | - private String script; | ||
| 92 | - | ||
| 93 | -} | ||
| 94 | \ No newline at end of file | 0 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/plugin/IotPluginInstanceDO.java deleted
| 1 | -package cn.iocoder.yudao.module.iot.dal.dataobject.plugin; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; | ||
| 4 | -import com.baomidou.mybatisplus.annotation.KeySequence; | ||
| 5 | -import com.baomidou.mybatisplus.annotation.TableId; | ||
| 6 | -import com.baomidou.mybatisplus.annotation.TableName; | ||
| 7 | -import lombok.*; | ||
| 8 | - | ||
| 9 | -import java.time.LocalDateTime; | ||
| 10 | - | ||
| 11 | -/** | ||
| 12 | - * IoT 插件实例 DO | ||
| 13 | - * | ||
| 14 | - * @author 芋道源码 | ||
| 15 | - */ | ||
| 16 | -@TableName("iot_plugin_instance") | ||
| 17 | -@KeySequence("iot_plugin_instance_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 | ||
| 18 | -@Data | ||
| 19 | -@Builder | ||
| 20 | -@NoArgsConstructor | ||
| 21 | -@AllArgsConstructor | ||
| 22 | -public class IotPluginInstanceDO extends TenantBaseDO { | ||
| 23 | - | ||
| 24 | - /** | ||
| 25 | - * 主键 | ||
| 26 | - */ | ||
| 27 | - @TableId | ||
| 28 | - private Long id; | ||
| 29 | - /** | ||
| 30 | - * 插件编号 | ||
| 31 | - * <p> | ||
| 32 | - * 关联 {@link IotPluginConfigDO#getId()} | ||
| 33 | - */ | ||
| 34 | - private Long pluginId; | ||
| 35 | - /** | ||
| 36 | - * 插件进程编号 | ||
| 37 | - * | ||
| 38 | - * 一般格式是:hostIp@processId@${uuid} | ||
| 39 | - */ | ||
| 40 | - private String processId; | ||
| 41 | - | ||
| 42 | - /** | ||
| 43 | - * 插件实例所在 IP | ||
| 44 | - */ | ||
| 45 | - private String hostIp; | ||
| 46 | - /** | ||
| 47 | - * 设备下行端口 | ||
| 48 | - */ | ||
| 49 | - private Integer downstreamPort; | ||
| 50 | - | ||
| 51 | - /** | ||
| 52 | - * 是否在线 | ||
| 53 | - */ | ||
| 54 | - private Boolean online; | ||
| 55 | - /** | ||
| 56 | - * 在线时间 | ||
| 57 | - */ | ||
| 58 | - private LocalDateTime onlineTime; | ||
| 59 | - /** | ||
| 60 | - * 离线时间 | ||
| 61 | - */ | ||
| 62 | - private LocalDateTime offlineTime; | ||
| 63 | - /** | ||
| 64 | - * 心跳时间 | ||
| 65 | - * | ||
| 66 | - * 目的:心路时间超过一定时间后,会被进行下线处理 | ||
| 67 | - */ | ||
| 68 | - private LocalDateTime heartbeatTime; | ||
| 69 | - | ||
| 70 | -} | ||
| 71 | \ No newline at end of file | 0 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/plugin/IotPluginConfigMapper.java deleted
| 1 | -package cn.iocoder.yudao.module.iot.dal.mysql.plugin; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 4 | -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | ||
| 5 | -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | ||
| 6 | -import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config.PluginConfigPageReqVO; | ||
| 7 | -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginConfigDO; | ||
| 8 | -import org.apache.ibatis.annotations.Mapper; | ||
| 9 | - | ||
| 10 | -import java.util.List; | ||
| 11 | - | ||
| 12 | -@Mapper | ||
| 13 | -public interface IotPluginConfigMapper extends BaseMapperX<IotPluginConfigDO> { | ||
| 14 | - | ||
| 15 | - default PageResult<IotPluginConfigDO> selectPage(PluginConfigPageReqVO reqVO) { | ||
| 16 | - return selectPage(reqVO, new LambdaQueryWrapperX<IotPluginConfigDO>() | ||
| 17 | - .likeIfPresent(IotPluginConfigDO::getName, reqVO.getName()) | ||
| 18 | - .eqIfPresent(IotPluginConfigDO::getStatus, reqVO.getStatus()) | ||
| 19 | - .orderByDesc(IotPluginConfigDO::getId)); | ||
| 20 | - } | ||
| 21 | - | ||
| 22 | - default List<IotPluginConfigDO> selectListByStatusAndDeployType(Integer status, Integer deployType) { | ||
| 23 | - return selectList(new LambdaQueryWrapperX<IotPluginConfigDO>() | ||
| 24 | - .eq(IotPluginConfigDO::getStatus, status) | ||
| 25 | - .eq(IotPluginConfigDO::getDeployType, deployType) | ||
| 26 | - .orderByAsc(IotPluginConfigDO::getId)); | ||
| 27 | - } | ||
| 28 | - | ||
| 29 | - default IotPluginConfigDO selectByPluginKey(String pluginKey) { | ||
| 30 | - return selectOne(IotPluginConfigDO::getPluginKey, pluginKey); | ||
| 31 | - } | ||
| 32 | - | ||
| 33 | -} | ||
| 34 | \ No newline at end of file | 0 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/plugin/IotPluginInstanceMapper.java deleted
| 1 | -package cn.iocoder.yudao.module.iot.dal.mysql.plugin; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | ||
| 4 | -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInstanceDO; | ||
| 5 | -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||
| 6 | -import org.apache.ibatis.annotations.Mapper; | ||
| 7 | - | ||
| 8 | -import java.time.LocalDateTime; | ||
| 9 | -import java.util.List; | ||
| 10 | - | ||
| 11 | -// TODO @li:参考 IotOtaUpgradeRecordMapper 的写法 | ||
| 12 | -@Mapper | ||
| 13 | -public interface IotPluginInstanceMapper extends BaseMapperX<IotPluginInstanceDO> { | ||
| 14 | - | ||
| 15 | - default IotPluginInstanceDO selectByProcessId(String processId) { | ||
| 16 | - return selectOne(IotPluginInstanceDO::getProcessId, processId); | ||
| 17 | - } | ||
| 18 | - | ||
| 19 | - default List<IotPluginInstanceDO> selectListByHeartbeatTimeLt(LocalDateTime heartbeatTime) { | ||
| 20 | - return selectList(new LambdaQueryWrapper<IotPluginInstanceDO>() | ||
| 21 | - .lt(IotPluginInstanceDO::getHeartbeatTime, heartbeatTime)); | ||
| 22 | - } | ||
| 23 | - | ||
| 24 | -} | ||
| 25 | \ No newline at end of file | 0 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/redis/RedisKeyConstants.java
| 1 | package cn.iocoder.yudao.module.iot.dal.redis; | 1 | package cn.iocoder.yudao.module.iot.dal.redis; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO; | 3 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO; |
| 4 | -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInstanceDO; | ||
| 5 | 4 | ||
| 6 | /** | 5 | /** |
| 7 | * IoT Redis Key 枚举类 | 6 | * IoT Redis Key 枚举类 |
| @@ -43,13 +42,4 @@ public interface RedisKeyConstants { | @@ -43,13 +42,4 @@ public interface RedisKeyConstants { | ||
| 43 | */ | 42 | */ |
| 44 | String THING_MODEL_LIST = "iot:thing_model_list"; | 43 | String THING_MODEL_LIST = "iot:thing_model_list"; |
| 45 | 44 | ||
| 46 | - /** | ||
| 47 | - * 设备插件的插件进程编号的映射,采用 HASH 结构 | ||
| 48 | - * | ||
| 49 | - * KEY 格式:device_plugin_instance_process_ids | ||
| 50 | - * HASH KEY:${deviceKey} | ||
| 51 | - * VALUE:插件进程编号,对应 {@link IotPluginInstanceDO#getProcessId()} 字段 | ||
| 52 | - */ | ||
| 53 | - String DEVICE_PLUGIN_INSTANCE_PROCESS_IDS = "iot:device_plugin_instance_process_ids"; | ||
| 54 | - | ||
| 55 | } | 45 | } |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/redis/plugin/DevicePluginProcessIdRedisDAO.java deleted
| 1 | -package cn.iocoder.yudao.module.iot.dal.redis.plugin; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.module.iot.dal.redis.RedisKeyConstants; | ||
| 4 | -import jakarta.annotation.Resource; | ||
| 5 | -import org.springframework.data.redis.core.StringRedisTemplate; | ||
| 6 | -import org.springframework.stereotype.Repository; | ||
| 7 | - | ||
| 8 | -/** | ||
| 9 | - * 设备插件的插件进程编号的缓存的 Redis DAO | ||
| 10 | - */ | ||
| 11 | -@Repository | ||
| 12 | -public class DevicePluginProcessIdRedisDAO { | ||
| 13 | - | ||
| 14 | - @Resource | ||
| 15 | - private StringRedisTemplate stringRedisTemplate; | ||
| 16 | - | ||
| 17 | - public void put(String deviceKey, String processId) { | ||
| 18 | - stringRedisTemplate.opsForHash().put(RedisKeyConstants.DEVICE_PLUGIN_INSTANCE_PROCESS_IDS, deviceKey, processId); | ||
| 19 | - } | ||
| 20 | - | ||
| 21 | - public String get(String deviceKey) { | ||
| 22 | - return (String) stringRedisTemplate.opsForHash().get(RedisKeyConstants.DEVICE_PLUGIN_INSTANCE_PROCESS_IDS, deviceKey); | ||
| 23 | - } | ||
| 24 | - | ||
| 25 | -} | ||
| 26 | \ No newline at end of file | 0 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/job/plugin/IotPluginInstancesJob.java deleted
| 1 | -package cn.iocoder.yudao.module.iot.job.plugin; | ||
| 2 | - | ||
| 3 | -import cn.hutool.core.util.StrUtil; | ||
| 4 | -import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler; | ||
| 5 | -import cn.iocoder.yudao.framework.tenant.core.job.TenantJob; | ||
| 6 | -import cn.iocoder.yudao.module.iot.service.plugin.IotPluginInstanceService; | ||
| 7 | -import org.springframework.stereotype.Component; | ||
| 8 | - | ||
| 9 | -import jakarta.annotation.Resource; | ||
| 10 | -import java.time.Duration; | ||
| 11 | -import java.time.LocalDateTime; | ||
| 12 | - | ||
| 13 | -/** | ||
| 14 | - * IoT 插件实例离线检查 Job | ||
| 15 | - * | ||
| 16 | - * @author 芋道源码 | ||
| 17 | - */ | ||
| 18 | -@Component | ||
| 19 | -public class IotPluginInstancesJob implements JobHandler { | ||
| 20 | - | ||
| 21 | - /** | ||
| 22 | - * 插件离线超时时间 | ||
| 23 | - * | ||
| 24 | - * TODO 芋艿:暂定 10 分钟,后续看要不要做配置 | ||
| 25 | - */ | ||
| 26 | - public static final Duration OFFLINE_TIMEOUT = Duration.ofMinutes(10); | ||
| 27 | - | ||
| 28 | - @Resource | ||
| 29 | - private IotPluginInstanceService pluginInstanceService; | ||
| 30 | - | ||
| 31 | - @Override | ||
| 32 | - @TenantJob | ||
| 33 | - public String execute(String param) { | ||
| 34 | - int count = pluginInstanceService.offlineTimeoutPluginInstance( | ||
| 35 | - LocalDateTime.now().minus(OFFLINE_TIMEOUT)); | ||
| 36 | - return StrUtil.format("离线超时插件实例数量为: {}", count); | ||
| 37 | - } | ||
| 38 | - | ||
| 39 | -} | ||
| 40 | \ No newline at end of file | 0 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/control/IotDeviceDownstreamServiceImpl.java
| 1 | package cn.iocoder.yudao.module.iot.service.device.control; | 1 | package cn.iocoder.yudao.module.iot.service.device.control; |
| 2 | 2 | ||
| 3 | -import cn.hutool.core.exceptions.ExceptionUtil; | ||
| 4 | import cn.hutool.core.lang.Assert; | 3 | import cn.hutool.core.lang.Assert; |
| 5 | -import cn.hutool.core.util.IdUtil; | ||
| 6 | import cn.iocoder.yudao.framework.common.exception.ServiceException; | 4 | import cn.iocoder.yudao.framework.common.exception.ServiceException; |
| 7 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | 5 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 8 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | 6 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; |
| 9 | -import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.*; | 7 | +import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDeviceConfigSetReqDTO; |
| 8 | +import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDeviceOtaUpgradeReqDTO; | ||
| 9 | +import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDevicePropertyGetReqDTO; | ||
| 10 | +import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDeviceServiceInvokeReqDTO; | ||
| 10 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.control.IotDeviceDownstreamReqVO; | 11 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.control.IotDeviceDownstreamReqVO; |
| 11 | import cn.iocoder.yudao.module.iot.core.mq.producer.IotDeviceMessageProducer; | 12 | import cn.iocoder.yudao.module.iot.core.mq.producer.IotDeviceMessageProducer; |
| 12 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; | 13 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; |
| 13 | -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInstanceDO; | ||
| 14 | import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum; | 14 | import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum; |
| 15 | import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageTypeEnum; | 15 | import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageTypeEnum; |
| 16 | import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | 16 | import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; |
| 17 | import cn.iocoder.yudao.module.iot.mq.producer.device.IotDeviceProducer; | 17 | import cn.iocoder.yudao.module.iot.mq.producer.device.IotDeviceProducer; |
| 18 | import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; | 18 | import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; |
| 19 | -import cn.iocoder.yudao.module.iot.service.plugin.IotPluginInstanceService; | ||
| 20 | import jakarta.annotation.Resource; | 19 | import jakarta.annotation.Resource; |
| 21 | import lombok.extern.slf4j.Slf4j; | 20 | import lombok.extern.slf4j.Slf4j; |
| 22 | -import org.springframework.http.ResponseEntity; | ||
| 23 | import org.springframework.stereotype.Service; | 21 | import org.springframework.stereotype.Service; |
| 24 | import org.springframework.validation.annotation.Validated; | 22 | import org.springframework.validation.annotation.Validated; |
| 25 | import org.springframework.web.client.RestTemplate; | 23 | import org.springframework.web.client.RestTemplate; |
| @@ -45,8 +43,6 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic | @@ -45,8 +43,6 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic | ||
| 45 | 43 | ||
| 46 | @Resource | 44 | @Resource |
| 47 | private IotDeviceService deviceService; | 45 | private IotDeviceService deviceService; |
| 48 | - @Resource | ||
| 49 | - private IotPluginInstanceService pluginInstanceService; | ||
| 50 | 46 | ||
| 51 | @Resource | 47 | @Resource |
| 52 | private RestTemplate restTemplate; | 48 | private RestTemplate restTemplate; |
| @@ -118,7 +114,8 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic | @@ -118,7 +114,8 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic | ||
| 118 | downstreamReqVO.getIdentifier()); | 114 | downstreamReqVO.getIdentifier()); |
| 119 | IotDeviceServiceInvokeReqDTO reqDTO = new IotDeviceServiceInvokeReqDTO() | 115 | IotDeviceServiceInvokeReqDTO reqDTO = new IotDeviceServiceInvokeReqDTO() |
| 120 | .setParams((Map<String, Object>) downstreamReqVO.getData()); | 116 | .setParams((Map<String, Object>) downstreamReqVO.getData()); |
| 121 | - CommonResult<Boolean> result = requestPlugin(url, reqDTO, device); | 117 | +// CommonResult<Boolean> result = requestPlugin(url, reqDTO, device); |
| 118 | + CommonResult<Boolean> result = null; | ||
| 122 | 119 | ||
| 123 | // 3. 发送设备消息 | 120 | // 3. 发送设备消息 |
| 124 | IotDeviceMessage message = new IotDeviceMessage().setRequestId(reqDTO.getRequestId()) | 121 | IotDeviceMessage message = new IotDeviceMessage().setRequestId(reqDTO.getRequestId()) |
| @@ -187,7 +184,8 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic | @@ -187,7 +184,8 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic | ||
| 187 | getProductKey(device, parentDevice), getDeviceName(device, parentDevice)); | 184 | getProductKey(device, parentDevice), getDeviceName(device, parentDevice)); |
| 188 | IotDevicePropertyGetReqDTO reqDTO = new IotDevicePropertyGetReqDTO() | 185 | IotDevicePropertyGetReqDTO reqDTO = new IotDevicePropertyGetReqDTO() |
| 189 | .setIdentifiers((List<String>) downstreamReqVO.getData()); | 186 | .setIdentifiers((List<String>) downstreamReqVO.getData()); |
| 190 | - CommonResult<Boolean> result = requestPlugin(url, reqDTO, device); | 187 | +// CommonResult<Boolean> result = requestPlugin(url, reqDTO, device); |
| 188 | + CommonResult<Boolean> result = null; | ||
| 191 | 189 | ||
| 192 | // 3. 发送设备消息 | 190 | // 3. 发送设备消息 |
| 193 | IotDeviceMessage message = new IotDeviceMessage().setRequestId(reqDTO.getRequestId()) | 191 | IotDeviceMessage message = new IotDeviceMessage().setRequestId(reqDTO.getRequestId()) |
| @@ -224,7 +222,8 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic | @@ -224,7 +222,8 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic | ||
| 224 | getProductKey(device, parentDevice), getDeviceName(device, parentDevice)); | 222 | getProductKey(device, parentDevice), getDeviceName(device, parentDevice)); |
| 225 | IotDeviceConfigSetReqDTO reqDTO = new IotDeviceConfigSetReqDTO() | 223 | IotDeviceConfigSetReqDTO reqDTO = new IotDeviceConfigSetReqDTO() |
| 226 | .setConfig(config); | 224 | .setConfig(config); |
| 227 | - CommonResult<Boolean> result = requestPlugin(url, reqDTO, device); | 225 | +// CommonResult<Boolean> result = requestPlugin(url, reqDTO, device); |
| 226 | + CommonResult<Boolean> result = null; | ||
| 228 | 227 | ||
| 229 | // 3. 发送设备消息 | 228 | // 3. 发送设备消息 |
| 230 | IotDeviceMessage message = new IotDeviceMessage().setRequestId(reqDTO.getRequestId()) | 229 | IotDeviceMessage message = new IotDeviceMessage().setRequestId(reqDTO.getRequestId()) |
| @@ -261,7 +260,8 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic | @@ -261,7 +260,8 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic | ||
| 261 | String url = String.format("ota/%s/%s/upgrade", | 260 | String url = String.format("ota/%s/%s/upgrade", |
| 262 | getProductKey(device, parentDevice), getDeviceName(device, parentDevice)); | 261 | getProductKey(device, parentDevice), getDeviceName(device, parentDevice)); |
| 263 | IotDeviceOtaUpgradeReqDTO reqDTO = IotDeviceOtaUpgradeReqDTO.build(data); | 262 | IotDeviceOtaUpgradeReqDTO reqDTO = IotDeviceOtaUpgradeReqDTO.build(data); |
| 264 | - CommonResult<Boolean> result = requestPlugin(url, reqDTO, device); | 263 | +// CommonResult<Boolean> result = requestPlugin(url, reqDTO, device); |
| 264 | + CommonResult<Boolean> result = null; | ||
| 265 | 265 | ||
| 266 | // 3. 发送设备消息 | 266 | // 3. 发送设备消息 |
| 267 | IotDeviceMessage message = new IotDeviceMessage().setRequestId(reqDTO.getRequestId()) | 267 | IotDeviceMessage message = new IotDeviceMessage().setRequestId(reqDTO.getRequestId()) |
| @@ -279,43 +279,6 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic | @@ -279,43 +279,6 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic | ||
| 279 | return message; | 279 | return message; |
| 280 | } | 280 | } |
| 281 | 281 | ||
| 282 | - /** | ||
| 283 | - * 请求插件 | ||
| 284 | - * | ||
| 285 | - * @param url URL | ||
| 286 | - * @param reqDTO 请求参数,只需要设置子类的参数! | ||
| 287 | - * @param device 设备 | ||
| 288 | - * @return 响应结果 | ||
| 289 | - */ | ||
| 290 | - @SuppressWarnings({ "unchecked", "HttpUrlsUsage" }) | ||
| 291 | - private CommonResult<Boolean> requestPlugin(String url, IotDeviceDownstreamAbstractReqDTO reqDTO, | ||
| 292 | - IotDeviceDO device) { | ||
| 293 | - // 获得设备对应的插件实例 | ||
| 294 | - IotPluginInstanceDO pluginInstance = pluginInstanceService.getPluginInstanceByDeviceKey(device.getDeviceKey()); | ||
| 295 | - if (pluginInstance == null) { | ||
| 296 | - throw exception(DEVICE_DOWNSTREAM_FAILED, "设备找不到对应的插件实例"); | ||
| 297 | - } | ||
| 298 | - | ||
| 299 | - // 补充通用参数 | ||
| 300 | - reqDTO.setRequestId(IdUtil.fastSimpleUUID()); | ||
| 301 | - | ||
| 302 | - // 执行请求 | ||
| 303 | - ResponseEntity<CommonResult<Boolean>> responseEntity; | ||
| 304 | - try { | ||
| 305 | - responseEntity = restTemplate.postForEntity( | ||
| 306 | - String.format("http://%s:%d/%s", pluginInstance.getHostIp(), pluginInstance.getDownstreamPort(), | ||
| 307 | - url), | ||
| 308 | - reqDTO, (Class<CommonResult<Boolean>>) (Class<?>) CommonResult.class); | ||
| 309 | - Assert.isTrue(responseEntity.getStatusCode().is2xxSuccessful(), | ||
| 310 | - "HTTP 状态码不是 2xx,而是" + responseEntity.getStatusCode()); | ||
| 311 | - Assert.notNull(responseEntity.getBody(), "响应结果不能为空"); | ||
| 312 | - } catch (Exception ex) { | ||
| 313 | - log.error("[requestPlugin][设备({}) url({}) 下行消息失败,请求参数({})]", device.getDeviceKey(), url, reqDTO, ex); | ||
| 314 | - throw exception(DEVICE_DOWNSTREAM_FAILED, ExceptionUtil.getMessage(ex)); | ||
| 315 | - } | ||
| 316 | - return responseEntity.getBody(); | ||
| 317 | - } | ||
| 318 | - | ||
| 319 | private void sendDeviceMessage(IotDeviceMessage message, IotDeviceDO device, Integer code) { | 282 | private void sendDeviceMessage(IotDeviceMessage message, IotDeviceDO device, Integer code) { |
| 320 | // 1. 完善消息 | 283 | // 1. 完善消息 |
| 321 | message.setProductKey(device.getProductKey()).setDeviceName(device.getDeviceName()) | 284 | message.setProductKey(device.getProductKey()).setDeviceName(device.getDeviceName()) |
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; | @@ -19,7 +19,6 @@ import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | ||
| 19 | import cn.iocoder.yudao.module.iot.mq.producer.device.IotDeviceProducer; | 19 | import cn.iocoder.yudao.module.iot.mq.producer.device.IotDeviceProducer; |
| 20 | import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; | 20 | import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; |
| 21 | import cn.iocoder.yudao.module.iot.service.device.data.IotDevicePropertyService; | 21 | import cn.iocoder.yudao.module.iot.service.device.data.IotDevicePropertyService; |
| 22 | -import cn.iocoder.yudao.module.iot.service.plugin.IotPluginInstanceService; | ||
| 23 | import cn.iocoder.yudao.module.iot.util.MqttSignUtils; | 22 | import cn.iocoder.yudao.module.iot.util.MqttSignUtils; |
| 24 | import cn.iocoder.yudao.module.iot.util.MqttSignUtils.MqttSignResult; | 23 | import cn.iocoder.yudao.module.iot.util.MqttSignUtils.MqttSignResult; |
| 25 | import jakarta.annotation.Resource; | 24 | import jakarta.annotation.Resource; |
| @@ -45,8 +44,6 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { | @@ -45,8 +44,6 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { | ||
| 45 | private IotDeviceService deviceService; | 44 | private IotDeviceService deviceService; |
| 46 | @Resource | 45 | @Resource |
| 47 | private IotDevicePropertyService devicePropertyService; | 46 | private IotDevicePropertyService devicePropertyService; |
| 48 | - @Resource | ||
| 49 | - private IotPluginInstanceService pluginInstanceService; | ||
| 50 | 47 | ||
| 51 | @Resource | 48 | @Resource |
| 52 | private IotDeviceProducer deviceProducer; | 49 | private IotDeviceProducer deviceProducer; |
| @@ -315,7 +312,8 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { | @@ -315,7 +312,8 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { | ||
| 315 | 312 | ||
| 316 | private void updateDeviceLastTime(IotDeviceDO device, IotDeviceUpstreamAbstractReqDTO reqDTO) { | 313 | private void updateDeviceLastTime(IotDeviceDO device, IotDeviceUpstreamAbstractReqDTO reqDTO) { |
| 317 | // 1. 【异步】记录设备与插件实例的映射 | 314 | // 1. 【异步】记录设备与插件实例的映射 |
| 318 | - pluginInstanceService.updateDevicePluginInstanceProcessIdAsync(device.getDeviceKey(), reqDTO.getProcessId()); | 315 | +// pluginInstanceService.updateDevicePluginInstanceProcessIdAsync(device.getDeviceKey(), reqDTO.getProcessId()); |
| 316 | + // TODO @芋艿:需要单独补充下; | ||
| 319 | 317 | ||
| 320 | // 2. 【异步】更新设备的最后时间 | 318 | // 2. 【异步】更新设备的最后时间 |
| 321 | devicePropertyService.updateDeviceReportTimeAsync(device.getDeviceKey(), LocalDateTime.now()); | 319 | devicePropertyService.updateDeviceReportTimeAsync(device.getDeviceKey(), LocalDateTime.now()); |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/IotPluginConfigService.java deleted
| 1 | -package cn.iocoder.yudao.module.iot.service.plugin; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 4 | -import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config.PluginConfigPageReqVO; | ||
| 5 | -import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config.PluginConfigSaveReqVO; | ||
| 6 | -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginConfigDO; | ||
| 7 | -import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginDeployTypeEnum; | ||
| 8 | -import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum; | ||
| 9 | -import jakarta.validation.Valid; | ||
| 10 | -import jakarta.validation.constraints.NotEmpty; | ||
| 11 | -import org.springframework.web.multipart.MultipartFile; | ||
| 12 | - | ||
| 13 | -import java.util.List; | ||
| 14 | - | ||
| 15 | -/** | ||
| 16 | - * IoT 插件配置 Service 接口 | ||
| 17 | - * | ||
| 18 | - * @author haohao | ||
| 19 | - */ | ||
| 20 | -public interface IotPluginConfigService { | ||
| 21 | - | ||
| 22 | - /** | ||
| 23 | - * 创建插件配置 | ||
| 24 | - * | ||
| 25 | - * @param createReqVO 创建信息 | ||
| 26 | - * @return 编号 | ||
| 27 | - */ | ||
| 28 | - Long createPluginConfig(@Valid PluginConfigSaveReqVO createReqVO); | ||
| 29 | - | ||
| 30 | - /** | ||
| 31 | - * 更新插件配置 | ||
| 32 | - * | ||
| 33 | - * @param updateReqVO 更新信息 | ||
| 34 | - */ | ||
| 35 | - void updatePluginConfig(@Valid PluginConfigSaveReqVO updateReqVO); | ||
| 36 | - | ||
| 37 | - /** | ||
| 38 | - * 删除插件配置 | ||
| 39 | - * | ||
| 40 | - * @param id 编号 | ||
| 41 | - */ | ||
| 42 | - void deletePluginConfig(Long id); | ||
| 43 | - | ||
| 44 | - /** | ||
| 45 | - * 获得插件配置 | ||
| 46 | - * | ||
| 47 | - * @param id 编号 | ||
| 48 | - * @return 插件配置 | ||
| 49 | - */ | ||
| 50 | - IotPluginConfigDO getPluginConfig(Long id); | ||
| 51 | - | ||
| 52 | - /** | ||
| 53 | - * 获得插件配置分页 | ||
| 54 | - * | ||
| 55 | - * @param pageReqVO 分页查询 | ||
| 56 | - * @return 插件配置分页 | ||
| 57 | - */ | ||
| 58 | - PageResult<IotPluginConfigDO> getPluginConfigPage(PluginConfigPageReqVO pageReqVO); | ||
| 59 | - | ||
| 60 | - /** | ||
| 61 | - * 上传插件的 JAR 包 | ||
| 62 | - * | ||
| 63 | - * @param id 插件id | ||
| 64 | - * @param file 文件 | ||
| 65 | - */ | ||
| 66 | - void uploadFile(Long id, MultipartFile file); | ||
| 67 | - | ||
| 68 | - /** | ||
| 69 | - * 更新插件的状态 | ||
| 70 | - * | ||
| 71 | - * @param id 插件id | ||
| 72 | - * @param status 状态 {@link IotPluginStatusEnum} | ||
| 73 | - */ | ||
| 74 | - void updatePluginStatus(Long id, Integer status); | ||
| 75 | - | ||
| 76 | - /** | ||
| 77 | - * 获得插件配置列表 | ||
| 78 | - * | ||
| 79 | - * @return 插件配置列表 | ||
| 80 | - */ | ||
| 81 | - List<IotPluginConfigDO> getPluginConfigList(); | ||
| 82 | - | ||
| 83 | - /** | ||
| 84 | - * 根据状态和部署类型获得插件配置列表 | ||
| 85 | - * | ||
| 86 | - * @param status 状态 {@link IotPluginStatusEnum} | ||
| 87 | - * @param deployType 部署类型 {@link IotPluginDeployTypeEnum} | ||
| 88 | - * @return 插件配置列表 | ||
| 89 | - */ | ||
| 90 | - List<IotPluginConfigDO> getPluginConfigListByStatusAndDeployType(Integer status, Integer deployType); | ||
| 91 | - | ||
| 92 | - /** | ||
| 93 | - * 根据插件包标识符获取插件配置 | ||
| 94 | - * | ||
| 95 | - * @param pluginKey 插件包标识符 | ||
| 96 | - * @return 插件配置 | ||
| 97 | - */ | ||
| 98 | - IotPluginConfigDO getPluginConfigByPluginKey(@NotEmpty(message = "插件包标识符不能为空") String pluginKey); | ||
| 99 | - | ||
| 100 | -} |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/IotPluginConfigServiceImpl.java deleted
| 1 | -package cn.iocoder.yudao.module.iot.service.plugin; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 4 | -import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | ||
| 5 | -import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config.PluginConfigPageReqVO; | ||
| 6 | -import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.config.PluginConfigSaveReqVO; | ||
| 7 | -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginConfigDO; | ||
| 8 | -import cn.iocoder.yudao.module.iot.dal.mysql.plugin.IotPluginConfigMapper; | ||
| 9 | -import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum; | ||
| 10 | -import jakarta.annotation.Resource; | ||
| 11 | -import lombok.extern.slf4j.Slf4j; | ||
| 12 | -import org.springframework.stereotype.Service; | ||
| 13 | -import org.springframework.validation.annotation.Validated; | ||
| 14 | -import org.springframework.web.multipart.MultipartFile; | ||
| 15 | - | ||
| 16 | -import java.util.List; | ||
| 17 | - | ||
| 18 | -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | ||
| 19 | -import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*; | ||
| 20 | - | ||
| 21 | -/** | ||
| 22 | - * IoT 插件配置 Service 实现类 | ||
| 23 | - * | ||
| 24 | - * @author haohao | ||
| 25 | - */ | ||
| 26 | -@Service | ||
| 27 | -@Validated | ||
| 28 | -@Slf4j | ||
| 29 | -public class IotPluginConfigServiceImpl implements IotPluginConfigService { | ||
| 30 | - | ||
| 31 | - @Resource | ||
| 32 | - private IotPluginConfigMapper pluginConfigMapper; | ||
| 33 | - | ||
| 34 | - @Resource | ||
| 35 | - private IotPluginInstanceService pluginInstanceService; | ||
| 36 | - | ||
| 37 | -// @Resource | ||
| 38 | -// private SpringPluginManager springPluginManager; | ||
| 39 | - | ||
| 40 | - @Override | ||
| 41 | - public Long createPluginConfig(PluginConfigSaveReqVO createReqVO) { | ||
| 42 | - // 1. 校验插件标识唯一性:确保没有其他配置使用相同的 pluginKey(新建时 id 为 null) | ||
| 43 | - validatePluginKeyUnique(null, createReqVO.getPluginKey()); | ||
| 44 | - IotPluginConfigDO pluginConfig = BeanUtils.toBean(createReqVO, IotPluginConfigDO.class); | ||
| 45 | - // 2. 插入插件配置到数据库 | ||
| 46 | - pluginConfigMapper.insert(pluginConfig); | ||
| 47 | - return pluginConfig.getId(); | ||
| 48 | - } | ||
| 49 | - | ||
| 50 | - @Override | ||
| 51 | - public void updatePluginConfig(PluginConfigSaveReqVO updateReqVO) { | ||
| 52 | - // 1. 校验插件配置是否存在:根据传入 ID 判断记录是否存在 | ||
| 53 | - validatePluginConfigExists(updateReqVO.getId()); | ||
| 54 | - // 2. 校验插件标识唯一性:确保更新后的 pluginKey 没有被其他记录占用 | ||
| 55 | - validatePluginKeyUnique(updateReqVO.getId(), updateReqVO.getPluginKey()); | ||
| 56 | - // 3. 将更新请求对象转换为插件配置数据对象 | ||
| 57 | - IotPluginConfigDO updateObj = BeanUtils.toBean(updateReqVO, IotPluginConfigDO.class); | ||
| 58 | - pluginConfigMapper.updateById(updateObj); | ||
| 59 | - } | ||
| 60 | - | ||
| 61 | - /** | ||
| 62 | - * 校验插件标识唯一性 | ||
| 63 | - * | ||
| 64 | - * @param id 当前插件配置的 ID(如果为 null 则说明为新建操作) | ||
| 65 | - * @param pluginKey 待校验的插件标识 | ||
| 66 | - */ | ||
| 67 | - private void validatePluginKeyUnique(Long id, String pluginKey) { | ||
| 68 | - // 1. 根据 pluginKey 从数据库中查询已有的插件配置 | ||
| 69 | - IotPluginConfigDO pluginConfig = pluginConfigMapper.selectByPluginKey(pluginKey); | ||
| 70 | - // 2. 如果查询到记录且记录的 ID 与当前 ID 不相同,则认为存在重复,抛出异常 | ||
| 71 | - if (pluginConfig != null && !pluginConfig.getId().equals(id)) { | ||
| 72 | - throw exception(PLUGIN_CONFIG_KEY_DUPLICATE); | ||
| 73 | - } | ||
| 74 | - } | ||
| 75 | - | ||
| 76 | - @Override | ||
| 77 | - public void deletePluginConfig(Long id) { | ||
| 78 | - // 1. 校验存在 | ||
| 79 | - IotPluginConfigDO pluginConfigDO = validatePluginConfigExists(id); | ||
| 80 | - // 2. 未开启状态,才允许删除 | ||
| 81 | - if (IotPluginStatusEnum.RUNNING.getStatus().equals(pluginConfigDO.getStatus())) { | ||
| 82 | - throw exception(PLUGIN_CONFIG_DELETE_FAILED_RUNNING); | ||
| 83 | - } | ||
| 84 | - | ||
| 85 | - // 3. 卸载插件 | ||
| 86 | - pluginInstanceService.stopAndUnloadPlugin(pluginConfigDO.getPluginKey()); | ||
| 87 | - // 4. 删除插件文件 | ||
| 88 | - pluginInstanceService.deletePluginFile(pluginConfigDO); | ||
| 89 | - | ||
| 90 | - // 5. 删除插件配置 | ||
| 91 | - pluginConfigMapper.deleteById(id); | ||
| 92 | - } | ||
| 93 | - | ||
| 94 | - /** | ||
| 95 | - * 校验插件配置是否存在 | ||
| 96 | - * | ||
| 97 | - * @param id 插件配置编号 | ||
| 98 | - * @return 插件配置 | ||
| 99 | - */ | ||
| 100 | - private IotPluginConfigDO validatePluginConfigExists(Long id) { | ||
| 101 | - IotPluginConfigDO pluginConfig = pluginConfigMapper.selectById(id); | ||
| 102 | - if (pluginConfig == null) { | ||
| 103 | - throw exception(PLUGIN_CONFIG_NOT_EXISTS); | ||
| 104 | - } | ||
| 105 | - return pluginConfig; | ||
| 106 | - } | ||
| 107 | - | ||
| 108 | - @Override | ||
| 109 | - public IotPluginConfigDO getPluginConfig(Long id) { | ||
| 110 | - return pluginConfigMapper.selectById(id); | ||
| 111 | - } | ||
| 112 | - | ||
| 113 | - @Override | ||
| 114 | - public PageResult<IotPluginConfigDO> getPluginConfigPage(PluginConfigPageReqVO pageReqVO) { | ||
| 115 | - return pluginConfigMapper.selectPage(pageReqVO); | ||
| 116 | - } | ||
| 117 | - | ||
| 118 | - @Override | ||
| 119 | - public void uploadFile(Long id, MultipartFile file) { | ||
| 120 | - // 1. 校验插件配置是否存在 | ||
| 121 | - IotPluginConfigDO pluginConfigDO = validatePluginConfigExists(id); | ||
| 122 | - | ||
| 123 | - // 2.1 停止并卸载旧的插件 | ||
| 124 | - pluginInstanceService.stopAndUnloadPlugin(pluginConfigDO.getPluginKey()); | ||
| 125 | - // 2.2 上传新的插件文件,更新插件启用状态文件 | ||
| 126 | - String pluginKeyNew = pluginInstanceService.uploadAndLoadNewPlugin(file); | ||
| 127 | - | ||
| 128 | - // 3. 校验 file 相关参数,是否完整 | ||
| 129 | - validatePluginConfigFile(pluginKeyNew); | ||
| 130 | - | ||
| 131 | - // 4. 更新插件配置 | ||
| 132 | -// IotPluginConfigDO updatedPluginConfig = new IotPluginConfigDO() | ||
| 133 | -// .setId(pluginConfigDO.getId()) | ||
| 134 | -// .setPluginKey(pluginKeyNew) | ||
| 135 | -// .setStatus(IotPluginStatusEnum.STOPPED.getStatus()) // TODO @haohao:这个状态,是不是非 stop 哈? | ||
| 136 | -// .setFileName(file.getOriginalFilename()) | ||
| 137 | -// .setScript("") // TODO @haohao:这个设置为 "" 会不会覆盖数据里的哈?应该从插件里读取?未来? | ||
| 138 | -// .setConfigSchema(springPluginManager.getPlugin(pluginKeyNew).getDescriptor().getPluginDescription()) | ||
| 139 | -// .setVersion(springPluginManager.getPlugin(pluginKeyNew).getDescriptor().getVersion()) | ||
| 140 | -// .setDescription(springPluginManager.getPlugin(pluginKeyNew).getDescriptor().getPluginDescription()); | ||
| 141 | -// pluginConfigMapper.updateById(updatedPluginConfig); | ||
| 142 | - } | ||
| 143 | - | ||
| 144 | - /** | ||
| 145 | - * 校验 file 相关参数 | ||
| 146 | - * | ||
| 147 | - * @param pluginKeyNew 插件标识符 | ||
| 148 | - */ | ||
| 149 | - private void validatePluginConfigFile(String pluginKeyNew) { | ||
| 150 | - // TODO @haohao:校验 file 相关参数,是否完整,类似:version 之类是不是可以解析到 | ||
| 151 | -// PluginWrapper plugin = springPluginManager.getPlugin(pluginKeyNew); | ||
| 152 | -// if (plugin == null) { | ||
| 153 | -// throw exception(PLUGIN_INSTALL_FAILED); | ||
| 154 | -// } | ||
| 155 | -// if (plugin.getDescriptor().getVersion() == null) { | ||
| 156 | -// throw exception(PLUGIN_INSTALL_FAILED); | ||
| 157 | -// } | ||
| 158 | - } | ||
| 159 | - | ||
| 160 | - @Override | ||
| 161 | - public void updatePluginStatus(Long id, Integer status) { | ||
| 162 | - // 1. 校验插件配置是否存在 | ||
| 163 | - IotPluginConfigDO pluginConfigDo = validatePluginConfigExists(id); | ||
| 164 | - | ||
| 165 | - // 2. 更新插件状态 | ||
| 166 | - pluginInstanceService.updatePluginStatus(pluginConfigDo, status); | ||
| 167 | - | ||
| 168 | - // 3. 更新数据库中的插件状态 | ||
| 169 | - pluginConfigMapper.updateById(new IotPluginConfigDO().setId(id).setStatus(status)); | ||
| 170 | - } | ||
| 171 | - | ||
| 172 | - @Override | ||
| 173 | - public List<IotPluginConfigDO> getPluginConfigList() { | ||
| 174 | - return pluginConfigMapper.selectList(); | ||
| 175 | - } | ||
| 176 | - | ||
| 177 | - @Override | ||
| 178 | - public List<IotPluginConfigDO> getPluginConfigListByStatusAndDeployType(Integer status, Integer deployType) { | ||
| 179 | - return pluginConfigMapper.selectListByStatusAndDeployType(status, deployType); | ||
| 180 | - } | ||
| 181 | - | ||
| 182 | - @Override | ||
| 183 | - public IotPluginConfigDO getPluginConfigByPluginKey(String pluginKey) { | ||
| 184 | - return pluginConfigMapper.selectByPluginKey(pluginKey); | ||
| 185 | - } | ||
| 186 | - | ||
| 187 | -} | ||
| 188 | \ No newline at end of file | 0 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/IotPluginInstanceService.java deleted
| 1 | -package cn.iocoder.yudao.module.iot.service.plugin; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginConfigDO; | ||
| 4 | -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInstanceDO; | ||
| 5 | -import org.springframework.web.multipart.MultipartFile; | ||
| 6 | - | ||
| 7 | -import java.time.LocalDateTime; | ||
| 8 | - | ||
| 9 | -/** | ||
| 10 | - * IoT 插件实例 Service 接口 | ||
| 11 | - * | ||
| 12 | - * @author 芋道源码 | ||
| 13 | - */ | ||
| 14 | -public interface IotPluginInstanceService { | ||
| 15 | - | ||
| 16 | - /** | ||
| 17 | - * 离线超时插件实例 | ||
| 18 | - * | ||
| 19 | - * @param maxHeartbeatTime 最大心跳时间 | ||
| 20 | - */ | ||
| 21 | - int offlineTimeoutPluginInstance(LocalDateTime maxHeartbeatTime); | ||
| 22 | - | ||
| 23 | - /** | ||
| 24 | - * 停止并卸载插件 | ||
| 25 | - * | ||
| 26 | - * @param pluginKey 插件标识符 | ||
| 27 | - */ | ||
| 28 | - void stopAndUnloadPlugin(String pluginKey); | ||
| 29 | - | ||
| 30 | - /** | ||
| 31 | - * 删除插件文件 | ||
| 32 | - * | ||
| 33 | - * @param pluginConfigDO 插件配置 | ||
| 34 | - */ | ||
| 35 | - void deletePluginFile(IotPluginConfigDO pluginConfigDO); | ||
| 36 | - | ||
| 37 | - /** | ||
| 38 | - * 上传并加载新的插件文件 | ||
| 39 | - * | ||
| 40 | - * @param file 插件文件 | ||
| 41 | - * @return 插件标识符 | ||
| 42 | - */ | ||
| 43 | - String uploadAndLoadNewPlugin(MultipartFile file); | ||
| 44 | - | ||
| 45 | - /** | ||
| 46 | - * 更新插件状态 | ||
| 47 | - * | ||
| 48 | - * @param pluginConfigDO 插件配置 | ||
| 49 | - * @param status 新状态 | ||
| 50 | - */ | ||
| 51 | - void updatePluginStatus(IotPluginConfigDO pluginConfigDO, Integer status); | ||
| 52 | - | ||
| 53 | - // ========== 设备与插件的映射操作 ========== | ||
| 54 | - | ||
| 55 | - /** | ||
| 56 | - * 更新设备对应的插件实例的进程编号 | ||
| 57 | - * | ||
| 58 | - * @param deviceKey 设备 Key | ||
| 59 | - * @param processId 进程编号 | ||
| 60 | - */ | ||
| 61 | - void updateDevicePluginInstanceProcessIdAsync(String deviceKey, String processId); | ||
| 62 | - | ||
| 63 | - /** | ||
| 64 | - * 获得设备对应的插件实例 | ||
| 65 | - * | ||
| 66 | - * @param deviceKey 设备 Key | ||
| 67 | - * @return 插件实例 | ||
| 68 | - */ | ||
| 69 | - IotPluginInstanceDO getPluginInstanceByDeviceKey(String deviceKey); | ||
| 70 | - | ||
| 71 | -} | ||
| 72 | \ No newline at end of file | 0 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/IotPluginInstanceServiceImpl.java deleted
| 1 | -package cn.iocoder.yudao.module.iot.service.plugin; | ||
| 2 | - | ||
| 3 | -import cn.hutool.core.collection.CollUtil; | ||
| 4 | -import cn.hutool.core.util.StrUtil; | ||
| 5 | -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginConfigDO; | ||
| 6 | -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInstanceDO; | ||
| 7 | -import cn.iocoder.yudao.module.iot.dal.mysql.plugin.IotPluginInstanceMapper; | ||
| 8 | -import cn.iocoder.yudao.module.iot.dal.redis.plugin.DevicePluginProcessIdRedisDAO; | ||
| 9 | -import jakarta.annotation.Resource; | ||
| 10 | -import lombok.extern.slf4j.Slf4j; | ||
| 11 | -import org.springframework.beans.factory.annotation.Value; | ||
| 12 | -import org.springframework.stereotype.Service; | ||
| 13 | -import org.springframework.validation.annotation.Validated; | ||
| 14 | -import org.springframework.web.multipart.MultipartFile; | ||
| 15 | - | ||
| 16 | -import java.io.File; | ||
| 17 | -import java.time.LocalDateTime; | ||
| 18 | -import java.util.List; | ||
| 19 | -import java.util.concurrent.TimeUnit; | ||
| 20 | - | ||
| 21 | -/** | ||
| 22 | - * IoT 插件实例 Service 实现类 | ||
| 23 | - * | ||
| 24 | - * @author 芋道源码 | ||
| 25 | - */ | ||
| 26 | -@Service | ||
| 27 | -@Validated | ||
| 28 | -@Slf4j | ||
| 29 | -public class IotPluginInstanceServiceImpl implements IotPluginInstanceService { | ||
| 30 | - | ||
| 31 | - @Resource | ||
| 32 | - private IotPluginInstanceMapper pluginInstanceMapper; | ||
| 33 | - | ||
| 34 | - @Resource | ||
| 35 | - private DevicePluginProcessIdRedisDAO devicePluginProcessIdRedisDAO; | ||
| 36 | - | ||
| 37 | -// @Resource | ||
| 38 | -// private SpringPluginManager pluginManager; | ||
| 39 | - | ||
| 40 | - @Value("${pf4j.pluginsDir}") | ||
| 41 | - private String pluginsDir; | ||
| 42 | - | ||
| 43 | - @Override | ||
| 44 | - public int offlineTimeoutPluginInstance(LocalDateTime maxHeartbeatTime) { | ||
| 45 | - List<IotPluginInstanceDO> list = pluginInstanceMapper.selectListByHeartbeatTimeLt(maxHeartbeatTime); | ||
| 46 | - if (CollUtil.isEmpty(list)) { | ||
| 47 | - return 0; | ||
| 48 | - } | ||
| 49 | - | ||
| 50 | - // 更新插件实例为离线 | ||
| 51 | - int count = 0; | ||
| 52 | - for (IotPluginInstanceDO instance : list) { | ||
| 53 | - pluginInstanceMapper.updateById(IotPluginInstanceDO.builder().id(instance.getId()) | ||
| 54 | - .online(false).offlineTime(LocalDateTime.now()).build()); | ||
| 55 | - count++; | ||
| 56 | - } | ||
| 57 | - return count; | ||
| 58 | - } | ||
| 59 | - | ||
| 60 | - @Override | ||
| 61 | - public void stopAndUnloadPlugin(String pluginKey) { | ||
| 62 | -// PluginWrapper plugin = pluginManager.getPlugin(pluginKey); | ||
| 63 | -// if (plugin == null) { | ||
| 64 | -// log.warn("插件不存在或已卸载: {}", pluginKey); | ||
| 65 | -// return; | ||
| 66 | -// } | ||
| 67 | -// if (plugin.getPluginState().equals(PluginState.STARTED)) { | ||
| 68 | -// pluginManager.stopPlugin(pluginKey); // 停止插件 | ||
| 69 | -// log.info("已停止插件: {}", pluginKey); | ||
| 70 | -// } | ||
| 71 | -// pluginManager.unloadPlugin(pluginKey); // 卸载插件 | ||
| 72 | -// log.info("已卸载插件: {}", pluginKey); | ||
| 73 | - } | ||
| 74 | - | ||
| 75 | - @Override | ||
| 76 | - public void deletePluginFile(IotPluginConfigDO pluginConfigDO) { | ||
| 77 | - File file = new File(pluginsDir, pluginConfigDO.getFileName()); | ||
| 78 | - if (!file.exists()) { | ||
| 79 | - return; | ||
| 80 | - } | ||
| 81 | - try { | ||
| 82 | - TimeUnit.SECONDS.sleep(1); // 等待 1 秒,避免插件未卸载完毕 | ||
| 83 | - if (!file.delete()) { | ||
| 84 | - log.error("[deletePluginFile][删除插件文件({}) 失败]", pluginConfigDO.getFileName()); | ||
| 85 | - } | ||
| 86 | - } catch (InterruptedException e) { | ||
| 87 | - log.error("[deletePluginFile][删除插件文件({}) 失败]", pluginConfigDO.getFileName(), e); | ||
| 88 | - } | ||
| 89 | - } | ||
| 90 | - | ||
| 91 | - @Override | ||
| 92 | - public String uploadAndLoadNewPlugin(MultipartFile file) { | ||
| 93 | -// String pluginKeyNew; | ||
| 94 | -// // TODO @haohao:多节点,是不是要上传 s3 之类的存储器;然后定时去加载 | ||
| 95 | -// Path pluginsPath = Paths.get(pluginsDir); | ||
| 96 | -// try { | ||
| 97 | -// FileUtil.mkdir(pluginsPath.toFile()); // 创建插件目录 | ||
| 98 | -// String filename = file.getOriginalFilename(); | ||
| 99 | -// if (filename != null) { | ||
| 100 | -// Path jarPath = pluginsPath.resolve(filename); | ||
| 101 | -// Files.copy(file.getInputStream(), jarPath, StandardCopyOption.REPLACE_EXISTING); // 保存上传的 JAR 文件 | ||
| 102 | -//// pluginKeyNew = pluginManager.loadPlugin(jarPath.toAbsolutePath()); // 加载插件 | ||
| 103 | -//// log.info("已加载插件: {}", pluginKeyNew); | ||
| 104 | -// } else { | ||
| 105 | -// throw exception(ErrorCodeConstants.PLUGIN_INSTALL_FAILED); | ||
| 106 | -// } | ||
| 107 | -// } catch (IOException e) { | ||
| 108 | -// log.error("[uploadAndLoadNewPlugin][上传插件文件失败]", e); | ||
| 109 | -// throw exception(ErrorCodeConstants.PLUGIN_INSTALL_FAILED, e); | ||
| 110 | -// } catch (Exception e) { | ||
| 111 | -// log.error("[uploadAndLoadNewPlugin][加载插件失败]", e); | ||
| 112 | -// throw exception(ErrorCodeConstants.PLUGIN_INSTALL_FAILED, e); | ||
| 113 | -// } | ||
| 114 | -// return pluginKeyNew; | ||
| 115 | - return null; | ||
| 116 | - } | ||
| 117 | - | ||
| 118 | - @Override | ||
| 119 | - public void updatePluginStatus(IotPluginConfigDO pluginConfigDO, Integer status) { | ||
| 120 | -// String pluginKey = pluginConfigDO.getPluginKey(); | ||
| 121 | -// PluginWrapper plugin = pluginManager.getPlugin(pluginKey); | ||
| 122 | -// | ||
| 123 | -// if (plugin == null) { | ||
| 124 | -// // 插件不存在且状态为停止,抛出异常 | ||
| 125 | -// if (IotPluginStatusEnum.STOPPED.getStatus().equals(pluginConfigDO.getStatus())) { | ||
| 126 | -// throw exception(ErrorCodeConstants.PLUGIN_STATUS_INVALID); | ||
| 127 | -// } | ||
| 128 | -// return; | ||
| 129 | -// } | ||
| 130 | -// | ||
| 131 | -// // 启动插件 | ||
| 132 | -// if (status.equals(IotPluginStatusEnum.RUNNING.getStatus()) | ||
| 133 | -// && plugin.getPluginState() != PluginState.STARTED) { | ||
| 134 | -// try { | ||
| 135 | -// pluginManager.startPlugin(pluginKey); | ||
| 136 | -// } catch (Exception e) { | ||
| 137 | -// log.error("[updatePluginStatus][启动插件({}) 失败]", pluginKey, e); | ||
| 138 | -// throw exception(ErrorCodeConstants.PLUGIN_START_FAILED, e); | ||
| 139 | -// } | ||
| 140 | -// log.info("已启动插件: {}", pluginKey); | ||
| 141 | -// } | ||
| 142 | -// // 停止插件 | ||
| 143 | -// else if (status.equals(IotPluginStatusEnum.STOPPED.getStatus()) | ||
| 144 | -// && plugin.getPluginState() == PluginState.STARTED) { | ||
| 145 | -// try { | ||
| 146 | -// pluginManager.stopPlugin(pluginKey); | ||
| 147 | -// } catch (Exception e) { | ||
| 148 | -// log.error("[updatePluginStatus][停止插件({}) 失败]", pluginKey, e); | ||
| 149 | -// throw exception(ErrorCodeConstants.PLUGIN_STOP_FAILED, e); | ||
| 150 | -// } | ||
| 151 | -// log.info("已停止插件: {}", pluginKey); | ||
| 152 | -// } | ||
| 153 | - } | ||
| 154 | - | ||
| 155 | - // ========== 设备与插件的映射操作 ========== | ||
| 156 | - | ||
| 157 | - @Override | ||
| 158 | - public void updateDevicePluginInstanceProcessIdAsync(String deviceKey, String processId) { | ||
| 159 | - devicePluginProcessIdRedisDAO.put(deviceKey, processId); | ||
| 160 | - } | ||
| 161 | - | ||
| 162 | - @Override | ||
| 163 | - public IotPluginInstanceDO getPluginInstanceByDeviceKey(String deviceKey) { | ||
| 164 | - String processId = devicePluginProcessIdRedisDAO.get(deviceKey); | ||
| 165 | - if (StrUtil.isEmpty(processId)) { | ||
| 166 | - return null; | ||
| 167 | - } | ||
| 168 | - return pluginInstanceMapper.selectByProcessId(processId); | ||
| 169 | - } | ||
| 170 | - | ||
| 171 | -} | ||
| 172 | \ No newline at end of file | 0 | \ No newline at end of file |
yudao-server/src/main/resources/application-dev.yaml
| @@ -198,28 +198,4 @@ justauth: | @@ -198,28 +198,4 @@ justauth: | ||
| 198 | cache: | 198 | cache: |
| 199 | type: REDIS | 199 | type: REDIS |
| 200 | prefix: 'social_auth_state:' # 缓存前缀,目前只对 Redis 缓存生效,默认 JUSTAUTH::STATE:: | 200 | prefix: 'social_auth_state:' # 缓存前缀,目前只对 Redis 缓存生效,默认 JUSTAUTH::STATE:: |
| 201 | - timeout: 24h # 超时时长,目前只对 Redis 缓存生效,默认 3 分钟 | ||
| 202 | - | ||
| 203 | - | ||
| 204 | ---- #################### iot相关配置 TODO 芋艿:再瞅瞅 #################### | ||
| 205 | -iot: | ||
| 206 | - emq: | ||
| 207 | - # 账号 | ||
| 208 | - username: anhaohao | ||
| 209 | - # 密码 | ||
| 210 | - password: ahh@123456 | ||
| 211 | - # 主机地址 | ||
| 212 | - hostUrl: tcp://chaojiniu.top:1883 | ||
| 213 | - # 客户端Id,不能相同,采用随机数 ${random.value} | ||
| 214 | - client-id: ${random.int} | ||
| 215 | - # 默认主题 | ||
| 216 | - default-topic: test | ||
| 217 | - # 保持连接 | ||
| 218 | - keepalive: 60 | ||
| 219 | - # 清除会话(设置为false,断开连接,重连后使用原来的会话 保留订阅的主题,能接收离线期间的消息) | ||
| 220 | - clearSession: true | ||
| 221 | - | ||
| 222 | - | ||
| 223 | -# 插件配置 | ||
| 224 | -pf4j: | ||
| 225 | - pluginsDir: ${user.home}/plugins # 插件目录 | ||
| 226 | \ No newline at end of file | 201 | \ No newline at end of file |
| 202 | + timeout: 24h # 超时时长,目前只对 Redis 缓存生效,默认 3 分钟 | ||
| 227 | \ No newline at end of file | 203 | \ No newline at end of file |
yudao-server/src/main/resources/application-local.yaml
| @@ -265,9 +265,4 @@ justauth: | @@ -265,9 +265,4 @@ justauth: | ||
| 265 | cache: | 265 | cache: |
| 266 | type: REDIS | 266 | type: REDIS |
| 267 | prefix: 'social_auth_state:' # 缓存前缀,目前只对 Redis 缓存生效,默认 JUSTAUTH::STATE:: | 267 | prefix: 'social_auth_state:' # 缓存前缀,目前只对 Redis 缓存生效,默认 JUSTAUTH::STATE:: |
| 268 | - timeout: 24h # 超时时长,目前只对 Redis 缓存生效,默认 3 分钟 | ||
| 269 | - | ||
| 270 | ---- #################### iot相关配置 TODO 芋艿【IOT】:再瞅瞅 #################### | ||
| 271 | -pf4j: | ||
| 272 | -# pluginsDir: /tmp/ | ||
| 273 | - pluginsDir: ../plugins | ||
| 274 | \ No newline at end of file | 268 | \ No newline at end of file |
| 269 | + timeout: 24h # 超时时长,目前只对 Redis 缓存生效,默认 3 分钟 | ||
| 275 | \ No newline at end of file | 270 | \ No newline at end of file |
yudao-server/src/main/resources/application.yaml
| @@ -315,7 +315,4 @@ yudao: | @@ -315,7 +315,4 @@ yudao: | ||
| 315 | message-bus: | 315 | message-bus: |
| 316 | type: rocketmq # 消息总线的类型 | 316 | type: rocketmq # 消息总线的类型 |
| 317 | 317 | ||
| 318 | -debug: false | ||
| 319 | -# 插件配置 TODO 芋艿:【IOT】需要处理下 | ||
| 320 | -pf4j: | ||
| 321 | - pluginsDir: /Users/anhaohao/code/gitee/ruoyi-vue-pro/plugins # 插件目录 | ||
| 322 | \ No newline at end of file | 318 | \ No newline at end of file |
| 319 | +debug: false | ||
| 323 | \ No newline at end of file | 320 | \ No newline at end of file |