Commit ce5e64e0aa635be458334af1d27236b102c6db4b

Authored by puhui999
1 parent 3b54deb9

【代码优化】IoT: 优化数据桥梁的执行器减少子类代码冗余

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&lt;Config, Producer&gt; imple @@ -93,4 +95,20 @@ public abstract class AbstractCacheableDataBridgeExecute&lt;Config, Producer&gt; 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&lt;Config&gt; { @@ -25,7 +25,7 @@ public interface IotDataBridgeExecute&lt;Config&gt; {
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&lt;Config&gt; { @@ -41,6 +41,6 @@ public interface IotDataBridgeExecute&lt;Config&gt; {
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 }