Commit 07f26a7e02291c71565207317b49012475d68ca0
1 parent
a08526d8
fix: 修复触发器和条件匹配器中缺少对产品和设备一致性的验证
Showing
8 changed files
with
73 additions
and
7 deletions
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; | ... | ... |