Commit 27e08266e085064dbf07bda0cee6b0aff3eddb50
Committed by
Gitee
!1269 【代码优化】IoT: 优化数据桥梁
Merge pull request !1269 from puhui999/iot
Showing
30 changed files
with
858 additions
and
470 deletions
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/DictTypeConstants.java
| @@ -15,5 +15,7 @@ public class DictTypeConstants { | @@ -15,5 +15,7 @@ public class DictTypeConstants { | ||
| 15 | public static final String VALIDATE_TYPE = "iot_validate_type"; | 15 | public static final String VALIDATE_TYPE = "iot_validate_type"; |
| 16 | 16 | ||
| 17 | public static final String DEVICE_STATE = "iot_device_state"; | 17 | public static final String DEVICE_STATE = "iot_device_state"; |
| 18 | + public static final String IOT_DATA_BRIDGE_DIRECTION_ENUM = "iot_data_bridge_direction_enum"; | ||
| 19 | + public static final String IOT_DATA_BRIDGE_TYPE_ENUM = "iot_data_bridge_type_enum"; | ||
| 18 | 20 | ||
| 19 | } | 21 | } |
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java
| @@ -70,4 +70,7 @@ public interface ErrorCodeConstants { | @@ -70,4 +70,7 @@ public interface ErrorCodeConstants { | ||
| 70 | // ========== MQTT 通信相关 1-050-009-000 ========== | 70 | // ========== MQTT 通信相关 1-050-009-000 ========== |
| 71 | ErrorCode MQTT_TOPIC_ILLEGAL = new ErrorCode(1_050_009_000, "topic illegal"); | 71 | ErrorCode MQTT_TOPIC_ILLEGAL = new ErrorCode(1_050_009_000, "topic illegal"); |
| 72 | 72 | ||
| 73 | + // ========== IoT 数据桥梁 1-050-010-000 ========== | ||
| 74 | + ErrorCode DATA_BRIDGE_NOT_EXISTS = new ErrorCode(1_050_010_000, "IoT 数据桥梁不存在"); | ||
| 75 | + | ||
| 73 | } | 76 | } |
| 74 | \ No newline at end of file | 77 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/rule/IotDataBridgDirectionEnum.java renamed to yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/rule/IotDataBridgeDirectionEnum.java
| @@ -13,14 +13,14 @@ import java.util.Arrays; | @@ -13,14 +13,14 @@ import java.util.Arrays; | ||
| 13 | */ | 13 | */ |
| 14 | @RequiredArgsConstructor | 14 | @RequiredArgsConstructor |
| 15 | @Getter | 15 | @Getter |
| 16 | -public enum IotDataBridgDirectionEnum implements ArrayValuable<Integer> { | 16 | +public enum IotDataBridgeDirectionEnum implements ArrayValuable<Integer> { |
| 17 | 17 | ||
| 18 | INPUT(1), // 输入 | 18 | INPUT(1), // 输入 |
| 19 | OUTPUT(2); // 输出 | 19 | OUTPUT(2); // 输出 |
| 20 | 20 | ||
| 21 | private final Integer type; | 21 | private final Integer type; |
| 22 | 22 | ||
| 23 | - public static final Integer[] ARRAYS = Arrays.stream(values()).map(IotDataBridgDirectionEnum::getType).toArray(Integer[]::new); | 23 | + public static final Integer[] ARRAYS = Arrays.stream(values()).map(IotDataBridgeDirectionEnum::getType).toArray(Integer[]::new); |
| 24 | 24 | ||
| 25 | @Override | 25 | @Override |
| 26 | public Integer[] array() { | 26 | public Integer[] array() { |
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/rule/IotDataBridgTypeEnum.java renamed to yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/rule/IotDataBridgeTypeEnum.java
| @@ -13,25 +13,26 @@ import java.util.Arrays; | @@ -13,25 +13,26 @@ import java.util.Arrays; | ||
| 13 | */ | 13 | */ |
| 14 | @RequiredArgsConstructor | 14 | @RequiredArgsConstructor |
| 15 | @Getter | 15 | @Getter |
| 16 | -public enum IotDataBridgTypeEnum implements ArrayValuable<Integer> { | 16 | +public enum IotDataBridgeTypeEnum implements ArrayValuable<Integer> { |
| 17 | 17 | ||
| 18 | - HTTP(1), | ||
| 19 | - TCP(2), | ||
| 20 | - WEBSOCKET(3), | 18 | + HTTP(1, "HTTP"), |
| 19 | + TCP(2, "TCP"), | ||
| 20 | + WEBSOCKET(3, "WEBSOCKET"), | ||
| 21 | 21 | ||
| 22 | - MQTT(10), | 22 | + MQTT(10, "MQTT"), |
| 23 | 23 | ||
| 24 | - DATABASE(20), | ||
| 25 | - REDIS_STREAM(21), | 24 | + DATABASE(20, "DATABASE"), |
| 25 | + REDIS_STREAM(21, "REDIS_STREAM"), | ||
| 26 | 26 | ||
| 27 | - ROCKETMQ(30), | ||
| 28 | - RABBITMQ(31), | ||
| 29 | - KAFKA(32) | ||
| 30 | - ; | 27 | + ROCKETMQ(30, "ROCKETMQ"), |
| 28 | + RABBITMQ(31, "RABBITMQ"), | ||
| 29 | + KAFKA(32, "KAFKA"); | ||
| 31 | 30 | ||
| 32 | private final Integer type; | 31 | private final Integer type; |
| 33 | 32 | ||
| 34 | - public static final Integer[] ARRAYS = Arrays.stream(values()).map(IotDataBridgTypeEnum::getType).toArray(Integer[]::new); | 33 | + private final String name; |
| 34 | + | ||
| 35 | + public static final Integer[] ARRAYS = Arrays.stream(values()).map(IotDataBridgeTypeEnum::getType).toArray(Integer[]::new); | ||
| 35 | 36 | ||
| 36 | @Override | 37 | @Override |
| 37 | public Integer[] array() { | 38 | public Integer[] array() { |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/IotDataBridgeController.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.controller.admin.rule; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; | ||
| 4 | +import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||
| 5 | +import cn.iocoder.yudao.framework.common.pojo.PageParam; | ||
| 6 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 7 | +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | ||
| 8 | +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; | ||
| 9 | +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.IotDataBridgePageReqVO; | ||
| 10 | +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.IotDataBridgeRespVO; | ||
| 11 | +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.IotDataBridgeSaveReqVO; | ||
| 12 | +import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO; | ||
| 13 | +import cn.iocoder.yudao.module.iot.service.rule.IotDataBridgeService; | ||
| 14 | +import io.swagger.v3.oas.annotations.Operation; | ||
| 15 | +import io.swagger.v3.oas.annotations.Parameter; | ||
| 16 | +import io.swagger.v3.oas.annotations.tags.Tag; | ||
| 17 | +import jakarta.annotation.Resource; | ||
| 18 | +import jakarta.servlet.http.HttpServletResponse; | ||
| 19 | +import jakarta.validation.Valid; | ||
| 20 | +import org.springframework.security.access.prepost.PreAuthorize; | ||
| 21 | +import org.springframework.validation.annotation.Validated; | ||
| 22 | +import org.springframework.web.bind.annotation.*; | ||
| 23 | + | ||
| 24 | +import java.io.IOException; | ||
| 25 | +import java.util.List; | ||
| 26 | + | ||
| 27 | +import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; | ||
| 28 | +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | ||
| 29 | + | ||
| 30 | +@Tag(name = "管理后台 - IoT 数据桥梁") | ||
| 31 | +@RestController | ||
| 32 | +@RequestMapping("/iot/data-bridge") | ||
| 33 | +@Validated | ||
| 34 | +public class IotDataBridgeController { | ||
| 35 | + | ||
| 36 | + @Resource | ||
| 37 | + private IotDataBridgeService dataBridgeService; | ||
| 38 | + | ||
| 39 | + @PostMapping("/create") | ||
| 40 | + @Operation(summary = "创建IoT 数据桥梁") | ||
| 41 | + @PreAuthorize("@ss.hasPermission('iot:data-bridge:create')") | ||
| 42 | + public CommonResult<Long> createDataBridge(@Valid @RequestBody IotDataBridgeSaveReqVO createReqVO) { | ||
| 43 | + return success(dataBridgeService.createDataBridge(createReqVO)); | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + @PutMapping("/update") | ||
| 47 | + @Operation(summary = "更新IoT 数据桥梁") | ||
| 48 | + @PreAuthorize("@ss.hasPermission('iot:data-bridge:update')") | ||
| 49 | + public CommonResult<Boolean> updateDataBridge(@Valid @RequestBody IotDataBridgeSaveReqVO updateReqVO) { | ||
| 50 | + dataBridgeService.updateDataBridge(updateReqVO); | ||
| 51 | + return success(true); | ||
| 52 | + } | ||
| 53 | + | ||
| 54 | + @DeleteMapping("/delete") | ||
| 55 | + @Operation(summary = "删除IoT 数据桥梁") | ||
| 56 | + @Parameter(name = "id", description = "编号", required = true) | ||
| 57 | + @PreAuthorize("@ss.hasPermission('iot:data-bridge:delete')") | ||
| 58 | + public CommonResult<Boolean> deleteDataBridge(@RequestParam("id") Long id) { | ||
| 59 | + dataBridgeService.deleteDataBridge(id); | ||
| 60 | + return success(true); | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | + @GetMapping("/get") | ||
| 64 | + @Operation(summary = "获得IoT 数据桥梁") | ||
| 65 | + @Parameter(name = "id", description = "编号", required = true, example = "1024") | ||
| 66 | + @PreAuthorize("@ss.hasPermission('iot:data-bridge:query')") | ||
| 67 | + public CommonResult<IotDataBridgeRespVO> getDataBridge(@RequestParam("id") Long id) { | ||
| 68 | + IotDataBridgeDO dataBridge = dataBridgeService.getDataBridge(id); | ||
| 69 | + return success(BeanUtils.toBean(dataBridge, IotDataBridgeRespVO.class)); | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | + @GetMapping("/page") | ||
| 73 | + @Operation(summary = "获得IoT 数据桥梁分页") | ||
| 74 | + @PreAuthorize("@ss.hasPermission('iot:data-bridge:query')") | ||
| 75 | + public CommonResult<PageResult<IotDataBridgeRespVO>> getDataBridgePage(@Valid IotDataBridgePageReqVO pageReqVO) { | ||
| 76 | + PageResult<IotDataBridgeDO> pageResult = dataBridgeService.getDataBridgePage(pageReqVO); | ||
| 77 | + return success(BeanUtils.toBean(pageResult, IotDataBridgeRespVO.class)); | ||
| 78 | + } | ||
| 79 | + | ||
| 80 | + @GetMapping("/export-excel") | ||
| 81 | + @Operation(summary = "导出IoT 数据桥梁 Excel") | ||
| 82 | + @PreAuthorize("@ss.hasPermission('iot:data-bridge:export')") | ||
| 83 | + @ApiAccessLog(operateType = EXPORT) | ||
| 84 | + public void exportDataBridgeExcel(@Valid IotDataBridgePageReqVO pageReqVO, | ||
| 85 | + HttpServletResponse response) throws IOException { | ||
| 86 | + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); | ||
| 87 | + List<IotDataBridgeDO> list = dataBridgeService.getDataBridgePage(pageReqVO).getList(); | ||
| 88 | + // 导出 Excel | ||
| 89 | + ExcelUtils.write(response, "IoT 数据桥梁.xls", "数据", IotDataBridgeRespVO.class, | ||
| 90 | + BeanUtils.toBean(list, IotDataBridgeRespVO.class)); | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | +} | ||
| 0 | \ No newline at end of file | 94 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/databridge/IotDataBridgePageReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageParam; | ||
| 4 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 5 | +import lombok.Data; | ||
| 6 | +import lombok.EqualsAndHashCode; | ||
| 7 | +import lombok.ToString; | ||
| 8 | +import org.springframework.format.annotation.DateTimeFormat; | ||
| 9 | + | ||
| 10 | +import java.time.LocalDateTime; | ||
| 11 | + | ||
| 12 | +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | ||
| 13 | + | ||
| 14 | +@Schema(description = "管理后台 - IoT 数据桥梁分页 Request VO") | ||
| 15 | +@Data | ||
| 16 | +@EqualsAndHashCode(callSuper = true) | ||
| 17 | +@ToString(callSuper = true) | ||
| 18 | +public class IotDataBridgePageReqVO extends PageParam { | ||
| 19 | + | ||
| 20 | + @Schema(description = "桥梁名称", example = "赵六") | ||
| 21 | + private String name; | ||
| 22 | + | ||
| 23 | + @Schema(description = "桥梁描述", example = "随便") | ||
| 24 | + private String description; | ||
| 25 | + | ||
| 26 | + @Schema(description = "桥梁状态", example = "2") | ||
| 27 | + private Integer status; | ||
| 28 | + | ||
| 29 | + @Schema(description = "桥梁方向") | ||
| 30 | + private Integer direction; | ||
| 31 | + | ||
| 32 | + @Schema(description = "桥梁类型", example = "1") | ||
| 33 | + private Integer type; | ||
| 34 | + | ||
| 35 | + @Schema(description = "创建时间") | ||
| 36 | + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | ||
| 37 | + private LocalDateTime[] createTime; | ||
| 38 | + | ||
| 39 | +} | ||
| 0 | \ No newline at end of file | 40 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/databridge/IotDataBridgeRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; | ||
| 4 | +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; | ||
| 5 | +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config.IotDataBridgeConfig; | ||
| 6 | +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; | ||
| 7 | +import com.alibaba.excel.annotation.ExcelProperty; | ||
| 8 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 9 | +import lombok.Data; | ||
| 10 | + | ||
| 11 | +import java.time.LocalDateTime; | ||
| 12 | + | ||
| 13 | +import static cn.iocoder.yudao.module.iot.enums.DictTypeConstants.IOT_DATA_BRIDGE_DIRECTION_ENUM; | ||
| 14 | +import static cn.iocoder.yudao.module.iot.enums.DictTypeConstants.IOT_DATA_BRIDGE_TYPE_ENUM; | ||
| 15 | +import static cn.iocoder.yudao.module.system.enums.DictTypeConstants.COMMON_STATUS; | ||
| 16 | + | ||
| 17 | +@Schema(description = "管理后台 - IoT 数据桥梁 Response VO") | ||
| 18 | +@Data | ||
| 19 | +@ExcelIgnoreUnannotated | ||
| 20 | +public class IotDataBridgeRespVO { | ||
| 21 | + | ||
| 22 | + @Schema(description = "桥梁编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "18564") | ||
| 23 | + @ExcelProperty("桥梁编号") | ||
| 24 | + private Long id; | ||
| 25 | + | ||
| 26 | + @Schema(description = "桥梁名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六") | ||
| 27 | + @ExcelProperty("桥梁名称") | ||
| 28 | + private String name; | ||
| 29 | + | ||
| 30 | + @Schema(description = "桥梁描述", example = "随便") | ||
| 31 | + @ExcelProperty("桥梁描述") | ||
| 32 | + private String description; | ||
| 33 | + | ||
| 34 | + @Schema(description = "桥梁状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") | ||
| 35 | + @ExcelProperty(value = "桥梁状态", converter = DictConvert.class) | ||
| 36 | + @DictFormat(COMMON_STATUS) | ||
| 37 | + private Integer status; | ||
| 38 | + | ||
| 39 | + @Schema(description = "桥梁方向", requiredMode = Schema.RequiredMode.REQUIRED) | ||
| 40 | + @ExcelProperty(value = "桥梁方向", converter = DictConvert.class) | ||
| 41 | + @DictFormat(IOT_DATA_BRIDGE_DIRECTION_ENUM) | ||
| 42 | + private Integer direction; | ||
| 43 | + | ||
| 44 | + @Schema(description = "桥梁类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | ||
| 45 | + @ExcelProperty(value = "桥梁类型", converter = DictConvert.class) | ||
| 46 | + @DictFormat(IOT_DATA_BRIDGE_TYPE_ENUM) | ||
| 47 | + private Integer type; | ||
| 48 | + | ||
| 49 | + @Schema(description = "桥梁配置") | ||
| 50 | + @ExcelProperty("桥梁配置") | ||
| 51 | + private IotDataBridgeConfig config; | ||
| 52 | + | ||
| 53 | + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) | ||
| 54 | + @ExcelProperty("创建时间") | ||
| 55 | + private LocalDateTime createTime; | ||
| 56 | + | ||
| 57 | +} | ||
| 0 | \ No newline at end of file | 58 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/databridge/IotDataBridgeSaveReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config.IotDataBridgeConfig; | ||
| 4 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 5 | +import jakarta.validation.constraints.NotEmpty; | ||
| 6 | +import jakarta.validation.constraints.NotNull; | ||
| 7 | +import lombok.Data; | ||
| 8 | + | ||
| 9 | +@Schema(description = "管理后台 - IoT 数据桥梁新增/修改 Request VO") | ||
| 10 | +@Data | ||
| 11 | +public class IotDataBridgeSaveReqVO { | ||
| 12 | + | ||
| 13 | + @Schema(description = "桥梁编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "18564") | ||
| 14 | + private Long id; | ||
| 15 | + | ||
| 16 | + @Schema(description = "桥梁名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六") | ||
| 17 | + @NotEmpty(message = "桥梁名称不能为空") | ||
| 18 | + private String name; | ||
| 19 | + | ||
| 20 | + @Schema(description = "桥梁描述", example = "随便") | ||
| 21 | + private String description; | ||
| 22 | + | ||
| 23 | + @Schema(description = "桥梁状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") | ||
| 24 | + @NotNull(message = "桥梁状态不能为空") | ||
| 25 | + private Integer status; | ||
| 26 | + | ||
| 27 | + @Schema(description = "桥梁方向", requiredMode = Schema.RequiredMode.REQUIRED) | ||
| 28 | + @NotNull(message = "桥梁方向不能为空") | ||
| 29 | + private Integer direction; | ||
| 30 | + | ||
| 31 | + @Schema(description = "桥梁类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | ||
| 32 | + @NotNull(message = "桥梁类型不能为空") | ||
| 33 | + private Integer type; | ||
| 34 | + | ||
| 35 | + @Schema(description = "桥梁配置") | ||
| 36 | + @NotNull(message = "桥梁配置不能为空") | ||
| 37 | + private IotDataBridgeConfig config; | ||
| 38 | + | ||
| 39 | +} | ||
| 0 | \ No newline at end of file | 40 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/databridge/config/IotDataBridgeConfig.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config; | ||
| 2 | + | ||
| 3 | +import com.fasterxml.jackson.annotation.JsonSubTypes; | ||
| 4 | +import com.fasterxml.jackson.annotation.JsonTypeInfo; | ||
| 5 | +import lombok.Data; | ||
| 6 | + | ||
| 7 | +/** | ||
| 8 | + * 抽象类 IotDataBridgeConfig | ||
| 9 | + * | ||
| 10 | + * 用于表示数据桥梁配置数据的通用类型,根据具体的 "type" 字段动态映射到对应的子类。 | ||
| 11 | + * 提供多态支持,适用于不同类型的数据结构序列化和反序列化场景。 | ||
| 12 | + * | ||
| 13 | + * @author HUIHUI | ||
| 14 | + */ | ||
| 15 | +@Data | ||
| 16 | +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", visible = true) | ||
| 17 | +@JsonSubTypes({ | ||
| 18 | + @JsonSubTypes.Type(value = IotDataBridgeHttpConfig.class, name = "HTTP"), | ||
| 19 | + @JsonSubTypes.Type(value = IotDataBridgeKafkaMQConfig.class, name = "KAFKA"), | ||
| 20 | + @JsonSubTypes.Type(value = IotDataBridgeMqttConfig.class, name = "MQTT"), | ||
| 21 | + @JsonSubTypes.Type(value = IotDataBridgeRabbitMQConfig.class, name = "RABBITMQ"), | ||
| 22 | + @JsonSubTypes.Type(value = IotDataBridgeRedisStreamMQConfig.class, name = "REDIS_STREAM"), | ||
| 23 | + @JsonSubTypes.Type(value = IotDataBridgeRocketMQConfig.class, name = "ROCKETMQ"), | ||
| 24 | +}) | ||
| 25 | +public abstract class IotDataBridgeConfig { | ||
| 26 | + | ||
| 27 | + /** | ||
| 28 | + * 配置类型 | ||
| 29 | + */ | ||
| 30 | + private String type; | ||
| 31 | + | ||
| 32 | +} |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/databridge/config/IotDataBridgeHttpConfig.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config; | ||
| 2 | + | ||
| 3 | +import lombok.Data; | ||
| 4 | + | ||
| 5 | +import java.util.Map; | ||
| 6 | + | ||
| 7 | +/** | ||
| 8 | + * HTTP 配置 | ||
| 9 | + * | ||
| 10 | + * @author HUIHUI | ||
| 11 | + */ | ||
| 12 | +@Data | ||
| 13 | +public class IotDataBridgeHttpConfig extends IotDataBridgeConfig { | ||
| 14 | + | ||
| 15 | + /** | ||
| 16 | + * 请求 URL | ||
| 17 | + */ | ||
| 18 | + private String url; | ||
| 19 | + /** | ||
| 20 | + * 请求方法 | ||
| 21 | + */ | ||
| 22 | + private String method; | ||
| 23 | + /** | ||
| 24 | + * 请求头 | ||
| 25 | + */ | ||
| 26 | + private Map<String, String> headers; | ||
| 27 | + /** | ||
| 28 | + * 请求参数 | ||
| 29 | + */ | ||
| 30 | + private Map<String, String> query; | ||
| 31 | + /** | ||
| 32 | + * 请求体 | ||
| 33 | + */ | ||
| 34 | + private String body; | ||
| 35 | + | ||
| 36 | +} | ||
| 0 | \ No newline at end of file | 37 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/databridge/config/IotDataBridgeKafkaMQConfig.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config; | ||
| 2 | + | ||
| 3 | +import lombok.Data; | ||
| 4 | + | ||
| 5 | +/** | ||
| 6 | + * Kafka 配置 | ||
| 7 | + * | ||
| 8 | + * @author HUIHUI | ||
| 9 | + */ | ||
| 10 | +@Data | ||
| 11 | +public class IotDataBridgeKafkaMQConfig extends IotDataBridgeConfig { | ||
| 12 | + | ||
| 13 | + /** | ||
| 14 | + * Kafka 服务器地址 | ||
| 15 | + */ | ||
| 16 | + private String bootstrapServers; | ||
| 17 | + /** | ||
| 18 | + * 用户名 | ||
| 19 | + */ | ||
| 20 | + private String username; | ||
| 21 | + /** | ||
| 22 | + * 密码 | ||
| 23 | + */ | ||
| 24 | + private String password; | ||
| 25 | + /** | ||
| 26 | + * 是否启用 SSL | ||
| 27 | + */ | ||
| 28 | + private Boolean ssl; | ||
| 29 | + | ||
| 30 | + /** | ||
| 31 | + * 主题 | ||
| 32 | + */ | ||
| 33 | + private String topic; | ||
| 34 | + | ||
| 35 | +} |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/databridge/config/IotDataBridgeMqttConfig.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config; | ||
| 2 | + | ||
| 3 | +import lombok.Data; | ||
| 4 | + | ||
| 5 | +/** | ||
| 6 | + * MQTT 配置 | ||
| 7 | + * | ||
| 8 | + * @author HUIHUI | ||
| 9 | + */ | ||
| 10 | +@Data | ||
| 11 | +public class IotDataBridgeMqttConfig extends IotDataBridgeConfig { | ||
| 12 | + | ||
| 13 | + /** | ||
| 14 | + * MQTT 服务器地址 | ||
| 15 | + */ | ||
| 16 | + private String url; | ||
| 17 | + /** | ||
| 18 | + * 用户名 | ||
| 19 | + */ | ||
| 20 | + private String username; | ||
| 21 | + /** | ||
| 22 | + * 密码 | ||
| 23 | + */ | ||
| 24 | + private String password; | ||
| 25 | + /** | ||
| 26 | + * 客户端编号 | ||
| 27 | + */ | ||
| 28 | + private String clientId; | ||
| 29 | + /** | ||
| 30 | + * 主题 | ||
| 31 | + */ | ||
| 32 | + private String topic; | ||
| 33 | + | ||
| 34 | +} | ||
| 0 | \ No newline at end of file | 35 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/databridge/config/IotDataBridgeRabbitMQConfig.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config; | ||
| 2 | + | ||
| 3 | +import lombok.Data; | ||
| 4 | + | ||
| 5 | +/** | ||
| 6 | + * RabbitMQ 配置 | ||
| 7 | + * | ||
| 8 | + * @author HUIHUI | ||
| 9 | + */ | ||
| 10 | +@Data | ||
| 11 | +public class IotDataBridgeRabbitMQConfig extends IotDataBridgeConfig { | ||
| 12 | + | ||
| 13 | + /** | ||
| 14 | + * RabbitMQ 服务器地址 | ||
| 15 | + */ | ||
| 16 | + private String host; | ||
| 17 | + /** | ||
| 18 | + * 端口 | ||
| 19 | + */ | ||
| 20 | + private Integer port; | ||
| 21 | + /** | ||
| 22 | + * 虚拟主机 | ||
| 23 | + */ | ||
| 24 | + private String virtualHost; | ||
| 25 | + /** | ||
| 26 | + * 用户名 | ||
| 27 | + */ | ||
| 28 | + private String username; | ||
| 29 | + /** | ||
| 30 | + * 密码 | ||
| 31 | + */ | ||
| 32 | + private String password; | ||
| 33 | + | ||
| 34 | + /** | ||
| 35 | + * 交换机名称 | ||
| 36 | + */ | ||
| 37 | + private String exchange; | ||
| 38 | + /** | ||
| 39 | + * 路由键 | ||
| 40 | + */ | ||
| 41 | + private String routingKey; | ||
| 42 | + /** | ||
| 43 | + * 队列名称 | ||
| 44 | + */ | ||
| 45 | + private String queue; | ||
| 46 | +} | ||
| 0 | \ No newline at end of file | 47 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/databridge/config/IotDataBridgeRedisStreamMQConfig.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config; | ||
| 2 | + | ||
| 3 | +import lombok.Data; | ||
| 4 | + | ||
| 5 | +/** | ||
| 6 | + * Redis Stream MQ 配置 | ||
| 7 | + * | ||
| 8 | + * @author HUIHUI | ||
| 9 | + */ | ||
| 10 | +@Data | ||
| 11 | +public class IotDataBridgeRedisStreamMQConfig extends IotDataBridgeConfig { | ||
| 12 | + | ||
| 13 | + /** | ||
| 14 | + * Redis 服务器地址 | ||
| 15 | + */ | ||
| 16 | + private String host; | ||
| 17 | + /** | ||
| 18 | + * 端口 | ||
| 19 | + */ | ||
| 20 | + private Integer port; | ||
| 21 | + /** | ||
| 22 | + * 密码 | ||
| 23 | + */ | ||
| 24 | + private String password; | ||
| 25 | + /** | ||
| 26 | + * 数据库索引 | ||
| 27 | + */ | ||
| 28 | + private Integer database; | ||
| 29 | + | ||
| 30 | + /** | ||
| 31 | + * 主题 | ||
| 32 | + */ | ||
| 33 | + private String topic; | ||
| 34 | +} | ||
| 0 | \ No newline at end of file | 35 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/databridge/config/IotDataBridgeRocketMQConfig.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config; | ||
| 2 | + | ||
| 3 | +import lombok.Data; | ||
| 4 | + | ||
| 5 | +/** | ||
| 6 | + * RocketMQ 配置 | ||
| 7 | + * | ||
| 8 | + * @author HUIHUI | ||
| 9 | + */ | ||
| 10 | +@Data | ||
| 11 | +public class IotDataBridgeRocketMQConfig extends IotDataBridgeConfig { | ||
| 12 | + | ||
| 13 | + /** | ||
| 14 | + * RocketMQ 名称服务器地址 | ||
| 15 | + */ | ||
| 16 | + private String nameServer; | ||
| 17 | + /** | ||
| 18 | + * 访问密钥 | ||
| 19 | + */ | ||
| 20 | + private String accessKey; | ||
| 21 | + /** | ||
| 22 | + * 秘密钥匙 | ||
| 23 | + */ | ||
| 24 | + private String secretKey; | ||
| 25 | + | ||
| 26 | + /** | ||
| 27 | + * 生产者组 | ||
| 28 | + */ | ||
| 29 | + private String group; | ||
| 30 | + /** | ||
| 31 | + * 主题 | ||
| 32 | + */ | ||
| 33 | + private String topic; | ||
| 34 | + /** | ||
| 35 | + * 标签 | ||
| 36 | + */ | ||
| 37 | + private String tags; | ||
| 38 | + | ||
| 39 | +} | ||
| 0 | \ No newline at end of file | 40 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/rule/vo/package-info.java
0 → 100644
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/rule/IotDataBridgeDO.java
| 1 | package cn.iocoder.yudao.module.iot.dal.dataobject.rule; | 1 | package cn.iocoder.yudao.module.iot.dal.dataobject.rule; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | 3 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 4 | +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config.IotDataBridgeConfig; | ||
| 5 | +import cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgeDirectionEnum; | ||
| 6 | +import cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgeTypeEnum; | ||
| 4 | import com.baomidou.mybatisplus.annotation.KeySequence; | 7 | import com.baomidou.mybatisplus.annotation.KeySequence; |
| 5 | import com.baomidou.mybatisplus.annotation.TableField; | 8 | import com.baomidou.mybatisplus.annotation.TableField; |
| 6 | import com.baomidou.mybatisplus.annotation.TableId; | 9 | import com.baomidou.mybatisplus.annotation.TableId; |
| 7 | import com.baomidou.mybatisplus.annotation.TableName; | 10 | import com.baomidou.mybatisplus.annotation.TableName; |
| 8 | import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; | 11 | import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; |
| 9 | -import com.fasterxml.jackson.annotation.JsonTypeInfo; | ||
| 10 | import lombok.*; | 12 | import lombok.*; |
| 11 | 13 | ||
| 12 | -import java.util.Map; | ||
| 13 | - | ||
| 14 | /** | 14 | /** |
| 15 | * IoT 数据桥梁 DO | 15 | * IoT 数据桥梁 DO |
| 16 | * | 16 | * |
| 17 | * @author 芋道源码 | 17 | * @author 芋道源码 |
| 18 | */ | 18 | */ |
| 19 | -@TableName("iot_data_bridge") | 19 | +@TableName(value = "iot_data_bridge", autoResultMap = true) |
| 20 | @KeySequence("iot_data_bridge_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 | 20 | @KeySequence("iot_data_bridge_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 |
| 21 | @Data | 21 | @Data |
| 22 | @EqualsAndHashCode(callSuper = true) | 22 | @EqualsAndHashCode(callSuper = true) |
| @@ -48,14 +48,14 @@ public class IotDataBridgeDO extends BaseDO { | @@ -48,14 +48,14 @@ public class IotDataBridgeDO extends BaseDO { | ||
| 48 | /** | 48 | /** |
| 49 | * 桥梁方向 | 49 | * 桥梁方向 |
| 50 | * | 50 | * |
| 51 | - * 枚举 {@link cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgDirectionEnum} | 51 | + * 枚举 {@link IotDataBridgeDirectionEnum} |
| 52 | */ | 52 | */ |
| 53 | private Integer direction; | 53 | private Integer direction; |
| 54 | 54 | ||
| 55 | /** | 55 | /** |
| 56 | * 桥梁类型 | 56 | * 桥梁类型 |
| 57 | * | 57 | * |
| 58 | - * 枚举 {@link cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgTypeEnum} | 58 | + * 枚举 {@link IotDataBridgeTypeEnum} |
| 59 | */ | 59 | */ |
| 60 | private Integer type; | 60 | private Integer type; |
| 61 | 61 | ||
| @@ -63,211 +63,6 @@ public class IotDataBridgeDO extends BaseDO { | @@ -63,211 +63,6 @@ public class IotDataBridgeDO extends BaseDO { | ||
| 63 | * 桥梁配置 | 63 | * 桥梁配置 |
| 64 | */ | 64 | */ |
| 65 | @TableField(typeHandler = JacksonTypeHandler.class) | 65 | @TableField(typeHandler = JacksonTypeHandler.class) |
| 66 | - private Config config; | ||
| 67 | - | ||
| 68 | - /** | ||
| 69 | - * 文件客户端的配置 | ||
| 70 | - * 不同实现的客户端,需要不同的配置,通过子类来定义 | ||
| 71 | - * | ||
| 72 | - * @author 芋道源码 | ||
| 73 | - */ | ||
| 74 | - @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) | ||
| 75 | - // @JsonTypeInfo 注解的作用,Jackson 多态 | ||
| 76 | - // 1. 序列化到时数据库时,增加 @class 属性。 | ||
| 77 | - // 2. 反序列化到内存对象时,通过 @class 属性,可以创建出正确的类型 | ||
| 78 | - public interface Config { | ||
| 79 | - } | ||
| 80 | - | ||
| 81 | - /** | ||
| 82 | - * HTTP 配置 | ||
| 83 | - */ | ||
| 84 | - @Data | ||
| 85 | - public static class HttpConfig implements Config { | ||
| 86 | - | ||
| 87 | - /** | ||
| 88 | - * 请求 URL | ||
| 89 | - */ | ||
| 90 | - private String url; | ||
| 91 | - /** | ||
| 92 | - * 请求方法 | ||
| 93 | - */ | ||
| 94 | - private String method; | ||
| 95 | - /** | ||
| 96 | - * 请求头 | ||
| 97 | - */ | ||
| 98 | - private Map<String, String> headers; | ||
| 99 | - /** | ||
| 100 | - * 请求参数 | ||
| 101 | - */ | ||
| 102 | - private Map<String, String> query; | ||
| 103 | - /** | ||
| 104 | - * 请求体 | ||
| 105 | - */ | ||
| 106 | - private String body; | ||
| 107 | - | ||
| 108 | - } | ||
| 109 | - | ||
| 110 | - /** | ||
| 111 | - * MQTT 配置 | ||
| 112 | - */ | ||
| 113 | - @Data | ||
| 114 | - public static class MqttConfig implements Config { | ||
| 115 | - | ||
| 116 | - /** | ||
| 117 | - * MQTT 服务器地址 | ||
| 118 | - */ | ||
| 119 | - private String url; | ||
| 120 | - /** | ||
| 121 | - * 用户名 | ||
| 122 | - */ | ||
| 123 | - private String username; | ||
| 124 | - /** | ||
| 125 | - * 密码 | ||
| 126 | - */ | ||
| 127 | - private String password; | ||
| 128 | - /** | ||
| 129 | - * 客户端编号 | ||
| 130 | - */ | ||
| 131 | - private String clientId; | ||
| 132 | - /** | ||
| 133 | - * 主题 | ||
| 134 | - */ | ||
| 135 | - private String topic; | ||
| 136 | - | ||
| 137 | - } | ||
| 138 | - | ||
| 139 | - /** | ||
| 140 | - * RocketMQ 配置 | ||
| 141 | - */ | ||
| 142 | - @Data | ||
| 143 | - public static class RocketMQConfig implements Config { | ||
| 144 | - | ||
| 145 | - /** | ||
| 146 | - * RocketMQ 名称服务器地址 | ||
| 147 | - */ | ||
| 148 | - private String nameServer; | ||
| 149 | - /** | ||
| 150 | - * 访问密钥 | ||
| 151 | - */ | ||
| 152 | - private String accessKey; | ||
| 153 | - /** | ||
| 154 | - * 秘密钥匙 | ||
| 155 | - */ | ||
| 156 | - private String secretKey; | ||
| 157 | - | ||
| 158 | - /** | ||
| 159 | - * 生产者组 | ||
| 160 | - */ | ||
| 161 | - private String group; | ||
| 162 | - /** | ||
| 163 | - * 主题 | ||
| 164 | - */ | ||
| 165 | - private String topic; | ||
| 166 | - /** | ||
| 167 | - * 标签 | ||
| 168 | - */ | ||
| 169 | - private String tags; | ||
| 170 | - | ||
| 171 | - } | ||
| 172 | - | ||
| 173 | - /** | ||
| 174 | - * Kafka 配置 | ||
| 175 | - */ | ||
| 176 | - @Data | ||
| 177 | - public static class KafkaMQConfig implements Config { | ||
| 178 | - | ||
| 179 | - /** | ||
| 180 | - * Kafka 服务器地址 | ||
| 181 | - */ | ||
| 182 | - private String bootstrapServers; | ||
| 183 | - /** | ||
| 184 | - * 用户名 | ||
| 185 | - */ | ||
| 186 | - private String username; | ||
| 187 | - /** | ||
| 188 | - * 密码 | ||
| 189 | - */ | ||
| 190 | - private String password; | ||
| 191 | - /** | ||
| 192 | - * 是否启用 SSL | ||
| 193 | - */ | ||
| 194 | - private Boolean ssl; | ||
| 195 | - | ||
| 196 | - /** | ||
| 197 | - * 主题 | ||
| 198 | - */ | ||
| 199 | - private String topic; | ||
| 200 | - | ||
| 201 | - } | ||
| 202 | - | ||
| 203 | - /** | ||
| 204 | - * RabbitMQ 配置 | ||
| 205 | - */ | ||
| 206 | - @Data | ||
| 207 | - public static class RabbitMQConfig implements Config { | ||
| 208 | - | ||
| 209 | - /** | ||
| 210 | - * RabbitMQ 服务器地址 | ||
| 211 | - */ | ||
| 212 | - private String host; | ||
| 213 | - /** | ||
| 214 | - * 端口 | ||
| 215 | - */ | ||
| 216 | - private Integer port; | ||
| 217 | - /** | ||
| 218 | - * 虚拟主机 | ||
| 219 | - */ | ||
| 220 | - private String virtualHost; | ||
| 221 | - /** | ||
| 222 | - * 用户名 | ||
| 223 | - */ | ||
| 224 | - private String username; | ||
| 225 | - /** | ||
| 226 | - * 密码 | ||
| 227 | - */ | ||
| 228 | - private String password; | ||
| 229 | - | ||
| 230 | - /** | ||
| 231 | - * 交换机名称 | ||
| 232 | - */ | ||
| 233 | - private String exchange; | ||
| 234 | - /** | ||
| 235 | - * 路由键 | ||
| 236 | - */ | ||
| 237 | - private String routingKey; | ||
| 238 | - /** | ||
| 239 | - * 队列名称 | ||
| 240 | - */ | ||
| 241 | - private String queue; | ||
| 242 | - } | ||
| 243 | - | ||
| 244 | - /** | ||
| 245 | - * Redis Stream MQ 配置 | ||
| 246 | - */ | ||
| 247 | - @Data | ||
| 248 | - public static class RedisStreamMQConfig implements Config { | ||
| 249 | - | ||
| 250 | - /** | ||
| 251 | - * Redis 服务器地址 | ||
| 252 | - */ | ||
| 253 | - private String host; | ||
| 254 | - /** | ||
| 255 | - * 端口 | ||
| 256 | - */ | ||
| 257 | - private Integer port; | ||
| 258 | - /** | ||
| 259 | - * 密码 | ||
| 260 | - */ | ||
| 261 | - private String password; | ||
| 262 | - /** | ||
| 263 | - * 数据库索引 | ||
| 264 | - */ | ||
| 265 | - private Integer database; | ||
| 266 | - | ||
| 267 | - /** | ||
| 268 | - * 主题 | ||
| 269 | - */ | ||
| 270 | - private String topic; | ||
| 271 | - } | 66 | + private IotDataBridgeConfig config; |
| 272 | 67 | ||
| 273 | } | 68 | } |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/rule/IotDataBridgeMapper.java
| 1 | package cn.iocoder.yudao.module.iot.dal.mysql.rule; | 1 | package cn.iocoder.yudao.module.iot.dal.mysql.rule; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 3 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | 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.rule.vo.databridge.IotDataBridgePageReqVO; | ||
| 4 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO; | 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO; |
| 5 | import org.apache.ibatis.annotations.Mapper; | 8 | import org.apache.ibatis.annotations.Mapper; |
| 6 | 9 | ||
| 10 | +/** | ||
| 11 | + * IoT 数据桥梁 Mapper | ||
| 12 | + * | ||
| 13 | + * @author HUIHUI | ||
| 14 | + */ | ||
| 7 | @Mapper | 15 | @Mapper |
| 8 | public interface IotDataBridgeMapper extends BaseMapperX<IotDataBridgeDO> { | 16 | public interface IotDataBridgeMapper extends BaseMapperX<IotDataBridgeDO> { |
| 9 | -} | 17 | + |
| 18 | + default PageResult<IotDataBridgeDO> selectPage(IotDataBridgePageReqVO reqVO) { | ||
| 19 | + return selectPage(reqVO, new LambdaQueryWrapperX<IotDataBridgeDO>() | ||
| 20 | + .likeIfPresent(IotDataBridgeDO::getName, reqVO.getName()) | ||
| 21 | + .likeIfPresent(IotDataBridgeDO::getDescription, reqVO.getDescription()) | ||
| 22 | + .eqIfPresent(IotDataBridgeDO::getStatus, reqVO.getStatus()) | ||
| 23 | + .eqIfPresent(IotDataBridgeDO::getDirection, reqVO.getDirection()) | ||
| 24 | + .eqIfPresent(IotDataBridgeDO::getType, reqVO.getType()) | ||
| 25 | + .betweenIfPresent(IotDataBridgeDO::getCreateTime, reqVO.getCreateTime()) | ||
| 26 | + .orderByDesc(IotDataBridgeDO::getId)); | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | +} | ||
| 10 | \ No newline at end of file | 30 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/IotDataBridgeService.java
| 1 | package cn.iocoder.yudao.module.iot.service.rule; | 1 | package cn.iocoder.yudao.module.iot.service.rule; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 4 | +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.IotDataBridgePageReqVO; | ||
| 5 | +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.IotDataBridgeSaveReqVO; | ||
| 3 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO; | 6 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO; |
| 7 | +import jakarta.validation.Valid; | ||
| 4 | 8 | ||
| 5 | /** | 9 | /** |
| 6 | - * IoT 数据桥梁的 Service 接口 | 10 | + * IoT 数据桥梁 Service 接口 |
| 7 | * | 11 | * |
| 8 | - * @author 芋道源码 | 12 | + * @author HUIHUI |
| 9 | */ | 13 | */ |
| 10 | public interface IotDataBridgeService { | 14 | public interface IotDataBridgeService { |
| 11 | 15 | ||
| 12 | /** | 16 | /** |
| 13 | - * 获得指定数据桥梁 | 17 | + * 创建IoT 数据桥梁 |
| 14 | * | 18 | * |
| 15 | - * @param id 数据桥梁编号 | ||
| 16 | - * @return 数据桥梁 | 19 | + * @param createReqVO 创建信息 |
| 20 | + * @return 编号 | ||
| 17 | */ | 21 | */ |
| 18 | - IotDataBridgeDO getIotDataBridge(Long id); | 22 | + Long createDataBridge(@Valid IotDataBridgeSaveReqVO createReqVO); |
| 19 | 23 | ||
| 20 | -} | 24 | + /** |
| 25 | + * 更新IoT 数据桥梁 | ||
| 26 | + * | ||
| 27 | + * @param updateReqVO 更新信息 | ||
| 28 | + */ | ||
| 29 | + void updateDataBridge(@Valid IotDataBridgeSaveReqVO updateReqVO); | ||
| 30 | + | ||
| 31 | + /** | ||
| 32 | + * 删除IoT 数据桥梁 | ||
| 33 | + * | ||
| 34 | + * @param id 编号 | ||
| 35 | + */ | ||
| 36 | + void deleteDataBridge(Long id); | ||
| 37 | + | ||
| 38 | + /** | ||
| 39 | + * 获得IoT 数据桥梁 | ||
| 40 | + * | ||
| 41 | + * @param id 编号 | ||
| 42 | + * @return IoT 数据桥梁 | ||
| 43 | + */ | ||
| 44 | + IotDataBridgeDO getDataBridge(Long id); | ||
| 45 | + | ||
| 46 | + /** | ||
| 47 | + * 获得IoT 数据桥梁分页 | ||
| 48 | + * | ||
| 49 | + * @param pageReqVO 分页查询 | ||
| 50 | + * @return IoT 数据桥梁分页 | ||
| 51 | + */ | ||
| 52 | + PageResult<IotDataBridgeDO> getDataBridgePage(IotDataBridgePageReqVO pageReqVO); | ||
| 53 | + | ||
| 54 | +} | ||
| 21 | \ No newline at end of file | 55 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/IotDataBridgeServiceImpl.java
| 1 | package cn.iocoder.yudao.module.iot.service.rule; | 1 | package cn.iocoder.yudao.module.iot.service.rule; |
| 2 | 2 | ||
| 3 | -import cn.hutool.core.map.MapUtil; | ||
| 4 | -import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | 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.rule.vo.databridge.IotDataBridgePageReqVO; | ||
| 6 | +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.IotDataBridgeSaveReqVO; | ||
| 5 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO; | 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO; |
| 6 | import cn.iocoder.yudao.module.iot.dal.mysql.rule.IotDataBridgeMapper; | 8 | import cn.iocoder.yudao.module.iot.dal.mysql.rule.IotDataBridgeMapper; |
| 7 | -import cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgTypeEnum; | ||
| 8 | import jakarta.annotation.Resource; | 9 | import jakarta.annotation.Resource; |
| 9 | -import lombok.extern.slf4j.Slf4j; | ||
| 10 | import org.springframework.stereotype.Service; | 10 | import org.springframework.stereotype.Service; |
| 11 | import org.springframework.validation.annotation.Validated; | 11 | import org.springframework.validation.annotation.Validated; |
| 12 | 12 | ||
| 13 | -import java.util.Objects; | 13 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 14 | +import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.DATA_BRIDGE_NOT_EXISTS; | ||
| 14 | 15 | ||
| 15 | /** | 16 | /** |
| 16 | - * IoT 数据桥梁的 Service 实现类 | 17 | + * IoT 数据桥梁 Service 实现类 |
| 17 | * | 18 | * |
| 18 | - * @author 芋道源码 | 19 | + * @author HUIHUI |
| 19 | */ | 20 | */ |
| 20 | @Service | 21 | @Service |
| 21 | @Validated | 22 | @Validated |
| 22 | -@Slf4j | ||
| 23 | public class IotDataBridgeServiceImpl implements IotDataBridgeService { | 23 | public class IotDataBridgeServiceImpl implements IotDataBridgeService { |
| 24 | 24 | ||
| 25 | @Resource | 25 | @Resource |
| 26 | private IotDataBridgeMapper dataBridgeMapper; | 26 | private IotDataBridgeMapper dataBridgeMapper; |
| 27 | 27 | ||
| 28 | - // TODO @芋艿:临时测试 | ||
| 29 | @Override | 28 | @Override |
| 30 | - public IotDataBridgeDO getIotDataBridge(Long id) { | ||
| 31 | - if (Objects.equals(id, 1L)) { | ||
| 32 | - IotDataBridgeDO.HttpConfig config = new IotDataBridgeDO.HttpConfig() | ||
| 33 | - .setUrl("http://127.0.0.1:48080/test") | ||
| 34 | -// .setMethod("POST") | ||
| 35 | - .setMethod("GET") | ||
| 36 | - .setQuery(MapUtil.of("aaa", "bbb")) | ||
| 37 | - .setHeaders(MapUtil.of("ccc", "ddd")) | ||
| 38 | - .setBody(JsonUtils.toJsonString(MapUtil.of("eee", "fff"))); | ||
| 39 | - return IotDataBridgeDO.builder().id(1L).name("芋道").description("芋道源码").status(0).direction(1) | ||
| 40 | - .type(IotDataBridgTypeEnum.HTTP.getType()).config(config).build(); | 29 | + public Long createDataBridge(IotDataBridgeSaveReqVO createReqVO) { |
| 30 | + // 插入 | ||
| 31 | + IotDataBridgeDO dataBridge = BeanUtils.toBean(createReqVO, IotDataBridgeDO.class); | ||
| 32 | + dataBridgeMapper.insert(dataBridge); | ||
| 33 | + // 返回 | ||
| 34 | + return dataBridge.getId(); | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | + @Override | ||
| 38 | + public void updateDataBridge(IotDataBridgeSaveReqVO updateReqVO) { | ||
| 39 | + // 校验存在 | ||
| 40 | + validateDataBridgeExists(updateReqVO.getId()); | ||
| 41 | + // 更新 | ||
| 42 | + IotDataBridgeDO updateObj = BeanUtils.toBean(updateReqVO, IotDataBridgeDO.class); | ||
| 43 | + dataBridgeMapper.updateById(updateObj); | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + @Override | ||
| 47 | + public void deleteDataBridge(Long id) { | ||
| 48 | + // 校验存在 | ||
| 49 | + validateDataBridgeExists(id); | ||
| 50 | + // 删除 | ||
| 51 | + dataBridgeMapper.deleteById(id); | ||
| 52 | + } | ||
| 53 | + | ||
| 54 | + private void validateDataBridgeExists(Long id) { | ||
| 55 | + if (dataBridgeMapper.selectById(id) == null) { | ||
| 56 | + throw exception(DATA_BRIDGE_NOT_EXISTS); | ||
| 41 | } | 57 | } |
| 58 | + } | ||
| 59 | + | ||
| 60 | + @Override | ||
| 61 | + public IotDataBridgeDO getDataBridge(Long id) { | ||
| 42 | return dataBridgeMapper.selectById(id); | 62 | return dataBridgeMapper.selectById(id); |
| 43 | } | 63 | } |
| 44 | 64 | ||
| 45 | -} | 65 | + @Override |
| 66 | + public PageResult<IotDataBridgeDO> getDataBridgePage(IotDataBridgePageReqVO pageReqVO) { | ||
| 67 | + return dataBridgeMapper.selectPage(pageReqVO); | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | +} | ||
| 46 | \ No newline at end of file | 71 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/IotRuleSceneAction.java
| @@ -22,7 +22,7 @@ public interface IotRuleSceneAction { | @@ -22,7 +22,7 @@ public interface IotRuleSceneAction { | ||
| 22 | * 2. 非空的情况:设备触发 | 22 | * 2. 非空的情况:设备触发 |
| 23 | * @param config 配置 | 23 | * @param config 配置 |
| 24 | */ | 24 | */ |
| 25 | - void execute(@Nullable IotDeviceMessage message, IotRuleSceneDO.ActionConfig config); | 25 | + void execute(@Nullable IotDeviceMessage message, IotRuleSceneDO.ActionConfig config) throws Exception; |
| 26 | 26 | ||
| 27 | /** | 27 | /** |
| 28 | * 获得类型 | 28 | * 获得类型 |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/IotRuleSceneDataBridgeAction.java
| @@ -26,17 +26,17 @@ public class IotRuleSceneDataBridgeAction implements IotRuleSceneAction { | @@ -26,17 +26,17 @@ public class IotRuleSceneDataBridgeAction implements IotRuleSceneAction { | ||
| 26 | @Resource | 26 | @Resource |
| 27 | private IotDataBridgeService dataBridgeService; | 27 | private IotDataBridgeService dataBridgeService; |
| 28 | @Resource | 28 | @Resource |
| 29 | - private List<IotDataBridgeExecute> dataBridgeExecutes; | 29 | + private List<IotDataBridgeExecute<?>> dataBridgeExecutes; |
| 30 | 30 | ||
| 31 | @Override | 31 | @Override |
| 32 | - public void execute(IotDeviceMessage message, IotRuleSceneDO.ActionConfig config) { | 32 | + public void execute(IotDeviceMessage message, IotRuleSceneDO.ActionConfig config) throws Exception { |
| 33 | // 1.1 如果消息为空,直接返回 | 33 | // 1.1 如果消息为空,直接返回 |
| 34 | if (message == null) { | 34 | if (message == null) { |
| 35 | return; | 35 | return; |
| 36 | } | 36 | } |
| 37 | // 1.2 获得数据桥梁 | 37 | // 1.2 获得数据桥梁 |
| 38 | Assert.notNull(config.getDataBridgeId(), "数据桥梁编号不能为空"); | 38 | Assert.notNull(config.getDataBridgeId(), "数据桥梁编号不能为空"); |
| 39 | - IotDataBridgeDO dataBridge = dataBridgeService.getIotDataBridge(config.getDataBridgeId()); | 39 | + IotDataBridgeDO dataBridge = dataBridgeService.getDataBridge(config.getDataBridgeId()); |
| 40 | if (dataBridge == null || dataBridge.getConfig() == null) { | 40 | if (dataBridge == null || dataBridge.getConfig() == null) { |
| 41 | log.error("[execute][message({}) config({}) 对应的数据桥梁不存在]", message, config); | 41 | log.error("[execute][message({}) config({}) 对应的数据桥梁不存在]", message, config); |
| 42 | return; | 42 | return; |
| @@ -47,7 +47,9 @@ public class IotRuleSceneDataBridgeAction implements IotRuleSceneAction { | @@ -47,7 +47,9 @@ public class IotRuleSceneDataBridgeAction implements IotRuleSceneAction { | ||
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | // 2. 执行数据桥接操作 | 49 | // 2. 执行数据桥接操作 |
| 50 | - dataBridgeExecutes.forEach(execute -> execute.execute(message, dataBridge)); | 50 | + for (IotDataBridgeExecute<?> execute : dataBridgeExecutes) { |
| 51 | + execute.execute(message, dataBridge); | ||
| 52 | + } | ||
| 51 | } | 53 | } |
| 52 | 54 | ||
| 53 | @Override | 55 | @Override |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/databridge/AbstractCacheableDataBridgeExecute.java
| 1 | package cn.iocoder.yudao.module.iot.service.rule.action.databridge; | 1 | package cn.iocoder.yudao.module.iot.service.rule.action.databridge; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO; | ||
| 4 | +import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | ||
| 3 | import com.google.common.cache.CacheBuilder; | 5 | import com.google.common.cache.CacheBuilder; |
| 4 | import com.google.common.cache.CacheLoader; | 6 | import com.google.common.cache.CacheLoader; |
| 5 | import com.google.common.cache.LoadingCache; | 7 | import com.google.common.cache.LoadingCache; |
| 8 | +import com.google.common.cache.RemovalListener; | ||
| 6 | import lombok.extern.slf4j.Slf4j; | 9 | import lombok.extern.slf4j.Slf4j; |
| 7 | 10 | ||
| 8 | import java.time.Duration; | 11 | import java.time.Duration; |
| @@ -15,22 +18,36 @@ import java.time.Duration; | @@ -15,22 +18,36 @@ import java.time.Duration; | ||
| 15 | /** | 18 | /** |
| 16 | * 带缓存功能的数据桥梁执行器抽象类 | 19 | * 带缓存功能的数据桥梁执行器抽象类 |
| 17 | * | 20 | * |
| 21 | + * 该类提供了一个通用的缓存机制,用于管理各类数据桥接的生产者(Producer)实例。 | ||
| 22 | + * | ||
| 23 | + * 主要特点: | ||
| 24 | + * - 基于Guava Cache实现高效的生产者实例缓存管理 | ||
| 25 | + * - 自动处理生产者的生命周期(创建、获取、关闭) | ||
| 26 | + * - 支持30分钟未访问自动过期清理机制 | ||
| 27 | + * - 异常处理与日志记录,便于问题排查 | ||
| 28 | + * | ||
| 29 | + * 子类需要实现: | ||
| 30 | + * - initProducer(Config) - 初始化特定类型的生产者实例 | ||
| 31 | + * - closeProducer(Producer) - 关闭生产者实例并释放资源 | ||
| 32 | + * | ||
| 33 | + * @param <Config> 配置信息类型,用于初始化生产者 | ||
| 34 | + * @param <Producer> 生产者类型,负责将数据发送到目标系统 | ||
| 18 | * @author HUIHUI | 35 | * @author HUIHUI |
| 19 | */ | 36 | */ |
| 20 | @Slf4j | 37 | @Slf4j |
| 21 | -public abstract class AbstractCacheableDataBridgeExecute implements IotDataBridgeExecute { | 38 | +public abstract class AbstractCacheableDataBridgeExecute<Config, Producer> implements IotDataBridgeExecute<Config> { |
| 22 | 39 | ||
| 23 | - // TODO @huihui:AbstractCacheableDataBridgeExecute<Producer> 这样,下面的 Object, Object 就有了类型;另外 IotDataBridgeDO.Config 可以替代一个 Object 哇, | ||
| 24 | /** | 40 | /** |
| 25 | * Producer 缓存 | 41 | * Producer 缓存 |
| 26 | */ | 42 | */ |
| 27 | - private final LoadingCache<Object, Object> PRODUCER_CACHE = CacheBuilder.newBuilder() | ||
| 28 | - .expireAfterAccess(Duration.ofMinutes(30)) | ||
| 29 | - .removalListener(notification -> { | ||
| 30 | - Object producer = notification.getValue(); | 43 | + private final LoadingCache<Config, Producer> PRODUCER_CACHE = CacheBuilder.newBuilder() |
| 44 | + .expireAfterAccess(Duration.ofMinutes(30)) // 30 分钟未访问就提前过期 | ||
| 45 | + .removalListener((RemovalListener<Config, Producer>) notification -> { | ||
| 46 | + Producer producer = notification.getValue(); | ||
| 31 | if (producer == null) { | 47 | if (producer == null) { |
| 32 | return; | 48 | return; |
| 33 | } | 49 | } |
| 50 | + | ||
| 34 | try { | 51 | try { |
| 35 | closeProducer(producer); | 52 | closeProducer(producer); |
| 36 | log.info("[PRODUCER_CACHE][配置({}) 对应的 producer 已关闭]", notification.getKey()); | 53 | log.info("[PRODUCER_CACHE][配置({}) 对应的 producer 已关闭]", notification.getKey()); |
| @@ -38,15 +55,18 @@ public abstract class AbstractCacheableDataBridgeExecute implements IotDataBridg | @@ -38,15 +55,18 @@ public abstract class AbstractCacheableDataBridgeExecute implements IotDataBridg | ||
| 38 | log.error("[PRODUCER_CACHE][配置({}) 对应的 producer 关闭失败]", notification.getKey(), e); | 55 | log.error("[PRODUCER_CACHE][配置({}) 对应的 producer 关闭失败]", notification.getKey(), e); |
| 39 | } | 56 | } |
| 40 | }) | 57 | }) |
| 41 | - .build(new CacheLoader<Object, Object>() { | ||
| 42 | - | 58 | + .build(new CacheLoader<Config, Producer>() { |
| 43 | @Override | 59 | @Override |
| 44 | - public Object load(Object config) throws Exception { | ||
| 45 | - Object producer = initProducer(config); | ||
| 46 | - log.info("[PRODUCER_CACHE][配置({}) 对应的 producer 已创建并启动]", config); | ||
| 47 | - return producer; | 60 | + public Producer load(Config config) throws Exception { |
| 61 | + try { | ||
| 62 | + Producer producer = initProducer(config); | ||
| 63 | + log.info("[PRODUCER_CACHE][配置({}) 对应的 producer 已创建并启动]", config); | ||
| 64 | + return producer; | ||
| 65 | + } catch (Exception e) { | ||
| 66 | + log.error("[PRODUCER_CACHE][配置({}) 对应的 producer 创建启动失败]", config, e); | ||
| 67 | + throw e; // 抛出异常,触发缓存加载失败机制 | ||
| 68 | + } | ||
| 48 | } | 69 | } |
| 49 | - | ||
| 50 | }); | 70 | }); |
| 51 | 71 | ||
| 52 | /** | 72 | /** |
| @@ -55,7 +75,7 @@ public abstract class AbstractCacheableDataBridgeExecute implements IotDataBridg | @@ -55,7 +75,7 @@ public abstract class AbstractCacheableDataBridgeExecute implements IotDataBridg | ||
| 55 | * @param config 配置信息 | 75 | * @param config 配置信息 |
| 56 | * @return 生产者对象 | 76 | * @return 生产者对象 |
| 57 | */ | 77 | */ |
| 58 | - protected Object getProducer(Object config) throws Exception { | 78 | + protected Producer getProducer(Config config) throws Exception { |
| 59 | return PRODUCER_CACHE.get(config); | 79 | return PRODUCER_CACHE.get(config); |
| 60 | } | 80 | } |
| 61 | 81 | ||
| @@ -66,13 +86,29 @@ public abstract class AbstractCacheableDataBridgeExecute implements IotDataBridg | @@ -66,13 +86,29 @@ public abstract class AbstractCacheableDataBridgeExecute implements IotDataBridg | ||
| 66 | * @return 生产者对象 | 86 | * @return 生产者对象 |
| 67 | * @throws Exception 如果初始化失败 | 87 | * @throws Exception 如果初始化失败 |
| 68 | */ | 88 | */ |
| 69 | - protected abstract Object initProducer(Object config) throws Exception; | 89 | + protected abstract Producer initProducer(Config config) throws Exception; |
| 70 | 90 | ||
| 71 | /** | 91 | /** |
| 72 | * 关闭生产者 | 92 | * 关闭生产者 |
| 73 | * | 93 | * |
| 74 | * @param producer 生产者对象 | 94 | * @param producer 生产者对象 |
| 75 | */ | 95 | */ |
| 76 | - protected abstract void closeProducer(Object producer); | 96 | + protected abstract void closeProducer(Producer producer) throws Exception; |
| 97 | + | ||
| 98 | + @Override | ||
| 99 | + @SuppressWarnings({"unchecked"}) | ||
| 100 | + public void execute(IotDeviceMessage message, IotDataBridgeDO dataBridge) { | ||
| 101 | + // 1.1 校验数据桥梁类型 | ||
| 102 | + if (!getType().equals(dataBridge.getType())) { | ||
| 103 | + return; | ||
| 104 | + } | ||
| 105 | + | ||
| 106 | + // 1.2 执行对应的数据桥梁发送消息 | ||
| 107 | + try { | ||
| 108 | + execute0(message, (Config) dataBridge.getConfig()); | ||
| 109 | + } catch (Exception e) { | ||
| 110 | + log.error("[execute][桥梁配置 config({}) 对应的 message({}) 发送异常]", dataBridge.getConfig(), message, e); | ||
| 111 | + } | ||
| 112 | + } | ||
| 77 | 113 | ||
| 78 | } | 114 | } |
| 79 | \ No newline at end of file | 115 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/databridge/IotDataBridgeExecute.java
| @@ -9,9 +9,14 @@ import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | @@ -9,9 +9,14 @@ import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | ||
| 9 | * | 9 | * |
| 10 | * @author HUIHUI | 10 | * @author HUIHUI |
| 11 | */ | 11 | */ |
| 12 | -public interface IotDataBridgeExecute { | 12 | +public interface IotDataBridgeExecute<Config> { |
| 13 | 13 | ||
| 14 | - // TODO @huihui:要不搞个 getType?然后 execute0 由子类实现。这样,子类的 executeRedisStream ,其实就是 execute0 了。 | 14 | + /** |
| 15 | + * 获取数据桥梁类型 | ||
| 16 | + * | ||
| 17 | + * @return 数据桥梁类型 | ||
| 18 | + */ | ||
| 19 | + Integer getType(); | ||
| 15 | 20 | ||
| 16 | /** | 21 | /** |
| 17 | * 执行数据桥梁操作 | 22 | * 执行数据桥梁操作 |
| @@ -19,6 +24,23 @@ public interface IotDataBridgeExecute { | @@ -19,6 +24,23 @@ public interface IotDataBridgeExecute { | ||
| 19 | * @param message 设备消息 | 24 | * @param message 设备消息 |
| 20 | * @param dataBridge 数据桥梁 | 25 | * @param dataBridge 数据桥梁 |
| 21 | */ | 26 | */ |
| 22 | - void execute(IotDeviceMessage message, IotDataBridgeDO dataBridge); | 27 | + @SuppressWarnings({"unchecked"}) |
| 28 | + default void execute(IotDeviceMessage message, IotDataBridgeDO dataBridge) throws Exception { | ||
| 29 | + // 1.1 校验数据桥梁类型 | ||
| 30 | + if (!getType().equals(dataBridge.getType())) { | ||
| 31 | + return; | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + // 1.2 执行对应的数据桥梁发送消息 | ||
| 35 | + execute0(message, (Config) dataBridge.getConfig()); | ||
| 36 | + } | ||
| 37 | + | ||
| 38 | + /** | ||
| 39 | + * 【真正】执行数据桥梁操作 | ||
| 40 | + * | ||
| 41 | + * @param message 设备消息 | ||
| 42 | + * @param config 桥梁配置 | ||
| 43 | + */ | ||
| 44 | + void execute0(IotDeviceMessage message, Config config) throws Exception; | ||
| 23 | 45 | ||
| 24 | } | 46 | } |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/databridge/IotHttpDataBridgeExecute.java
| @@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.iot.service.rule.action.databridge; | @@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.iot.service.rule.action.databridge; | ||
| 3 | import cn.hutool.core.collection.CollUtil; | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | import cn.iocoder.yudao.framework.common.util.http.HttpUtils; | 4 | import cn.iocoder.yudao.framework.common.util.http.HttpUtils; |
| 5 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | 5 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; |
| 6 | -import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO; | ||
| 7 | -import cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgTypeEnum; | 6 | +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config.IotDataBridgeHttpConfig; |
| 7 | +import cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgeTypeEnum; | ||
| 8 | import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | 8 | import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; |
| 9 | import jakarta.annotation.Resource; | 9 | import jakarta.annotation.Resource; |
| 10 | import lombok.extern.slf4j.Slf4j; | 10 | import lombok.extern.slf4j.Slf4j; |
| @@ -25,23 +25,19 @@ import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_ | @@ -25,23 +25,19 @@ import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_ | ||
| 25 | */ | 25 | */ |
| 26 | @Component | 26 | @Component |
| 27 | @Slf4j | 27 | @Slf4j |
| 28 | -public class IotHttpDataBridgeExecute implements IotDataBridgeExecute { | 28 | +public class IotHttpDataBridgeExecute implements IotDataBridgeExecute<IotDataBridgeHttpConfig> { |
| 29 | 29 | ||
| 30 | @Resource | 30 | @Resource |
| 31 | private RestTemplate restTemplate; | 31 | private RestTemplate restTemplate; |
| 32 | 32 | ||
| 33 | @Override | 33 | @Override |
| 34 | - public void execute(IotDeviceMessage message, IotDataBridgeDO dataBridge) { | ||
| 35 | - // 1.1 校验数据桥梁的类型 == HTTP | ||
| 36 | - if (!IotDataBridgTypeEnum.HTTP.getType().equals(dataBridge.getType())) { | ||
| 37 | - return; | ||
| 38 | - } | ||
| 39 | - // 1.2 执行 HTTP 请求 | ||
| 40 | - executeHttp(message, (IotDataBridgeDO.HttpConfig) dataBridge.getConfig()); | 34 | + public Integer getType() { |
| 35 | + return IotDataBridgeTypeEnum.HTTP.getType(); | ||
| 41 | } | 36 | } |
| 42 | 37 | ||
| 38 | + @Override | ||
| 43 | @SuppressWarnings({"unchecked", "deprecation"}) | 39 | @SuppressWarnings({"unchecked", "deprecation"}) |
| 44 | - private void executeHttp(IotDeviceMessage message, IotDataBridgeDO.HttpConfig config) { | 40 | + public void execute0(IotDeviceMessage message, IotDataBridgeHttpConfig config) { |
| 45 | String url = null; | 41 | String url = null; |
| 46 | HttpMethod method = HttpMethod.valueOf(config.getMethod().toUpperCase()); | 42 | HttpMethod method = HttpMethod.valueOf(config.getMethod().toUpperCase()); |
| 47 | HttpEntity<String> requestEntity = null; | 43 | HttpEntity<String> requestEntity = null; |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/databridge/IotKafkaMQDataBridgeExecute.java
| 1 | package cn.iocoder.yudao.module.iot.service.rule.action.databridge; | 1 | package cn.iocoder.yudao.module.iot.service.rule.action.databridge; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config.IotDataBridgeKafkaMQConfig; | ||
| 3 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO; | 4 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO; |
| 4 | -import cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgTypeEnum; | 5 | +import cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgeTypeEnum; |
| 5 | import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | 6 | import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; |
| 6 | import lombok.extern.slf4j.Slf4j; | 7 | import lombok.extern.slf4j.Slf4j; |
| 7 | import org.apache.kafka.clients.producer.ProducerConfig; | 8 | import org.apache.kafka.clients.producer.ProducerConfig; |
| 8 | import org.apache.kafka.common.serialization.StringSerializer; | 9 | import org.apache.kafka.common.serialization.StringSerializer; |
| 10 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; | ||
| 9 | import org.springframework.kafka.core.DefaultKafkaProducerFactory; | 11 | import org.springframework.kafka.core.DefaultKafkaProducerFactory; |
| 10 | import org.springframework.kafka.core.KafkaTemplate; | 12 | import org.springframework.kafka.core.KafkaTemplate; |
| 11 | import org.springframework.stereotype.Component; | 13 | import org.springframework.stereotype.Component; |
| @@ -15,65 +17,53 @@ import java.time.LocalDateTime; | @@ -15,65 +17,53 @@ import java.time.LocalDateTime; | ||
| 15 | import java.util.HashMap; | 17 | import java.util.HashMap; |
| 16 | import java.util.Map; | 18 | import java.util.Map; |
| 17 | import java.util.concurrent.TimeUnit; | 19 | import java.util.concurrent.TimeUnit; |
| 18 | -import java.util.concurrent.TimeoutException; | ||
| 19 | 20 | ||
| 20 | /** | 21 | /** |
| 21 | * Kafka 的 {@link IotDataBridgeExecute} 实现类 | 22 | * Kafka 的 {@link IotDataBridgeExecute} 实现类 |
| 22 | * | 23 | * |
| 23 | * @author HUIHUI | 24 | * @author HUIHUI |
| 24 | */ | 25 | */ |
| 26 | +@ConditionalOnClass(name = "org.springframework.kafka.core.KafkaTemplate") | ||
| 25 | @Component | 27 | @Component |
| 26 | @Slf4j | 28 | @Slf4j |
| 27 | -public class IotKafkaMQDataBridgeExecute extends AbstractCacheableDataBridgeExecute { | 29 | +public class IotKafkaMQDataBridgeExecute extends |
| 30 | + AbstractCacheableDataBridgeExecute<IotDataBridgeKafkaMQConfig, KafkaTemplate<String, String>> { | ||
| 28 | 31 | ||
| 29 | - private static final Duration SEND_TIMEOUT = Duration.ofMillis(10); | 32 | + private static final Duration SEND_TIMEOUT = Duration.ofMillis(10000); // 10 秒超时时间 |
| 30 | 33 | ||
| 31 | @Override | 34 | @Override |
| 32 | - public void execute(IotDeviceMessage message, IotDataBridgeDO dataBridge) { | ||
| 33 | - // 1. 校验数据桥梁的类型 == KAFKA | ||
| 34 | - if (!IotDataBridgTypeEnum.KAFKA.getType().equals(dataBridge.getType())) { | ||
| 35 | - return; | ||
| 36 | - } | ||
| 37 | - // 2. 执行 Kafka 发送消息 | ||
| 38 | - executeKafka(message, (IotDataBridgeDO.KafkaMQConfig) dataBridge.getConfig()); | 35 | + public Integer getType() { |
| 36 | + return IotDataBridgeTypeEnum.KAFKA.getType(); | ||
| 39 | } | 37 | } |
| 40 | 38 | ||
| 41 | - @SuppressWarnings("unchecked") | ||
| 42 | - private void executeKafka(IotDeviceMessage message, IotDataBridgeDO.KafkaMQConfig config) { | ||
| 43 | - try { | ||
| 44 | - // 1. 获取或创建 KafkaTemplate | ||
| 45 | - KafkaTemplate<String, String> kafkaTemplate = (KafkaTemplate<String, String>) getProducer(config); | ||
| 46 | - | ||
| 47 | - // 2. 发送消息并等待结果 | ||
| 48 | - kafkaTemplate.send(config.getTopic(), message.toString()) | ||
| 49 | - .get(SEND_TIMEOUT.getSeconds(), TimeUnit.SECONDS); // 添加超时等待 | ||
| 50 | - log.info("[executeKafka][message({}) 发送成功]", message); | ||
| 51 | - } catch (TimeoutException e) { | ||
| 52 | - log.error("[executeKafka][message({}) config({}) 发送超时]", message, config, e); | ||
| 53 | - } catch (Exception e) { | ||
| 54 | - log.error("[executeKafka][message({}) config({}) 发送异常]", message, config, e); | ||
| 55 | - } | 39 | + @Override |
| 40 | + public void execute0(IotDeviceMessage message, IotDataBridgeKafkaMQConfig config) throws Exception { | ||
| 41 | + // 1. 获取或创建 KafkaTemplate | ||
| 42 | + KafkaTemplate<String, String> kafkaTemplate = getProducer(config); | ||
| 43 | + | ||
| 44 | + // 2. 发送消息并等待结果 | ||
| 45 | + kafkaTemplate.send(config.getTopic(), message.toString()) | ||
| 46 | + .get(SEND_TIMEOUT.getSeconds(), TimeUnit.SECONDS); // 添加超时等待 | ||
| 47 | + log.info("[execute0][message({}) 发送成功]", message); | ||
| 56 | } | 48 | } |
| 57 | 49 | ||
| 58 | @Override | 50 | @Override |
| 59 | - protected Object initProducer(Object config) { | ||
| 60 | - IotDataBridgeDO.KafkaMQConfig kafkaConfig = (IotDataBridgeDO.KafkaMQConfig) config; | ||
| 61 | - | 51 | + protected KafkaTemplate<String, String> initProducer(IotDataBridgeKafkaMQConfig config) { |
| 62 | // 1.1 构建生产者配置 | 52 | // 1.1 构建生产者配置 |
| 63 | Map<String, Object> props = new HashMap<>(); | 53 | Map<String, Object> props = new HashMap<>(); |
| 64 | - props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaConfig.getBootstrapServers()); | 54 | + props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, config.getBootstrapServers()); |
| 65 | props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); | 55 | props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); |
| 66 | props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class); | 56 | props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class); |
| 67 | // 1.2 如果配置了认证信息 | 57 | // 1.2 如果配置了认证信息 |
| 68 | - if (kafkaConfig.getUsername() != null && kafkaConfig.getPassword() != null) { | 58 | + if (config.getUsername() != null && config.getPassword() != null) { |
| 69 | props.put("security.protocol", "SASL_PLAINTEXT"); | 59 | props.put("security.protocol", "SASL_PLAINTEXT"); |
| 70 | props.put("sasl.mechanism", "PLAIN"); | 60 | props.put("sasl.mechanism", "PLAIN"); |
| 71 | props.put("sasl.jaas.config", | 61 | props.put("sasl.jaas.config", |
| 72 | "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"" | 62 | "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"" |
| 73 | - + kafkaConfig.getUsername() + "\" password=\"" + kafkaConfig.getPassword() + "\";"); | 63 | + + config.getUsername() + "\" password=\"" + config.getPassword() + "\";"); |
| 74 | } | 64 | } |
| 75 | // 1.3 如果启用 SSL | 65 | // 1.3 如果启用 SSL |
| 76 | - if (Boolean.TRUE.equals(kafkaConfig.getSsl())) { | 66 | + if (Boolean.TRUE.equals(config.getSsl())) { |
| 77 | props.put("security.protocol", "SSL"); | 67 | props.put("security.protocol", "SSL"); |
| 78 | } | 68 | } |
| 79 | 69 | ||
| @@ -83,10 +73,8 @@ public class IotKafkaMQDataBridgeExecute extends AbstractCacheableDataBridgeExec | @@ -83,10 +73,8 @@ public class IotKafkaMQDataBridgeExecute extends AbstractCacheableDataBridgeExec | ||
| 83 | } | 73 | } |
| 84 | 74 | ||
| 85 | @Override | 75 | @Override |
| 86 | - protected void closeProducer(Object producer) { | ||
| 87 | - if (producer instanceof KafkaTemplate) { | ||
| 88 | - ((KafkaTemplate<?, ?>) producer).destroy(); | ||
| 89 | - } | 76 | + protected void closeProducer(KafkaTemplate<String, String> producer) { |
| 77 | + producer.destroy(); | ||
| 90 | } | 78 | } |
| 91 | 79 | ||
| 92 | // TODO @芋艿:测试代码,后续清理 | 80 | // TODO @芋艿:测试代码,后续清理 |
| @@ -95,7 +83,7 @@ public class IotKafkaMQDataBridgeExecute extends AbstractCacheableDataBridgeExec | @@ -95,7 +83,7 @@ public class IotKafkaMQDataBridgeExecute extends AbstractCacheableDataBridgeExec | ||
| 95 | IotKafkaMQDataBridgeExecute action = new IotKafkaMQDataBridgeExecute(); | 83 | IotKafkaMQDataBridgeExecute action = new IotKafkaMQDataBridgeExecute(); |
| 96 | 84 | ||
| 97 | // 2. 创建共享的配置 | 85 | // 2. 创建共享的配置 |
| 98 | - IotDataBridgeDO.KafkaMQConfig config = new IotDataBridgeDO.KafkaMQConfig(); | 86 | + IotDataBridgeKafkaMQConfig config = new IotDataBridgeKafkaMQConfig(); |
| 99 | config.setBootstrapServers("127.0.0.1:9092"); | 87 | config.setBootstrapServers("127.0.0.1:9092"); |
| 100 | config.setTopic("test-topic"); | 88 | config.setTopic("test-topic"); |
| 101 | config.setSsl(false); | 89 | config.setSsl(false); |
| @@ -117,10 +105,10 @@ public class IotKafkaMQDataBridgeExecute extends AbstractCacheableDataBridgeExec | @@ -117,10 +105,10 @@ public class IotKafkaMQDataBridgeExecute extends AbstractCacheableDataBridgeExec | ||
| 117 | 105 | ||
| 118 | // 4. 执行两次测试,验证缓存 | 106 | // 4. 执行两次测试,验证缓存 |
| 119 | log.info("[main][第一次执行,应该会创建新的 producer]"); | 107 | log.info("[main][第一次执行,应该会创建新的 producer]"); |
| 120 | - action.executeKafka(message, config); | 108 | + action.execute(message, new IotDataBridgeDO().setType(action.getType()).setConfig(config)); |
| 121 | 109 | ||
| 122 | log.info("[main][第二次执行,应该会复用缓存的 producer]"); | 110 | log.info("[main][第二次执行,应该会复用缓存的 producer]"); |
| 123 | - action.executeKafka(message, config); | 111 | + action.execute(message, new IotDataBridgeDO().setType(action.getType()).setConfig(config)); |
| 124 | } | 112 | } |
| 125 | 113 | ||
| 126 | } | 114 | } |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/databridge/IotRabbitMQDataBridgeExecute.java
| 1 | package cn.iocoder.yudao.module.iot.service.rule.action.databridge; | 1 | package cn.iocoder.yudao.module.iot.service.rule.action.databridge; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config.IotDataBridgeRabbitMQConfig; | ||
| 3 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO; | 4 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO; |
| 4 | -import cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgTypeEnum; | 5 | +import cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgeTypeEnum; |
| 5 | import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | 6 | import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; |
| 6 | import com.rabbitmq.client.Channel; | 7 | import com.rabbitmq.client.Channel; |
| 7 | import com.rabbitmq.client.Connection; | 8 | import com.rabbitmq.client.Connection; |
| 8 | import com.rabbitmq.client.ConnectionFactory; | 9 | import com.rabbitmq.client.ConnectionFactory; |
| 9 | import lombok.extern.slf4j.Slf4j; | 10 | import lombok.extern.slf4j.Slf4j; |
| 11 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; | ||
| 10 | import org.springframework.stereotype.Component; | 12 | import org.springframework.stereotype.Component; |
| 11 | 13 | ||
| 12 | import java.nio.charset.StandardCharsets; | 14 | import java.nio.charset.StandardCharsets; |
| @@ -17,51 +19,44 @@ import java.time.LocalDateTime; | @@ -17,51 +19,44 @@ import java.time.LocalDateTime; | ||
| 17 | * | 19 | * |
| 18 | * @author HUIHUI | 20 | * @author HUIHUI |
| 19 | */ | 21 | */ |
| 22 | +@ConditionalOnClass(name = "com.rabbitmq.client.Channel") | ||
| 20 | @Component | 23 | @Component |
| 21 | @Slf4j | 24 | @Slf4j |
| 22 | -public class IotRabbitMQDataBridgeExecute extends AbstractCacheableDataBridgeExecute { | 25 | +public class IotRabbitMQDataBridgeExecute extends |
| 26 | + AbstractCacheableDataBridgeExecute<IotDataBridgeRabbitMQConfig, Channel> { | ||
| 27 | + | ||
| 23 | 28 | ||
| 24 | @Override | 29 | @Override |
| 25 | - public void execute(IotDeviceMessage message, IotDataBridgeDO dataBridge) { | ||
| 26 | - // 1.1 校验数据桥梁的类型 == RABBITMQ | ||
| 27 | - if (!IotDataBridgTypeEnum.RABBITMQ.getType().equals(dataBridge.getType())) { | ||
| 28 | - return; | ||
| 29 | - } | ||
| 30 | - // 1.2 执行 RabbitMQ 发送消息 | ||
| 31 | - executeRabbitMQ(message, (IotDataBridgeDO.RabbitMQConfig) dataBridge.getConfig()); | 30 | + public Integer getType() { |
| 31 | + return IotDataBridgeTypeEnum.RABBITMQ.getType(); | ||
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | - private void executeRabbitMQ(IotDeviceMessage message, IotDataBridgeDO.RabbitMQConfig config) { | ||
| 35 | - try { | ||
| 36 | - // 1. 获取或创建 Channel | ||
| 37 | - Channel channel = (Channel) getProducer(config); | ||
| 38 | - | ||
| 39 | - // 2.1 声明交换机、队列和绑定关系 | ||
| 40 | - channel.exchangeDeclare(config.getExchange(), "direct", true); | ||
| 41 | - channel.queueDeclare(config.getQueue(), true, false, false, null); | ||
| 42 | - channel.queueBind(config.getQueue(), config.getExchange(), config.getRoutingKey()); | ||
| 43 | - | ||
| 44 | - // 2.2 发送消息 | ||
| 45 | - channel.basicPublish(config.getExchange(), config.getRoutingKey(), null, | ||
| 46 | - message.toString().getBytes(StandardCharsets.UTF_8)); | ||
| 47 | - log.info("[executeRabbitMQ][message({}) config({}) 发送成功]", message, config); | ||
| 48 | - } catch (Exception e) { | ||
| 49 | - log.error("[executeRabbitMQ][message({}) config({}) 发送异常]", message, config, e); | ||
| 50 | - } | 34 | + @Override |
| 35 | + public void execute0(IotDeviceMessage message, IotDataBridgeRabbitMQConfig config) throws Exception { | ||
| 36 | + // 1. 获取或创建 Channel | ||
| 37 | + Channel channel = getProducer(config); | ||
| 38 | + | ||
| 39 | + // 2.1 声明交换机、队列和绑定关系 | ||
| 40 | + channel.exchangeDeclare(config.getExchange(), "direct", true); | ||
| 41 | + channel.queueDeclare(config.getQueue(), true, false, false, null); | ||
| 42 | + channel.queueBind(config.getQueue(), config.getExchange(), config.getRoutingKey()); | ||
| 43 | + | ||
| 44 | + // 2.2 发送消息 | ||
| 45 | + channel.basicPublish(config.getExchange(), config.getRoutingKey(), null, | ||
| 46 | + message.toString().getBytes(StandardCharsets.UTF_8)); | ||
| 47 | + log.info("[executeRabbitMQ][message({}) config({}) 发送成功]", message, config); | ||
| 51 | } | 48 | } |
| 52 | 49 | ||
| 53 | @Override | 50 | @Override |
| 54 | @SuppressWarnings("resource") | 51 | @SuppressWarnings("resource") |
| 55 | - protected Object initProducer(Object config) throws Exception { | ||
| 56 | - IotDataBridgeDO.RabbitMQConfig rabbitConfig = (IotDataBridgeDO.RabbitMQConfig) config; | ||
| 57 | - | 52 | + protected Channel initProducer(IotDataBridgeRabbitMQConfig config) throws Exception { |
| 58 | // 1. 创建连接工厂 | 53 | // 1. 创建连接工厂 |
| 59 | ConnectionFactory factory = new ConnectionFactory(); | 54 | ConnectionFactory factory = new ConnectionFactory(); |
| 60 | - factory.setHost(rabbitConfig.getHost()); | ||
| 61 | - factory.setPort(rabbitConfig.getPort()); | ||
| 62 | - factory.setVirtualHost(rabbitConfig.getVirtualHost()); | ||
| 63 | - factory.setUsername(rabbitConfig.getUsername()); | ||
| 64 | - factory.setPassword(rabbitConfig.getPassword()); | 55 | + factory.setHost(config.getHost()); |
| 56 | + factory.setPort(config.getPort()); | ||
| 57 | + factory.setVirtualHost(config.getVirtualHost()); | ||
| 58 | + factory.setUsername(config.getUsername()); | ||
| 59 | + factory.setPassword(config.getPassword()); | ||
| 65 | 60 | ||
| 66 | // 2. 创建连接 | 61 | // 2. 创建连接 |
| 67 | Connection connection = factory.newConnection(); | 62 | Connection connection = factory.newConnection(); |
| @@ -71,20 +66,13 @@ public class IotRabbitMQDataBridgeExecute extends AbstractCacheableDataBridgeExe | @@ -71,20 +66,13 @@ public class IotRabbitMQDataBridgeExecute extends AbstractCacheableDataBridgeExe | ||
| 71 | } | 66 | } |
| 72 | 67 | ||
| 73 | @Override | 68 | @Override |
| 74 | - protected void closeProducer(Object producer) { | ||
| 75 | - if (producer instanceof Channel) { | ||
| 76 | - try { | ||
| 77 | - Channel channel = (Channel) producer; | ||
| 78 | - if (channel.isOpen()) { | ||
| 79 | - channel.close(); | ||
| 80 | - } | ||
| 81 | - Connection connection = channel.getConnection(); | ||
| 82 | - if (connection.isOpen()) { | ||
| 83 | - connection.close(); | ||
| 84 | - } | ||
| 85 | - } catch (Exception e) { | ||
| 86 | - log.error("[closeProducer][关闭 RabbitMQ 连接异常]", e); | ||
| 87 | - } | 69 | + protected void closeProducer(Channel channel) throws Exception { |
| 70 | + if (channel.isOpen()) { | ||
| 71 | + channel.close(); | ||
| 72 | + } | ||
| 73 | + Connection connection = channel.getConnection(); | ||
| 74 | + if (connection.isOpen()) { | ||
| 75 | + connection.close(); | ||
| 88 | } | 76 | } |
| 89 | } | 77 | } |
| 90 | 78 | ||
| @@ -94,7 +82,7 @@ public class IotRabbitMQDataBridgeExecute extends AbstractCacheableDataBridgeExe | @@ -94,7 +82,7 @@ public class IotRabbitMQDataBridgeExecute extends AbstractCacheableDataBridgeExe | ||
| 94 | IotRabbitMQDataBridgeExecute action = new IotRabbitMQDataBridgeExecute(); | 82 | IotRabbitMQDataBridgeExecute action = new IotRabbitMQDataBridgeExecute(); |
| 95 | 83 | ||
| 96 | // 2. 创建共享的配置 | 84 | // 2. 创建共享的配置 |
| 97 | - IotDataBridgeDO.RabbitMQConfig config = new IotDataBridgeDO.RabbitMQConfig(); | 85 | + IotDataBridgeRabbitMQConfig config = new IotDataBridgeRabbitMQConfig(); |
| 98 | config.setHost("localhost"); | 86 | config.setHost("localhost"); |
| 99 | config.setPort(5672); | 87 | config.setPort(5672); |
| 100 | config.setVirtualHost("/"); | 88 | config.setVirtualHost("/"); |
| @@ -118,10 +106,12 @@ public class IotRabbitMQDataBridgeExecute extends AbstractCacheableDataBridgeExe | @@ -118,10 +106,12 @@ public class IotRabbitMQDataBridgeExecute extends AbstractCacheableDataBridgeExe | ||
| 118 | .build(); | 106 | .build(); |
| 119 | 107 | ||
| 120 | // 4. 执行两次测试,验证缓存 | 108 | // 4. 执行两次测试,验证缓存 |
| 121 | - log.info("[main][第一次执行,应该会创建新的 channel]"); | ||
| 122 | - action.executeRabbitMQ(message, config); | 109 | + // 4. 执行两次测试,验证缓存 |
| 110 | + log.info("[main][第一次执行,应该会创建新的 producer]"); | ||
| 111 | + action.execute(message, new IotDataBridgeDO().setType(action.getType()).setConfig(config)); | ||
| 123 | 112 | ||
| 124 | - log.info("[main][第二次执行,应该会复用缓存的 channel]"); | ||
| 125 | - action.executeRabbitMQ(message, config); | 113 | + log.info("[main][第二次执行,应该会复用缓存的 producer]"); |
| 114 | + action.execute(message, new IotDataBridgeDO().setType(action.getType()).setConfig(config)); | ||
| 126 | } | 115 | } |
| 116 | + | ||
| 127 | } | 117 | } |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/databridge/IotRedisStreamMQDataBridgeExecute.java
| @@ -2,8 +2,9 @@ package cn.iocoder.yudao.module.iot.service.rule.action.databridge; | @@ -2,8 +2,9 @@ package cn.iocoder.yudao.module.iot.service.rule.action.databridge; | ||
| 2 | 2 | ||
| 3 | import cn.hutool.core.util.ReflectUtil; | 3 | import cn.hutool.core.util.ReflectUtil; |
| 4 | import cn.hutool.core.util.StrUtil; | 4 | import cn.hutool.core.util.StrUtil; |
| 5 | +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config.IotDataBridgeRedisStreamMQConfig; | ||
| 5 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO; | 6 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO; |
| 6 | -import cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgTypeEnum; | 7 | +import cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgeTypeEnum; |
| 7 | import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | 8 | import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; |
| 8 | import com.fasterxml.jackson.databind.ObjectMapper; | 9 | import com.fasterxml.jackson.databind.ObjectMapper; |
| 9 | import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; | 10 | import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; |
| @@ -29,47 +30,36 @@ import java.time.LocalDateTime; | @@ -29,47 +30,36 @@ import java.time.LocalDateTime; | ||
| 29 | */ | 30 | */ |
| 30 | @Component | 31 | @Component |
| 31 | @Slf4j | 32 | @Slf4j |
| 32 | -public class IotRedisStreamMQDataBridgeExecute extends AbstractCacheableDataBridgeExecute { | 33 | +public class IotRedisStreamMQDataBridgeExecute extends |
| 34 | + AbstractCacheableDataBridgeExecute<IotDataBridgeRedisStreamMQConfig, RedisTemplate<String, Object>> { | ||
| 33 | 35 | ||
| 34 | @Override | 36 | @Override |
| 35 | - public void execute(IotDeviceMessage message, IotDataBridgeDO dataBridge) { | ||
| 36 | - // 1.1 校验数据桥梁类型 | ||
| 37 | - if (!IotDataBridgTypeEnum.REDIS_STREAM.getType().equals(dataBridge.getType())) { | ||
| 38 | - return; | ||
| 39 | - } | ||
| 40 | - // 1.2 执行消息发送 | ||
| 41 | - executeRedisStream(message, (IotDataBridgeDO.RedisStreamMQConfig) dataBridge.getConfig()); | 37 | + public Integer getType() { |
| 38 | + return IotDataBridgeTypeEnum.REDIS_STREAM.getType(); | ||
| 42 | } | 39 | } |
| 43 | 40 | ||
| 44 | - @SuppressWarnings("unchecked") | ||
| 45 | - // TODO @huihui:try catch 交给父类来做,子类不处理异常 | ||
| 46 | - private void executeRedisStream(IotDeviceMessage message, IotDataBridgeDO.RedisStreamMQConfig config) { | ||
| 47 | - try { | ||
| 48 | - // 1. 获取 RedisTemplate | ||
| 49 | - RedisTemplate<String, Object> redisTemplate = (RedisTemplate<String, Object>) getProducer(config); | ||
| 50 | - | ||
| 51 | - // 2. 创建并发送 Stream 记录 | ||
| 52 | - ObjectRecord<String, IotDeviceMessage> record = StreamRecords.newRecord() | ||
| 53 | - .ofObject(message).withStreamKey(config.getTopic()); | ||
| 54 | - String recordId = String.valueOf(redisTemplate.opsForStream().add(record)); | ||
| 55 | - log.info("[executeRedisStream][消息发送成功] messageId: {}, config: {}", recordId, config); | ||
| 56 | - } catch (Exception e) { | ||
| 57 | - log.error("[executeRedisStream][消息发送失败] message: {}, config: {}", message, config, e); | ||
| 58 | - } | 41 | + @Override |
| 42 | + public void execute0(IotDeviceMessage message, IotDataBridgeRedisStreamMQConfig config) throws Exception { | ||
| 43 | + // 1. 获取 RedisTemplate | ||
| 44 | + RedisTemplate<String, Object> redisTemplate = getProducer(config); | ||
| 45 | + | ||
| 46 | + // 2. 创建并发送 Stream 记录 | ||
| 47 | + ObjectRecord<String, IotDeviceMessage> record = StreamRecords.newRecord() | ||
| 48 | + .ofObject(message).withStreamKey(config.getTopic()); | ||
| 49 | + String recordId = String.valueOf(redisTemplate.opsForStream().add(record)); | ||
| 50 | + log.info("[executeRedisStream][消息发送成功] messageId: {}, config: {}", recordId, config); | ||
| 59 | } | 51 | } |
| 60 | 52 | ||
| 61 | @Override | 53 | @Override |
| 62 | - protected Object initProducer(Object config) { | ||
| 63 | - IotDataBridgeDO.RedisStreamMQConfig redisConfig = (IotDataBridgeDO.RedisStreamMQConfig) config; | ||
| 64 | - | 54 | + protected RedisTemplate<String, Object> initProducer(IotDataBridgeRedisStreamMQConfig config) { |
| 65 | // 1.1 创建 Redisson 配置 | 55 | // 1.1 创建 Redisson 配置 |
| 66 | Config redissonConfig = new Config(); | 56 | Config redissonConfig = new Config(); |
| 67 | SingleServerConfig serverConfig = redissonConfig.useSingleServer() | 57 | SingleServerConfig serverConfig = redissonConfig.useSingleServer() |
| 68 | - .setAddress("redis://" + redisConfig.getHost() + ":" + redisConfig.getPort()) | ||
| 69 | - .setDatabase(redisConfig.getDatabase()); | 58 | + .setAddress("redis://" + config.getHost() + ":" + config.getPort()) |
| 59 | + .setDatabase(config.getDatabase()); | ||
| 70 | // 1.2 设置密码(如果有) | 60 | // 1.2 设置密码(如果有) |
| 71 | - if (StrUtil.isNotBlank(redisConfig.getPassword())) { | ||
| 72 | - serverConfig.setPassword(redisConfig.getPassword()); | 61 | + if (StrUtil.isNotBlank(config.getPassword())) { |
| 62 | + serverConfig.setPassword(config.getPassword()); | ||
| 73 | } | 63 | } |
| 74 | 64 | ||
| 75 | // TODO @huihui:看看能不能简化一些。按道理说,不用这么多的哈。 | 65 | // TODO @huihui:看看能不能简化一些。按道理说,不用这么多的哈。 |
| @@ -90,17 +80,10 @@ public class IotRedisStreamMQDataBridgeExecute extends AbstractCacheableDataBrid | @@ -90,17 +80,10 @@ public class IotRedisStreamMQDataBridgeExecute extends AbstractCacheableDataBrid | ||
| 90 | } | 80 | } |
| 91 | 81 | ||
| 92 | @Override | 82 | @Override |
| 93 | - protected void closeProducer(Object producer) { | ||
| 94 | - // TODO @huihui:try catch 交给父类来做。子类不处理异常 | ||
| 95 | - if (producer instanceof RedisTemplate) { | ||
| 96 | - RedisConnectionFactory factory = ((RedisTemplate<?, ?>) producer).getConnectionFactory(); | ||
| 97 | - try { | ||
| 98 | - if (factory != null) { | ||
| 99 | - ((RedissonConnectionFactory) factory).destroy(); | ||
| 100 | - } | ||
| 101 | - } catch (Exception e) { | ||
| 102 | - log.error("[closeProducer][关闭 redisson 连接异常]", e); | ||
| 103 | - } | 83 | + protected void closeProducer(RedisTemplate<String, Object> producer) throws Exception { |
| 84 | + RedisConnectionFactory factory = producer.getConnectionFactory(); | ||
| 85 | + if (factory != null) { | ||
| 86 | + ((RedissonConnectionFactory) factory).destroy(); | ||
| 104 | } | 87 | } |
| 105 | } | 88 | } |
| 106 | 89 | ||
| @@ -119,7 +102,7 @@ public class IotRedisStreamMQDataBridgeExecute extends AbstractCacheableDataBrid | @@ -119,7 +102,7 @@ public class IotRedisStreamMQDataBridgeExecute extends AbstractCacheableDataBrid | ||
| 119 | IotRedisStreamMQDataBridgeExecute action = new IotRedisStreamMQDataBridgeExecute(); | 102 | IotRedisStreamMQDataBridgeExecute action = new IotRedisStreamMQDataBridgeExecute(); |
| 120 | 103 | ||
| 121 | // 2. 创建共享的配置 | 104 | // 2. 创建共享的配置 |
| 122 | - IotDataBridgeDO.RedisStreamMQConfig config = new IotDataBridgeDO.RedisStreamMQConfig(); | 105 | + IotDataBridgeRedisStreamMQConfig config = new IotDataBridgeRedisStreamMQConfig(); |
| 123 | config.setHost("127.0.0.1"); | 106 | config.setHost("127.0.0.1"); |
| 124 | config.setPort(6379); | 107 | config.setPort(6379); |
| 125 | config.setDatabase(0); | 108 | config.setDatabase(0); |
| @@ -140,11 +123,11 @@ public class IotRedisStreamMQDataBridgeExecute extends AbstractCacheableDataBrid | @@ -140,11 +123,11 @@ public class IotRedisStreamMQDataBridgeExecute extends AbstractCacheableDataBrid | ||
| 140 | .build(); | 123 | .build(); |
| 141 | 124 | ||
| 142 | // 4. 执行两次测试,验证缓存 | 125 | // 4. 执行两次测试,验证缓存 |
| 143 | - log.info("[main][第一次执行,应该会创建新的 RedisTemplate]"); | ||
| 144 | - action.executeRedisStream(message, config); | 126 | + log.info("[main][第一次执行,应该会创建新的 producer]"); |
| 127 | + action.execute(message, new IotDataBridgeDO().setType(action.getType()).setConfig(config)); | ||
| 145 | 128 | ||
| 146 | - log.info("[main][第二次执行,应该会复用缓存的 RedisTemplate]"); | ||
| 147 | - action.executeRedisStream(message, config); | 129 | + log.info("[main][第二次执行,应该会复用缓存的 producer]"); |
| 130 | + action.execute(message, new IotDataBridgeDO().setType(action.getType()).setConfig(config)); | ||
| 148 | } | 131 | } |
| 149 | 132 | ||
| 150 | } | 133 | } |
| 151 | \ No newline at end of file | 134 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/databridge/IotRocketMQDataBridgeExecute.java
| 1 | package cn.iocoder.yudao.module.iot.service.rule.action.databridge; | 1 | package cn.iocoder.yudao.module.iot.service.rule.action.databridge; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config.IotDataBridgeRocketMQConfig; | ||
| 3 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO; | 4 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO; |
| 4 | -import cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgTypeEnum; | 5 | +import cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgeTypeEnum; |
| 5 | import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | 6 | import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; |
| 6 | import lombok.extern.slf4j.Slf4j; | 7 | import lombok.extern.slf4j.Slf4j; |
| 7 | import org.apache.rocketmq.client.producer.DefaultMQProducer; | 8 | import org.apache.rocketmq.client.producer.DefaultMQProducer; |
| @@ -9,6 +10,7 @@ import org.apache.rocketmq.client.producer.SendResult; | @@ -9,6 +10,7 @@ import org.apache.rocketmq.client.producer.SendResult; | ||
| 9 | import org.apache.rocketmq.client.producer.SendStatus; | 10 | import org.apache.rocketmq.client.producer.SendStatus; |
| 10 | import org.apache.rocketmq.common.message.Message; | 11 | import org.apache.rocketmq.common.message.Message; |
| 11 | import org.apache.rocketmq.remoting.common.RemotingHelper; | 12 | import org.apache.rocketmq.remoting.common.RemotingHelper; |
| 13 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; | ||
| 12 | import org.springframework.stereotype.Component; | 14 | import org.springframework.stereotype.Component; |
| 13 | 15 | ||
| 14 | import java.time.LocalDateTime; | 16 | import java.time.LocalDateTime; |
| @@ -18,58 +20,49 @@ import java.time.LocalDateTime; | @@ -18,58 +20,49 @@ import java.time.LocalDateTime; | ||
| 18 | * | 20 | * |
| 19 | * @author HUIHUI | 21 | * @author HUIHUI |
| 20 | */ | 22 | */ |
| 23 | +@ConditionalOnClass(name = "org.apache.rocketmq.client.producer.DefaultMQProducer") | ||
| 21 | @Component | 24 | @Component |
| 22 | @Slf4j | 25 | @Slf4j |
| 23 | -public class IotRocketMQDataBridgeExecute extends AbstractCacheableDataBridgeExecute { | 26 | +public class IotRocketMQDataBridgeExecute extends |
| 27 | + AbstractCacheableDataBridgeExecute<IotDataBridgeRocketMQConfig, DefaultMQProducer> { | ||
| 24 | 28 | ||
| 25 | @Override | 29 | @Override |
| 26 | - public void execute(IotDeviceMessage message, IotDataBridgeDO dataBridge) { | ||
| 27 | - // 1.1 校验数据桥梁的类型 == ROCKETMQ | ||
| 28 | - if (!IotDataBridgTypeEnum.ROCKETMQ.getType().equals(dataBridge.getType())) { | ||
| 29 | - return; | ||
| 30 | - } | ||
| 31 | - // 1.2 执行 RocketMQ 发送消息 | ||
| 32 | - executeRocketMQ(message, (IotDataBridgeDO.RocketMQConfig) dataBridge.getConfig()); | 30 | + public Integer getType() { |
| 31 | + return IotDataBridgeTypeEnum.ROCKETMQ.getType(); | ||
| 33 | } | 32 | } |
| 34 | 33 | ||
| 35 | - private void executeRocketMQ(IotDeviceMessage message, IotDataBridgeDO.RocketMQConfig config) { | ||
| 36 | - try { | ||
| 37 | - // 1. 获取或创建 Producer | ||
| 38 | - DefaultMQProducer producer = (DefaultMQProducer) getProducer(config); | 34 | + @Override |
| 35 | + public void execute0(IotDeviceMessage message, IotDataBridgeRocketMQConfig config) throws Exception { | ||
| 36 | + // 1. 获取或创建 Producer | ||
| 37 | + DefaultMQProducer producer = getProducer(config); | ||
| 39 | 38 | ||
| 40 | - // 2.1 创建消息对象,指定Topic、Tag和消息体 | ||
| 41 | - Message msg = new Message( | ||
| 42 | - config.getTopic(), | ||
| 43 | - config.getTags(), | ||
| 44 | - message.toString().getBytes(RemotingHelper.DEFAULT_CHARSET) | ||
| 45 | - ); | ||
| 46 | - // 2.2 发送同步消息并处理结果 | ||
| 47 | - SendResult sendResult = producer.send(msg); | ||
| 48 | - // 2.3 处理发送结果 | ||
| 49 | - if (SendStatus.SEND_OK.equals(sendResult.getSendStatus())) { | ||
| 50 | - log.info("[executeRocketMQ][message({}) config({}) 发送成功,结果({})]", message, config, sendResult); | ||
| 51 | - } else { | ||
| 52 | - log.error("[executeRocketMQ][message({}) config({}) 发送失败,结果({})]", message, config, sendResult); | ||
| 53 | - } | ||
| 54 | - } catch (Exception e) { | ||
| 55 | - log.error("[executeRocketMQ][message({}) config({}) 发送异常]", message, config, e); | 39 | + // 2.1 创建消息对象,指定Topic、Tag和消息体 |
| 40 | + Message msg = new Message( | ||
| 41 | + config.getTopic(), | ||
| 42 | + config.getTags(), | ||
| 43 | + message.toString().getBytes(RemotingHelper.DEFAULT_CHARSET) | ||
| 44 | + ); | ||
| 45 | + // 2.2 发送同步消息并处理结果 | ||
| 46 | + SendResult sendResult = producer.send(msg); | ||
| 47 | + // 2.3 处理发送结果 | ||
| 48 | + if (SendStatus.SEND_OK.equals(sendResult.getSendStatus())) { | ||
| 49 | + log.info("[executeRocketMQ][message({}) config({}) 发送成功,结果({})]", message, config, sendResult); | ||
| 50 | + } else { | ||
| 51 | + log.error("[executeRocketMQ][message({}) config({}) 发送失败,结果({})]", message, config, sendResult); | ||
| 56 | } | 52 | } |
| 57 | } | 53 | } |
| 58 | 54 | ||
| 59 | @Override | 55 | @Override |
| 60 | - protected Object initProducer(Object config) throws Exception { | ||
| 61 | - IotDataBridgeDO.RocketMQConfig rocketMQConfig = (IotDataBridgeDO.RocketMQConfig) config; | ||
| 62 | - DefaultMQProducer producer = new DefaultMQProducer(rocketMQConfig.getGroup()); | ||
| 63 | - producer.setNamesrvAddr(rocketMQConfig.getNameServer()); | 56 | + protected DefaultMQProducer initProducer(IotDataBridgeRocketMQConfig config) throws Exception { |
| 57 | + DefaultMQProducer producer = new DefaultMQProducer(config.getGroup()); | ||
| 58 | + producer.setNamesrvAddr(config.getNameServer()); | ||
| 64 | producer.start(); | 59 | producer.start(); |
| 65 | return producer; | 60 | return producer; |
| 66 | } | 61 | } |
| 67 | 62 | ||
| 68 | @Override | 63 | @Override |
| 69 | - protected void closeProducer(Object producer) { | ||
| 70 | - if (producer instanceof DefaultMQProducer) { | ||
| 71 | - ((DefaultMQProducer) producer).shutdown(); | ||
| 72 | - } | 64 | + protected void closeProducer(DefaultMQProducer producer) { |
| 65 | + producer.shutdown(); | ||
| 73 | } | 66 | } |
| 74 | 67 | ||
| 75 | // TODO @芋艿:测试代码,后续清理 | 68 | // TODO @芋艿:测试代码,后续清理 |
| @@ -78,7 +71,7 @@ public class IotRocketMQDataBridgeExecute extends AbstractCacheableDataBridgeExe | @@ -78,7 +71,7 @@ public class IotRocketMQDataBridgeExecute extends AbstractCacheableDataBridgeExe | ||
| 78 | IotRocketMQDataBridgeExecute action = new IotRocketMQDataBridgeExecute(); | 71 | IotRocketMQDataBridgeExecute action = new IotRocketMQDataBridgeExecute(); |
| 79 | 72 | ||
| 80 | // 2. 创建共享的配置 | 73 | // 2. 创建共享的配置 |
| 81 | - IotDataBridgeDO.RocketMQConfig config = new IotDataBridgeDO.RocketMQConfig(); | 74 | + IotDataBridgeRocketMQConfig config = new IotDataBridgeRocketMQConfig(); |
| 82 | config.setNameServer("127.0.0.1:9876"); | 75 | config.setNameServer("127.0.0.1:9876"); |
| 83 | config.setGroup("test-group"); | 76 | config.setGroup("test-group"); |
| 84 | config.setTopic("test-topic"); | 77 | config.setTopic("test-topic"); |
| @@ -99,10 +92,10 @@ public class IotRocketMQDataBridgeExecute extends AbstractCacheableDataBridgeExe | @@ -99,10 +92,10 @@ public class IotRocketMQDataBridgeExecute extends AbstractCacheableDataBridgeExe | ||
| 99 | 92 | ||
| 100 | // 4. 执行两次测试,验证缓存 | 93 | // 4. 执行两次测试,验证缓存 |
| 101 | log.info("[main][第一次执行,应该会创建新的 producer]"); | 94 | log.info("[main][第一次执行,应该会创建新的 producer]"); |
| 102 | - action.executeRocketMQ(message, config); | 95 | + action.execute(message, new IotDataBridgeDO().setType(action.getType()).setConfig(config)); |
| 103 | 96 | ||
| 104 | log.info("[main][第二次执行,应该会复用缓存的 producer]"); | 97 | log.info("[main][第二次执行,应该会复用缓存的 producer]"); |
| 105 | - action.executeRocketMQ(message, config); | 98 | + action.execute(message, new IotDataBridgeDO().setType(action.getType()).setConfig(config)); |
| 106 | } | 99 | } |
| 107 | 100 | ||
| 108 | } | 101 | } |
yudao-server/pom.xml
| @@ -114,6 +114,19 @@ | @@ -114,6 +114,19 @@ | ||
| 114 | <artifactId>yudao-module-iot-biz</artifactId> | 114 | <artifactId>yudao-module-iot-biz</artifactId> |
| 115 | <version>${revision}</version> | 115 | <version>${revision}</version> |
| 116 | </dependency> | 116 | </dependency> |
| 117 | + <!-- IoT 数据桥梁的执行器所需消息队列。如果您只需要使用 rocketmq 那么则注释掉其它消息队列即可 --> | ||
| 118 | + <dependency> | ||
| 119 | + <groupId>org.apache.rocketmq</groupId> | ||
| 120 | + <artifactId>rocketmq-spring-boot-starter</artifactId> | ||
| 121 | + </dependency> | ||
| 122 | + <dependency> | ||
| 123 | + <groupId>org.springframework.kafka</groupId> | ||
| 124 | + <artifactId>spring-kafka</artifactId> | ||
| 125 | + </dependency> | ||
| 126 | + <dependency> | ||
| 127 | + <groupId>org.springframework.boot</groupId> | ||
| 128 | + <artifactId>spring-boot-starter-amqp</artifactId> | ||
| 129 | + </dependency> | ||
| 117 | 130 | ||
| 118 | <!-- spring boot 配置所需依赖 --> | 131 | <!-- spring boot 配置所需依赖 --> |
| 119 | <dependency> | 132 | <dependency> |