Commit ce5e64e0aa635be458334af1d27236b102c6db4b
1 parent
3b54deb9
【代码优化】IoT: 优化数据桥梁的执行器减少子类代码冗余
Showing
8 changed files
with
85 additions
and
83 deletions
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,10 +26,10 @@ public class IotRuleSceneDataBridgeAction implements IotRuleSceneAction { | @@ -26,10 +26,10 @@ 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; |
| @@ -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; |
| @@ -93,4 +95,20 @@ public abstract class AbstractCacheableDataBridgeExecute<Config, Producer> imple | @@ -93,4 +95,20 @@ public abstract class AbstractCacheableDataBridgeExecute<Config, Producer> imple | ||
| 93 | */ | 95 | */ |
| 94 | protected abstract void closeProducer(Producer producer) throws Exception; | 96 | protected abstract void closeProducer(Producer producer) throws Exception; |
| 95 | 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 | + } | ||
| 113 | + | ||
| 96 | } | 114 | } |
| 97 | \ 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
| @@ -25,7 +25,7 @@ public interface IotDataBridgeExecute<Config> { | @@ -25,7 +25,7 @@ public interface IotDataBridgeExecute<Config> { | ||
| 25 | * @param dataBridge 数据桥梁 | 25 | * @param dataBridge 数据桥梁 |
| 26 | */ | 26 | */ |
| 27 | @SuppressWarnings({"unchecked"}) | 27 | @SuppressWarnings({"unchecked"}) |
| 28 | - default void execute(IotDeviceMessage message, IotDataBridgeDO dataBridge) { | 28 | + default void execute(IotDeviceMessage message, IotDataBridgeDO dataBridge) throws Exception { |
| 29 | // 1.1 校验数据桥梁类型 | 29 | // 1.1 校验数据桥梁类型 |
| 30 | if (!getType().equals(dataBridge.getType())) { | 30 | if (!getType().equals(dataBridge.getType())) { |
| 31 | return; | 31 | return; |
| @@ -41,6 +41,6 @@ public interface IotDataBridgeExecute<Config> { | @@ -41,6 +41,6 @@ public interface IotDataBridgeExecute<Config> { | ||
| 41 | * @param message 设备消息 | 41 | * @param message 设备消息 |
| 42 | * @param config 桥梁配置 | 42 | * @param config 桥梁配置 |
| 43 | */ | 43 | */ |
| 44 | - void execute0(IotDeviceMessage message, Config config); | 44 | + void execute0(IotDeviceMessage message, Config config) throws Exception; |
| 45 | 45 | ||
| 46 | } | 46 | } |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/databridge/IotKafkaMQDataBridgeExecute.java
| @@ -15,7 +15,6 @@ import java.time.LocalDateTime; | @@ -15,7 +15,6 @@ import java.time.LocalDateTime; | ||
| 15 | import java.util.HashMap; | 15 | import java.util.HashMap; |
| 16 | import java.util.Map; | 16 | import java.util.Map; |
| 17 | import java.util.concurrent.TimeUnit; | 17 | import java.util.concurrent.TimeUnit; |
| 18 | -import java.util.concurrent.TimeoutException; | ||
| 19 | 18 | ||
| 20 | /** | 19 | /** |
| 21 | * Kafka 的 {@link IotDataBridgeExecute} 实现类 | 20 | * Kafka 的 {@link IotDataBridgeExecute} 实现类 |
| @@ -35,20 +34,14 @@ public class IotKafkaMQDataBridgeExecute extends | @@ -35,20 +34,14 @@ public class IotKafkaMQDataBridgeExecute extends | ||
| 35 | } | 34 | } |
| 36 | 35 | ||
| 37 | @Override | 36 | @Override |
| 38 | - public void execute0(IotDeviceMessage message, IotDataBridgeDO.KafkaMQConfig config) { | ||
| 39 | - try { | ||
| 40 | - // 1. 获取或创建 KafkaTemplate | ||
| 41 | - KafkaTemplate<String, String> kafkaTemplate = getProducer(config); | ||
| 42 | - | ||
| 43 | - // 2. 发送消息并等待结果 | ||
| 44 | - kafkaTemplate.send(config.getTopic(), message.toString()) | ||
| 45 | - .get(SEND_TIMEOUT.getSeconds(), TimeUnit.SECONDS); // 添加超时等待 | ||
| 46 | - log.info("[executeKafka][message({}) 发送成功]", message); | ||
| 47 | - } catch (TimeoutException e) { | ||
| 48 | - log.error("[executeKafka][message({}) config({}) 发送超时]", message, config, e); | ||
| 49 | - } catch (Exception e) { | ||
| 50 | - log.error("[executeKafka][message({}) config({}) 发送异常]", message, config, e); | ||
| 51 | - } | 37 | + public void execute0(IotDeviceMessage message, IotDataBridgeDO.KafkaMQConfig config) throws Exception { |
| 38 | + // 1. 获取或创建 KafkaTemplate | ||
| 39 | + KafkaTemplate<String, String> kafkaTemplate = getProducer(config); | ||
| 40 | + | ||
| 41 | + // 2. 发送消息并等待结果 | ||
| 42 | + kafkaTemplate.send(config.getTopic(), message.toString()) | ||
| 43 | + .get(SEND_TIMEOUT.getSeconds(), TimeUnit.SECONDS); // 添加超时等待 | ||
| 44 | + log.info("[execute0][message({}) 发送成功]", message); | ||
| 52 | } | 45 | } |
| 53 | 46 | ||
| 54 | @Override | 47 | @Override |
| @@ -109,10 +102,10 @@ public class IotKafkaMQDataBridgeExecute extends | @@ -109,10 +102,10 @@ public class IotKafkaMQDataBridgeExecute extends | ||
| 109 | 102 | ||
| 110 | // 4. 执行两次测试,验证缓存 | 103 | // 4. 执行两次测试,验证缓存 |
| 111 | log.info("[main][第一次执行,应该会创建新的 producer]"); | 104 | log.info("[main][第一次执行,应该会创建新的 producer]"); |
| 112 | - action.execute0(message, config); | 105 | + action.execute(message, new IotDataBridgeDO().setType(action.getType()).setConfig(config)); |
| 113 | 106 | ||
| 114 | log.info("[main][第二次执行,应该会复用缓存的 producer]"); | 107 | log.info("[main][第二次执行,应该会复用缓存的 producer]"); |
| 115 | - action.execute0(message, config); | 108 | + action.execute(message, new IotDataBridgeDO().setType(action.getType()).setConfig(config)); |
| 116 | } | 109 | } |
| 117 | 110 | ||
| 118 | } | 111 | } |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/databridge/IotRabbitMQDataBridgeExecute.java
| @@ -29,23 +29,19 @@ public class IotRabbitMQDataBridgeExecute extends | @@ -29,23 +29,19 @@ public class IotRabbitMQDataBridgeExecute extends | ||
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | @Override | 31 | @Override |
| 32 | - public void execute0(IotDeviceMessage message, IotDataBridgeDO.RabbitMQConfig config) { | ||
| 33 | - try { | ||
| 34 | - // 1. 获取或创建 Channel | ||
| 35 | - Channel channel = getProducer(config); | ||
| 36 | - | ||
| 37 | - // 2.1 声明交换机、队列和绑定关系 | ||
| 38 | - channel.exchangeDeclare(config.getExchange(), "direct", true); | ||
| 39 | - channel.queueDeclare(config.getQueue(), true, false, false, null); | ||
| 40 | - channel.queueBind(config.getQueue(), config.getExchange(), config.getRoutingKey()); | ||
| 41 | - | ||
| 42 | - // 2.2 发送消息 | ||
| 43 | - channel.basicPublish(config.getExchange(), config.getRoutingKey(), null, | ||
| 44 | - message.toString().getBytes(StandardCharsets.UTF_8)); | ||
| 45 | - log.info("[executeRabbitMQ][message({}) config({}) 发送成功]", message, config); | ||
| 46 | - } catch (Exception e) { | ||
| 47 | - log.error("[executeRabbitMQ][message({}) config({}) 发送异常]", message, config, e); | ||
| 48 | - } | 32 | + public void execute0(IotDeviceMessage message, IotDataBridgeDO.RabbitMQConfig config) throws Exception { |
| 33 | + // 1. 获取或创建 Channel | ||
| 34 | + Channel channel = getProducer(config); | ||
| 35 | + | ||
| 36 | + // 2.1 声明交换机、队列和绑定关系 | ||
| 37 | + channel.exchangeDeclare(config.getExchange(), "direct", true); | ||
| 38 | + channel.queueDeclare(config.getQueue(), true, false, false, null); | ||
| 39 | + channel.queueBind(config.getQueue(), config.getExchange(), config.getRoutingKey()); | ||
| 40 | + | ||
| 41 | + // 2.2 发送消息 | ||
| 42 | + channel.basicPublish(config.getExchange(), config.getRoutingKey(), null, | ||
| 43 | + message.toString().getBytes(StandardCharsets.UTF_8)); | ||
| 44 | + log.info("[executeRabbitMQ][message({}) config({}) 发送成功]", message, config); | ||
| 49 | } | 45 | } |
| 50 | 46 | ||
| 51 | @Override | 47 | @Override |
| @@ -107,11 +103,12 @@ public class IotRabbitMQDataBridgeExecute extends | @@ -107,11 +103,12 @@ public class IotRabbitMQDataBridgeExecute extends | ||
| 107 | .build(); | 103 | .build(); |
| 108 | 104 | ||
| 109 | // 4. 执行两次测试,验证缓存 | 105 | // 4. 执行两次测试,验证缓存 |
| 110 | - log.info("[main][第一次执行,应该会创建新的 channel]"); | ||
| 111 | - action.execute0(message, config); | 106 | + // 4. 执行两次测试,验证缓存 |
| 107 | + log.info("[main][第一次执行,应该会创建新的 producer]"); | ||
| 108 | + action.execute(message, new IotDataBridgeDO().setType(action.getType()).setConfig(config)); | ||
| 112 | 109 | ||
| 113 | - log.info("[main][第二次执行,应该会复用缓存的 channel]"); | ||
| 114 | - action.execute0(message, config); | 110 | + log.info("[main][第二次执行,应该会复用缓存的 producer]"); |
| 111 | + action.execute(message, new IotDataBridgeDO().setType(action.getType()).setConfig(config)); | ||
| 115 | } | 112 | } |
| 116 | 113 | ||
| 117 | } | 114 | } |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/databridge/IotRedisStreamMQDataBridgeExecute.java
| @@ -38,19 +38,15 @@ public class IotRedisStreamMQDataBridgeExecute extends | @@ -38,19 +38,15 @@ public class IotRedisStreamMQDataBridgeExecute extends | ||
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | @Override | 40 | @Override |
| 41 | - public void execute0(IotDeviceMessage message, IotDataBridgeDO.RedisStreamMQConfig config) { | ||
| 42 | - try { | ||
| 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); | ||
| 51 | - } catch (Exception e) { | ||
| 52 | - log.error("[executeRedisStream][消息发送失败] message: {}, config: {}", message, config, e); | ||
| 53 | - } | 41 | + public void execute0(IotDeviceMessage message, IotDataBridgeDO.RedisStreamMQConfig config) throws Exception { |
| 42 | + // 1. 获取 RedisTemplate | ||
| 43 | + RedisTemplate<String, Object> redisTemplate = getProducer(config); | ||
| 44 | + | ||
| 45 | + // 2. 创建并发送 Stream 记录 | ||
| 46 | + ObjectRecord<String, IotDeviceMessage> record = StreamRecords.newRecord() | ||
| 47 | + .ofObject(message).withStreamKey(config.getTopic()); | ||
| 48 | + String recordId = String.valueOf(redisTemplate.opsForStream().add(record)); | ||
| 49 | + log.info("[executeRedisStream][消息发送成功] messageId: {}, config: {}", recordId, config); | ||
| 54 | } | 50 | } |
| 55 | 51 | ||
| 56 | @Override | 52 | @Override |
| @@ -126,11 +122,11 @@ public class IotRedisStreamMQDataBridgeExecute extends | @@ -126,11 +122,11 @@ public class IotRedisStreamMQDataBridgeExecute extends | ||
| 126 | .build(); | 122 | .build(); |
| 127 | 123 | ||
| 128 | // 4. 执行两次测试,验证缓存 | 124 | // 4. 执行两次测试,验证缓存 |
| 129 | - log.info("[main][第一次执行,应该会创建新的 RedisTemplate]"); | ||
| 130 | - action.execute0(message, config); | 125 | + log.info("[main][第一次执行,应该会创建新的 producer]"); |
| 126 | + action.execute(message, new IotDataBridgeDO().setType(action.getType()).setConfig(config)); | ||
| 131 | 127 | ||
| 132 | - log.info("[main][第二次执行,应该会复用缓存的 RedisTemplate]"); | ||
| 133 | - action.execute0(message, config); | 128 | + log.info("[main][第二次执行,应该会复用缓存的 producer]"); |
| 129 | + action.execute(message, new IotDataBridgeDO().setType(action.getType()).setConfig(config)); | ||
| 134 | } | 130 | } |
| 135 | 131 | ||
| 136 | } | 132 | } |
| 137 | \ No newline at end of file | 133 | \ 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
| @@ -29,27 +29,23 @@ public class IotRocketMQDataBridgeExecute extends | @@ -29,27 +29,23 @@ public class IotRocketMQDataBridgeExecute extends | ||
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | @Override | 31 | @Override |
| 32 | - public void execute0(IotDeviceMessage message, IotDataBridgeDO.RocketMQConfig config) { | ||
| 33 | - try { | ||
| 34 | - // 1. 获取或创建 Producer | ||
| 35 | - DefaultMQProducer producer = getProducer(config); | 32 | + public void execute0(IotDeviceMessage message, IotDataBridgeDO.RocketMQConfig config) throws Exception { |
| 33 | + // 1. 获取或创建 Producer | ||
| 34 | + DefaultMQProducer producer = getProducer(config); | ||
| 36 | 35 | ||
| 37 | - // 2.1 创建消息对象,指定Topic、Tag和消息体 | ||
| 38 | - Message msg = new Message( | ||
| 39 | - config.getTopic(), | ||
| 40 | - config.getTags(), | ||
| 41 | - message.toString().getBytes(RemotingHelper.DEFAULT_CHARSET) | ||
| 42 | - ); | ||
| 43 | - // 2.2 发送同步消息并处理结果 | ||
| 44 | - SendResult sendResult = producer.send(msg); | ||
| 45 | - // 2.3 处理发送结果 | ||
| 46 | - if (SendStatus.SEND_OK.equals(sendResult.getSendStatus())) { | ||
| 47 | - log.info("[executeRocketMQ][message({}) config({}) 发送成功,结果({})]", message, config, sendResult); | ||
| 48 | - } else { | ||
| 49 | - log.error("[executeRocketMQ][message({}) config({}) 发送失败,结果({})]", message, config, sendResult); | ||
| 50 | - } | ||
| 51 | - } catch (Exception e) { | ||
| 52 | - log.error("[executeRocketMQ][message({}) config({}) 发送异常]", message, config, e); | 36 | + // 2.1 创建消息对象,指定Topic、Tag和消息体 |
| 37 | + Message msg = new Message( | ||
| 38 | + config.getTopic(), | ||
| 39 | + config.getTags(), | ||
| 40 | + message.toString().getBytes(RemotingHelper.DEFAULT_CHARSET) | ||
| 41 | + ); | ||
| 42 | + // 2.2 发送同步消息并处理结果 | ||
| 43 | + SendResult sendResult = producer.send(msg); | ||
| 44 | + // 2.3 处理发送结果 | ||
| 45 | + if (SendStatus.SEND_OK.equals(sendResult.getSendStatus())) { | ||
| 46 | + log.info("[executeRocketMQ][message({}) config({}) 发送成功,结果({})]", message, config, sendResult); | ||
| 47 | + } else { | ||
| 48 | + log.error("[executeRocketMQ][message({}) config({}) 发送失败,结果({})]", message, config, sendResult); | ||
| 53 | } | 49 | } |
| 54 | } | 50 | } |
| 55 | 51 | ||
| @@ -93,10 +89,10 @@ public class IotRocketMQDataBridgeExecute extends | @@ -93,10 +89,10 @@ public class IotRocketMQDataBridgeExecute extends | ||
| 93 | 89 | ||
| 94 | // 4. 执行两次测试,验证缓存 | 90 | // 4. 执行两次测试,验证缓存 |
| 95 | log.info("[main][第一次执行,应该会创建新的 producer]"); | 91 | log.info("[main][第一次执行,应该会创建新的 producer]"); |
| 96 | - action.execute0(message, config); | 92 | + action.execute(message, new IotDataBridgeDO().setType(action.getType()).setConfig(config)); |
| 97 | 93 | ||
| 98 | log.info("[main][第二次执行,应该会复用缓存的 producer]"); | 94 | log.info("[main][第二次执行,应该会复用缓存的 producer]"); |
| 99 | - action.execute0(message, config); | 95 | + action.execute(message, new IotDataBridgeDO().setType(action.getType()).setConfig(config)); |
| 100 | } | 96 | } |
| 101 | 97 | ||
| 102 | } | 98 | } |