Commit 81cbc61f3cee7ef67e37865d491d9052047035bf

Authored by YunaiV
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 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 4 import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.*;
5 5 import cn.iocoder.yudao.module.iot.service.device.control.IotDeviceUpstreamService;
6   -import cn.iocoder.yudao.module.iot.service.plugin.IotPluginInstanceService;
7 6 import jakarta.annotation.Resource;
8 7 import org.springframework.context.annotation.Primary;
9 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 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 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 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 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 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 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 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 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 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 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 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 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 1 package cn.iocoder.yudao.module.iot.dal.redis;
2 2  
3 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 6 * IoT Redis Key 枚举类
... ... @@ -43,13 +42,4 @@ public interface RedisKeyConstants {
43 42 */
44 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 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 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 1 package cn.iocoder.yudao.module.iot.service.device.control;
2 2  
3   -import cn.hutool.core.exceptions.ExceptionUtil;
4 3 import cn.hutool.core.lang.Assert;
5   -import cn.hutool.core.util.IdUtil;
6 4 import cn.iocoder.yudao.framework.common.exception.ServiceException;
7 5 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
8 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 11 import cn.iocoder.yudao.module.iot.controller.admin.device.vo.control.IotDeviceDownstreamReqVO;
11 12 import cn.iocoder.yudao.module.iot.core.mq.producer.IotDeviceMessageProducer;
12 13 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
13   -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInstanceDO;
14 14 import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum;
15 15 import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageTypeEnum;
16 16 import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage;
17 17 import cn.iocoder.yudao.module.iot.mq.producer.device.IotDeviceProducer;
18 18 import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
19   -import cn.iocoder.yudao.module.iot.service.plugin.IotPluginInstanceService;
20 19 import jakarta.annotation.Resource;
21 20 import lombok.extern.slf4j.Slf4j;
22   -import org.springframework.http.ResponseEntity;
23 21 import org.springframework.stereotype.Service;
24 22 import org.springframework.validation.annotation.Validated;
25 23 import org.springframework.web.client.RestTemplate;
... ... @@ -45,8 +43,6 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic
45 43  
46 44 @Resource
47 45 private IotDeviceService deviceService;
48   - @Resource
49   - private IotPluginInstanceService pluginInstanceService;
50 46  
51 47 @Resource
52 48 private RestTemplate restTemplate;
... ... @@ -118,7 +114,8 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic
118 114 downstreamReqVO.getIdentifier());
119 115 IotDeviceServiceInvokeReqDTO reqDTO = new IotDeviceServiceInvokeReqDTO()
120 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 120 // 3. 发送设备消息
124 121 IotDeviceMessage message = new IotDeviceMessage().setRequestId(reqDTO.getRequestId())
... ... @@ -187,7 +184,8 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic
187 184 getProductKey(device, parentDevice), getDeviceName(device, parentDevice));
188 185 IotDevicePropertyGetReqDTO reqDTO = new IotDevicePropertyGetReqDTO()
189 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 190 // 3. 发送设备消息
193 191 IotDeviceMessage message = new IotDeviceMessage().setRequestId(reqDTO.getRequestId())
... ... @@ -224,7 +222,8 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic
224 222 getProductKey(device, parentDevice), getDeviceName(device, parentDevice));
225 223 IotDeviceConfigSetReqDTO reqDTO = new IotDeviceConfigSetReqDTO()
226 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 228 // 3. 发送设备消息
230 229 IotDeviceMessage message = new IotDeviceMessage().setRequestId(reqDTO.getRequestId())
... ... @@ -261,7 +260,8 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic
261 260 String url = String.format("ota/%s/%s/upgrade",
262 261 getProductKey(device, parentDevice), getDeviceName(device, parentDevice));
263 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 266 // 3. 发送设备消息
267 267 IotDeviceMessage message = new IotDeviceMessage().setRequestId(reqDTO.getRequestId())
... ... @@ -279,43 +279,6 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic
279 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 282 private void sendDeviceMessage(IotDeviceMessage message, IotDeviceDO device, Integer code) {
320 283 // 1. 完善消息
321 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 19 import cn.iocoder.yudao.module.iot.mq.producer.device.IotDeviceProducer;
20 20 import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
21 21 import cn.iocoder.yudao.module.iot.service.device.data.IotDevicePropertyService;
22   -import cn.iocoder.yudao.module.iot.service.plugin.IotPluginInstanceService;
23 22 import cn.iocoder.yudao.module.iot.util.MqttSignUtils;
24 23 import cn.iocoder.yudao.module.iot.util.MqttSignUtils.MqttSignResult;
25 24 import jakarta.annotation.Resource;
... ... @@ -45,8 +44,6 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService {
45 44 private IotDeviceService deviceService;
46 45 @Resource
47 46 private IotDevicePropertyService devicePropertyService;
48   - @Resource
49   - private IotPluginInstanceService pluginInstanceService;
50 47  
51 48 @Resource
52 49 private IotDeviceProducer deviceProducer;
... ... @@ -315,7 +312,8 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService {
315 312  
316 313 private void updateDeviceLastTime(IotDeviceDO device, IotDeviceUpstreamAbstractReqDTO reqDTO) {
317 314 // 1. 【异步】记录设备与插件实例的映射
318   - pluginInstanceService.updateDevicePluginInstanceProcessIdAsync(device.getDeviceKey(), reqDTO.getProcessId());
  315 +// pluginInstanceService.updateDevicePluginInstanceProcessIdAsync(device.getDeviceKey(), reqDTO.getProcessId());
  316 + // TODO @芋艿:需要单独补充下;
319 317  
320 318 // 2. 【异步】更新设备的最后时间
321 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 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 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 0 \ No newline at end of file
yudao-server/src/main/resources/application-dev.yaml
... ... @@ -198,28 +198,4 @@ justauth:
198 198 cache:
199 199 type: REDIS
200 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 201 \ No newline at end of file
  202 + timeout: 24h # 超时时长,目前只对 Redis 缓存生效,默认 3 分钟
227 203 \ No newline at end of file
... ...
yudao-server/src/main/resources/application-local.yaml
... ... @@ -265,9 +265,4 @@ justauth:
265 265 cache:
266 266 type: REDIS
267 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 268 \ No newline at end of file
  269 + timeout: 24h # 超时时长,目前只对 Redis 缓存生效,默认 3 分钟
275 270 \ No newline at end of file
... ...
yudao-server/src/main/resources/application.yaml
... ... @@ -315,7 +315,4 @@ yudao:
315 315 message-bus:
316 316 type: rocketmq # 消息总线的类型
317 317  
318   -debug: false
319   -# 插件配置 TODO 芋艿:【IOT】需要处理下
320   -pf4j:
321   - pluginsDir: /Users/anhaohao/code/gitee/ruoyi-vue-pro/plugins # 插件目录
322 318 \ No newline at end of file
  319 +debug: false
323 320 \ No newline at end of file
... ...