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,13 +2,17 @@ package cn.iocoder.yudao.module.iot.service.rule.scene.matcher; | ||
| 2 | 2 | ||
| 3 | import cn.hutool.core.text.CharPool; | 3 | import cn.hutool.core.text.CharPool; |
| 4 | import cn.hutool.core.util.NumberUtil; | 4 | import cn.hutool.core.util.NumberUtil; |
| 5 | +import cn.hutool.core.util.ObjectUtil; | ||
| 5 | import cn.hutool.core.util.StrUtil; | 6 | import cn.hutool.core.util.StrUtil; |
| 6 | import cn.iocoder.yudao.framework.common.util.number.NumberUtils; | 7 | import cn.iocoder.yudao.framework.common.util.number.NumberUtils; |
| 7 | import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; | 8 | import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; |
| 8 | import cn.iocoder.yudao.framework.common.util.spring.SpringExpressionUtils; | 9 | import cn.iocoder.yudao.framework.common.util.spring.SpringExpressionUtils; |
| 10 | +import cn.iocoder.yudao.framework.common.util.spring.SpringUtils; | ||
| 9 | import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | 11 | import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; |
| 12 | +import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; | ||
| 10 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO; | 13 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO; |
| 11 | import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleConditionOperatorEnum; | 14 | import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleConditionOperatorEnum; |
| 15 | +import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; | ||
| 12 | import lombok.extern.slf4j.Slf4j; | 16 | import lombok.extern.slf4j.Slf4j; |
| 13 | 17 | ||
| 14 | import java.util.HashMap; | 18 | import java.util.HashMap; |
| @@ -248,4 +252,16 @@ public final class IotSceneRuleMatcherHelper { | @@ -248,4 +252,16 @@ public final class IotSceneRuleMatcherHelper { | ||
| 248 | return StrUtil.isNotBlank(expectedIdentifier) && expectedIdentifier.equals(actualIdentifier); | 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,7 +31,13 @@ public class IotCurrentTimeConditionMatcher implements IotSceneRuleConditionMatc | ||
| 31 | return false; | 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 | if (!IotSceneRuleMatcherHelper.isConditionOperatorAndParamValid(condition)) { | 41 | if (!IotSceneRuleMatcherHelper.isConditionOperatorAndParamValid(condition)) { |
| 36 | IotSceneRuleMatcherHelper.logConditionMatchFailure(message, condition, "操作符或参数无效"); | 42 | IotSceneRuleMatcherHelper.logConditionMatchFailure(message, condition, "操作符或参数无效"); |
| 37 | return false; | 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,7 +30,13 @@ public class IotDevicePropertyConditionMatcher implements IotSceneRuleConditionM | ||
| 30 | return false; | 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 | // 注意:属性上报可能同时上报多个属性,所以需要判断 condition.getIdentifier() 是否在 message 的 params 中 | 40 | // 注意:属性上报可能同时上报多个属性,所以需要判断 condition.getIdentifier() 是否在 message 的 params 中 |
| 35 | if (IotDeviceMessageUtils.notContainsIdentifier(message, condition.getIdentifier())) { | 41 | if (IotDeviceMessageUtils.notContainsIdentifier(message, condition.getIdentifier())) { |
| 36 | IotSceneRuleMatcherHelper.logConditionMatchFailure(message, condition, "消息中不包含属性: " + condition.getIdentifier()); | 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,8 +27,13 @@ public class IotDeviceStateConditionMatcher implements IotSceneRuleConditionMatc | ||
| 27 | IotSceneRuleMatcherHelper.logConditionMatchFailure(message, condition, "条件基础参数无效"); | 27 | IotSceneRuleMatcherHelper.logConditionMatchFailure(message, condition, "条件基础参数无效"); |
| 28 | return false; | 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 | if (!IotSceneRuleMatcherHelper.isConditionOperatorAndParamValid(condition)) { | 37 | if (!IotSceneRuleMatcherHelper.isConditionOperatorAndParamValid(condition)) { |
| 33 | IotSceneRuleMatcherHelper.logConditionMatchFailure(message, condition, "操作符或参数无效"); | 38 | IotSceneRuleMatcherHelper.logConditionMatchFailure(message, condition, "操作符或参数无效"); |
| 34 | return false; | 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,7 +43,13 @@ public class IotDeviceEventPostTriggerMatcher implements IotSceneRuleTriggerMatc | ||
| 43 | return false; | 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 | String messageIdentifier = IotDeviceMessageUtils.getIdentifier(message); | 53 | String messageIdentifier = IotDeviceMessageUtils.getIdentifier(message); |
| 48 | if (!IotSceneRuleMatcherHelper.isIdentifierMatched(trigger.getIdentifier(), messageIdentifier)) { | 54 | if (!IotSceneRuleMatcherHelper.isIdentifierMatched(trigger.getIdentifier(), messageIdentifier)) { |
| 49 | IotSceneRuleMatcherHelper.logTriggerMatchFailure(message, trigger, "标识符不匹配,期望: " + | 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,7 +36,13 @@ public class IotDevicePropertyPostTriggerMatcher implements IotSceneRuleTriggerM | ||
| 36 | return false; | 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 | // 注意:属性上报可能同时上报多个属性,所以需要判断 trigger.getIdentifier() 是否在 message 的 params 中 | 46 | // 注意:属性上报可能同时上报多个属性,所以需要判断 trigger.getIdentifier() 是否在 message 的 params 中 |
| 41 | if (IotDeviceMessageUtils.notContainsIdentifier(message, trigger.getIdentifier())) { | 47 | if (IotDeviceMessageUtils.notContainsIdentifier(message, trigger.getIdentifier())) { |
| 42 | IotSceneRuleMatcherHelper.logTriggerMatchFailure(message, trigger, "消息中不包含属性: " + | 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 +7,9 @@ import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | ||
| 7 | import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils; | 7 | import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils; |
| 8 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO; | 8 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO; |
| 9 | import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum; | 9 | import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum; |
| 10 | +import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; | ||
| 10 | import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatcherHelper; | 11 | import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatcherHelper; |
| 12 | +import jakarta.annotation.Resource; | ||
| 11 | import org.springframework.stereotype.Component; | 13 | import org.springframework.stereotype.Component; |
| 12 | 14 | ||
| 13 | import java.util.Map; | 15 | import java.util.Map; |
| @@ -20,6 +22,9 @@ import java.util.Map; | @@ -20,6 +22,9 @@ import java.util.Map; | ||
| 20 | @Component | 22 | @Component |
| 21 | public class IotDeviceServiceInvokeTriggerMatcher implements IotSceneRuleTriggerMatcher { | 23 | public class IotDeviceServiceInvokeTriggerMatcher implements IotSceneRuleTriggerMatcher { |
| 22 | 24 | ||
| 25 | + @Resource | ||
| 26 | + private IotDeviceService iotDeviceService; | ||
| 27 | + | ||
| 23 | @Override | 28 | @Override |
| 24 | public IotSceneRuleTriggerTypeEnum getSupportedTriggerType() { | 29 | public IotSceneRuleTriggerTypeEnum getSupportedTriggerType() { |
| 25 | return IotSceneRuleTriggerTypeEnum.DEVICE_SERVICE_INVOKE; | 30 | return IotSceneRuleTriggerTypeEnum.DEVICE_SERVICE_INVOKE; |
| @@ -37,7 +42,12 @@ public class IotDeviceServiceInvokeTriggerMatcher implements IotSceneRuleTrigger | @@ -37,7 +42,12 @@ public class IotDeviceServiceInvokeTriggerMatcher implements IotSceneRuleTrigger | ||
| 37 | IotSceneRuleMatcherHelper.logTriggerMatchFailure(message, trigger, "消息方法不匹配,期望: " + IotDeviceMessageMethodEnum.SERVICE_INVOKE.getMethod() + ", 实际: " + message.getMethod()); | 42 | IotSceneRuleMatcherHelper.logTriggerMatchFailure(message, trigger, "消息方法不匹配,期望: " + IotDeviceMessageMethodEnum.SERVICE_INVOKE.getMethod() + ", 实际: " + message.getMethod()); |
| 38 | return false; | 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 | String messageIdentifier = IotDeviceMessageUtils.getIdentifier(message); | 51 | String messageIdentifier = IotDeviceMessageUtils.getIdentifier(message); |
| 42 | if (!IotSceneRuleMatcherHelper.isIdentifierMatched(trigger.getIdentifier(), messageIdentifier)) { | 52 | if (!IotSceneRuleMatcherHelper.isIdentifierMatched(trigger.getIdentifier(), messageIdentifier)) { |
| 43 | IotSceneRuleMatcherHelper.logTriggerMatchFailure(message, trigger, "标识符不匹配,期望: " + trigger.getIdentifier() + ", 实际: " + messageIdentifier); | 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,7 +5,9 @@ import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | ||
| 5 | import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils; | 5 | import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils; |
| 6 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO; | 6 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO; |
| 7 | import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum; | 7 | import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum; |
| 8 | +import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; | ||
| 8 | import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatcherHelper; | 9 | import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatcherHelper; |
| 10 | +import jakarta.annotation.Resource; | ||
| 9 | import org.springframework.stereotype.Component; | 11 | import org.springframework.stereotype.Component; |
| 10 | 12 | ||
| 11 | /** | 13 | /** |
| @@ -16,6 +18,9 @@ import org.springframework.stereotype.Component; | @@ -16,6 +18,9 @@ import org.springframework.stereotype.Component; | ||
| 16 | @Component | 18 | @Component |
| 17 | public class IotDeviceStateUpdateTriggerMatcher implements IotSceneRuleTriggerMatcher { | 19 | public class IotDeviceStateUpdateTriggerMatcher implements IotSceneRuleTriggerMatcher { |
| 18 | 20 | ||
| 21 | + @Resource | ||
| 22 | + private IotDeviceService iotDeviceService; | ||
| 23 | + | ||
| 19 | @Override | 24 | @Override |
| 20 | public IotSceneRuleTriggerTypeEnum getSupportedTriggerType() { | 25 | public IotSceneRuleTriggerTypeEnum getSupportedTriggerType() { |
| 21 | return IotSceneRuleTriggerTypeEnum.DEVICE_STATE_UPDATE; | 26 | return IotSceneRuleTriggerTypeEnum.DEVICE_STATE_UPDATE; |
| @@ -36,7 +41,13 @@ public class IotDeviceStateUpdateTriggerMatcher implements IotSceneRuleTriggerMa | @@ -36,7 +41,13 @@ public class IotDeviceStateUpdateTriggerMatcher implements IotSceneRuleTriggerMa | ||
| 36 | return false; | 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 | if (!IotSceneRuleMatcherHelper.isTriggerOperatorAndValueValid(trigger)) { | 51 | if (!IotSceneRuleMatcherHelper.isTriggerOperatorAndValueValid(trigger)) { |
| 41 | IotSceneRuleMatcherHelper.logTriggerMatchFailure(message, trigger, "操作符或值无效"); | 52 | IotSceneRuleMatcherHelper.logTriggerMatchFailure(message, trigger, "操作符或值无效"); |
| 42 | return false; | 53 | return false; |