Commit 07f26a7e02291c71565207317b49012475d68ca0

Authored by panda
1 parent a08526d8

fix: 修复触发器和条件匹配器中缺少对产品和设备一致性的验证

yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/IotSceneRuleMatcherHelper.java
... ... @@ -2,13 +2,17 @@ package cn.iocoder.yudao.module.iot.service.rule.scene.matcher;
2 2  
3 3 import cn.hutool.core.text.CharPool;
4 4 import cn.hutool.core.util.NumberUtil;
  5 +import cn.hutool.core.util.ObjectUtil;
5 6 import cn.hutool.core.util.StrUtil;
6 7 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
7 8 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
8 9 import cn.iocoder.yudao.framework.common.util.spring.SpringExpressionUtils;
  10 +import cn.iocoder.yudao.framework.common.util.spring.SpringUtils;
9 11 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
  12 +import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
10 13 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO;
11 14 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleConditionOperatorEnum;
  15 +import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
12 16 import lombok.extern.slf4j.Slf4j;
13 17  
14 18 import java.util.HashMap;
... ... @@ -248,4 +252,16 @@ public final class IotSceneRuleMatcherHelper {
248 252 return StrUtil.isNotBlank(expectedIdentifier) && expectedIdentifier.equals(actualIdentifier);
249 253 }
250 254  
  255 + /**
  256 + * 校验匹配器中的产品和设备是否一致
  257 + * @param message 消息
  258 + * @param productId 产品ID
  259 + * @param deviceId 设备id
  260 + * @return 校验结果
  261 + */
  262 + public static boolean productAndDeviceNotMatched(IotDeviceMessage message, Long productId, Long deviceId) {
  263 + IotDeviceDO device = SpringUtils.getBean(IotDeviceService.class).getDeviceFromCache(message.getDeviceId());
  264 +
  265 + return IotDeviceDO.DEVICE_ID_ALL.equals(deviceId) ? ObjectUtil.notEqual(device.getProductId(), productId) : ObjectUtil.notEqual(message.getDeviceId(), deviceId);
  266 + }
251 267 }
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/condition/IotCurrentTimeConditionMatcher.java
... ... @@ -31,7 +31,13 @@ public class IotCurrentTimeConditionMatcher implements IotSceneRuleConditionMatc
31 31 return false;
32 32 }
33 33  
34   - // 1.2 检查操作符和参数是否有效
  34 + // 1.2 修复条件匹配中忽略了产品和设备的一致性验证,2025.05.25 by panda
  35 + if (IotSceneRuleMatcherHelper.productAndDeviceNotMatched(message, condition.getProductId(),condition.getDeviceId())){
  36 + IotSceneRuleMatcherHelper.logConditionMatchFailure(message,condition,"条件匹配器中产品或设备不匹配");
  37 + return false;
  38 + }
  39 +
  40 + // 1.3 检查操作符和参数是否有效
35 41 if (!IotSceneRuleMatcherHelper.isConditionOperatorAndParamValid(condition)) {
36 42 IotSceneRuleMatcherHelper.logConditionMatchFailure(message, condition, "操作符或参数无效");
37 43 return false;
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/condition/IotDevicePropertyConditionMatcher.java
... ... @@ -30,7 +30,13 @@ public class IotDevicePropertyConditionMatcher implements IotSceneRuleConditionM
30 30 return false;
31 31 }
32 32  
33   - // 1.2 检查消息中是否包含条件指定的属性标识符
  33 + // 1.2 修复条件匹配中忽略了产品和设备的一致性验证,2025.05.25 by panda
  34 + if (IotSceneRuleMatcherHelper.productAndDeviceNotMatched(message, condition.getProductId(),condition.getDeviceId())){
  35 + IotSceneRuleMatcherHelper.logConditionMatchFailure(message,condition,"条件匹配器中产品或设备不匹配");
  36 + return false;
  37 + }
  38 +
  39 + // 1.3 检查消息中是否包含条件指定的属性标识符
34 40 // 注意:属性上报可能同时上报多个属性,所以需要判断 condition.getIdentifier() 是否在 message 的 params 中
35 41 if (IotDeviceMessageUtils.notContainsIdentifier(message, condition.getIdentifier())) {
36 42 IotSceneRuleMatcherHelper.logConditionMatchFailure(message, condition, "消息中不包含属性: " + condition.getIdentifier());
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/condition/IotDeviceStateConditionMatcher.java
... ... @@ -27,8 +27,13 @@ public class IotDeviceStateConditionMatcher implements IotSceneRuleConditionMatc
27 27 IotSceneRuleMatcherHelper.logConditionMatchFailure(message, condition, "条件基础参数无效");
28 28 return false;
29 29 }
  30 + // 1.2 修复条件匹配中忽略了产品和设备的一致性验证,2025.05.25 by panda
  31 + if (IotSceneRuleMatcherHelper.productAndDeviceNotMatched(message, condition.getProductId(),condition.getDeviceId())){
  32 + IotSceneRuleMatcherHelper.logConditionMatchFailure(message,condition,"条件匹配器中产品或设备不匹配");
  33 + return false;
  34 + }
30 35  
31   - // 1.2 检查操作符和参数是否有效
  36 + // 1.3 检查操作符和参数是否有效
32 37 if (!IotSceneRuleMatcherHelper.isConditionOperatorAndParamValid(condition)) {
33 38 IotSceneRuleMatcherHelper.logConditionMatchFailure(message, condition, "操作符或参数无效");
34 39 return false;
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/IotDeviceEventPostTriggerMatcher.java
... ... @@ -43,7 +43,13 @@ public class IotDeviceEventPostTriggerMatcher implements IotSceneRuleTriggerMatc
43 43 return false;
44 44 }
45 45  
46   - // 1.3 检查标识符是否匹配
  46 + // 1.3 修复触发器中忽略了产品和设备的一致性验证,2025.05.25 by panda
  47 + if (IotSceneRuleMatcherHelper.productAndDeviceNotMatched(message, trigger.getProductId(),trigger.getDeviceId())){
  48 + IotSceneRuleMatcherHelper.logTriggerMatchFailure(message,trigger,"触发器中产品或设备不匹配");
  49 + return false;
  50 + }
  51 +
  52 + // 1.4 检查标识符是否匹配
47 53 String messageIdentifier = IotDeviceMessageUtils.getIdentifier(message);
48 54 if (!IotSceneRuleMatcherHelper.isIdentifierMatched(trigger.getIdentifier(), messageIdentifier)) {
49 55 IotSceneRuleMatcherHelper.logTriggerMatchFailure(message, trigger, "标识符不匹配,期望: " +
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/IotDevicePropertyPostTriggerMatcher.java
... ... @@ -36,7 +36,13 @@ public class IotDevicePropertyPostTriggerMatcher implements IotSceneRuleTriggerM
36 36 return false;
37 37 }
38 38  
39   - // 1.3 检查消息中是否包含触发器指定的属性标识符
  39 + // 1.3 修复触发器中忽略了产品和设备的一致性验证,2025.05.25 by panda
  40 + if (IotSceneRuleMatcherHelper.productAndDeviceNotMatched(message, trigger.getProductId(),trigger.getDeviceId())){
  41 + IotSceneRuleMatcherHelper.logTriggerMatchFailure(message,trigger,"触发器中产品或设备不匹配");
  42 + return false;
  43 + }
  44 +
  45 + // 1.4 检查消息中是否包含触发器指定的属性标识符
40 46 // 注意:属性上报可能同时上报多个属性,所以需要判断 trigger.getIdentifier() 是否在 message 的 params 中
41 47 if (IotDeviceMessageUtils.notContainsIdentifier(message, trigger.getIdentifier())) {
42 48 IotSceneRuleMatcherHelper.logTriggerMatchFailure(message, trigger, "消息中不包含属性: " +
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/IotDeviceServiceInvokeTriggerMatcher.java
... ... @@ -7,7 +7,9 @@ import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
7 7 import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils;
8 8 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO;
9 9 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum;
  10 +import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
10 11 import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatcherHelper;
  12 +import jakarta.annotation.Resource;
11 13 import org.springframework.stereotype.Component;
12 14  
13 15 import java.util.Map;
... ... @@ -20,6 +22,9 @@ import java.util.Map;
20 22 @Component
21 23 public class IotDeviceServiceInvokeTriggerMatcher implements IotSceneRuleTriggerMatcher {
22 24  
  25 + @Resource
  26 + private IotDeviceService iotDeviceService;
  27 +
23 28 @Override
24 29 public IotSceneRuleTriggerTypeEnum getSupportedTriggerType() {
25 30 return IotSceneRuleTriggerTypeEnum.DEVICE_SERVICE_INVOKE;
... ... @@ -37,7 +42,12 @@ public class IotDeviceServiceInvokeTriggerMatcher implements IotSceneRuleTrigger
37 42 IotSceneRuleMatcherHelper.logTriggerMatchFailure(message, trigger, "消息方法不匹配,期望: " + IotDeviceMessageMethodEnum.SERVICE_INVOKE.getMethod() + ", 实际: " + message.getMethod());
38 43 return false;
39 44 }
40   - // 1.3 检查标识符是否匹配
  45 + // 1.3 修复触发器中忽略了产品和设备的一致性验证,2025.05.25 by panda
  46 + if (IotSceneRuleMatcherHelper.productAndDeviceNotMatched(message, trigger.getProductId(),trigger.getDeviceId())){
  47 + IotSceneRuleMatcherHelper.logTriggerMatchFailure(message,trigger,"触发器中产品或设备不匹配");
  48 + return false;
  49 + }
  50 + // 1.4 检查标识符是否匹配
41 51 String messageIdentifier = IotDeviceMessageUtils.getIdentifier(message);
42 52 if (!IotSceneRuleMatcherHelper.isIdentifierMatched(trigger.getIdentifier(), messageIdentifier)) {
43 53 IotSceneRuleMatcherHelper.logTriggerMatchFailure(message, trigger, "标识符不匹配,期望: " + trigger.getIdentifier() + ", 实际: " + messageIdentifier);
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/IotDeviceStateUpdateTriggerMatcher.java
... ... @@ -5,7 +5,9 @@ import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
5 5 import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils;
6 6 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO;
7 7 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum;
  8 +import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
8 9 import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatcherHelper;
  10 +import jakarta.annotation.Resource;
9 11 import org.springframework.stereotype.Component;
10 12  
11 13 /**
... ... @@ -16,6 +18,9 @@ import org.springframework.stereotype.Component;
16 18 @Component
17 19 public class IotDeviceStateUpdateTriggerMatcher implements IotSceneRuleTriggerMatcher {
18 20  
  21 + @Resource
  22 + private IotDeviceService iotDeviceService;
  23 +
19 24 @Override
20 25 public IotSceneRuleTriggerTypeEnum getSupportedTriggerType() {
21 26 return IotSceneRuleTriggerTypeEnum.DEVICE_STATE_UPDATE;
... ... @@ -36,7 +41,13 @@ public class IotDeviceStateUpdateTriggerMatcher implements IotSceneRuleTriggerMa
36 41 return false;
37 42 }
38 43  
39   - // 1.3 检查操作符和值是否有效
  44 + // 1.3 修复触发器中忽略了产品和设备的一致性验证,2025.05.25 by panda
  45 + if (IotSceneRuleMatcherHelper.productAndDeviceNotMatched(message, trigger.getProductId(),trigger.getDeviceId())){
  46 + IotSceneRuleMatcherHelper.logTriggerMatchFailure(message,trigger,"触发器中产品或设备不匹配");
  47 + return false;
  48 + }
  49 +
  50 + // 1.4 检查操作符和值是否有效
40 51 if (!IotSceneRuleMatcherHelper.isTriggerOperatorAndValueValid(trigger)) {
41 52 IotSceneRuleMatcherHelper.logTriggerMatchFailure(message, trigger, "操作符或值无效");
42 53 return false;
... ...