diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/IotSceneRuleMatcher.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/IotSceneRuleMatcher.java index fb86fa9ffe..f799a45147 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/IotSceneRuleMatcher.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/IotSceneRuleMatcher.java @@ -1,91 +1,20 @@ package cn.iocoder.yudao.module.iot.service.rule.scene.matcher; -import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; -import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO; -import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleConditionTypeEnum; -import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum; +import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.condition.IotSceneRuleConditionMatcher; +import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.trigger.IotSceneRuleTriggerMatcher; /** - * IoT 场景规则匹配器统一接口 + * IoT 场景规则匹配器基础接口 *
- * 支持触发器匹配和条件匹配两种类型,遵循策略模式设计 + * 定义所有匹配器的通用行为,包括优先级、名称和启用状态 *
- * 匹配器类型说明: - * - 触发器匹配器:用于匹配主触发条件(如设备消息类型、定时器等) - * - 条件匹配器:用于匹配子条件(如设备状态、属性值、时间条件等) + * - {@link IotSceneRuleTriggerMatcher} 触发器匹配器 + * - {@link IotSceneRuleConditionMatcher} 条件匹配器 * * @author HUIHUI */ public interface IotSceneRuleMatcher { - /** - * 匹配器类型枚举 - */ - enum MatcherTypeEnum { - - /** - * 触发器匹配器 - 用于匹配主触发条件 - */ - TRIGGER, - - /** - * 条件匹配器 - 用于匹配子条件 - */ - CONDITION - - } - - /** - * 获取匹配器类型 - * - * @return 匹配器类型 - */ - MatcherTypeEnum getMatcherType(); - - // TODO @puhui999:【重要】有个思路,IotSceneRuleMatcher 拆分成 2 种 mather 接口;然后 AbstractIotSceneRuleMatcher 是个 Helper 工具类; - - // TODO @puhui999:是不是和 AbstractSceneRuleMatcher 一样,分下块; - - /** - * 获取支持的触发器类型(仅触发器匹配器需要实现) - * - * @return 触发器类型枚举,条件匹配器返回 null - */ - default IotSceneRuleTriggerTypeEnum getSupportedTriggerType() { - return null; - } - - /** - * 获取支持的条件类型(仅条件匹配器需要实现) - * - * @return 条件类型枚举,触发器匹配器返回 null - */ - default IotSceneRuleConditionTypeEnum getSupportedConditionType() { - return null; - } - - /** - * 检查触发器是否匹配消息(仅触发器匹配器需要实现) - * - * @param message 设备消息 - * @param trigger 触发器配置 - * @return 是否匹配 - */ - default boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger) { - throw new UnsupportedOperationException("触发器匹配方法仅支持触发器匹配器"); - } - - /** - * 检查条件是否匹配消息(仅条件匹配器需要实现) - * - * @param message 设备消息 - * @param condition 触发条件 - * @return 是否匹配 - */ - default boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.TriggerCondition condition) { - throw new UnsupportedOperationException("条件匹配方法仅支持条件匹配器"); - } - /** * 获取匹配优先级(数值越小优先级越高) *
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/AbstractIotSceneRuleMatcher.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/IotSceneRuleMatcherHelper.java similarity index 65% rename from yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/AbstractIotSceneRuleMatcher.java rename to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/IotSceneRuleMatcherHelper.java index 5d48bba293..dc67237786 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/AbstractIotSceneRuleMatcher.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/IotSceneRuleMatcherHelper.java @@ -15,16 +15,22 @@ import java.util.Map; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; /** - * IoT 场景规则匹配器抽象基类 + * IoT 场景规则匹配器工具类 *
- * 提供通用的条件评估逻辑和工具方法,支持触发器和条件两种匹配类型 + * 提供通用的条件评估逻辑和工具方法,供触发器和条件匹配器使用 + *
+ * 该类包含了匹配器实现中常用的工具方法,如条件评估、参数校验、日志记录等
*
* @author HUIHUI
*/
@Slf4j
-public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher {
+public final class IotSceneRuleMatcherHelper {
- // TODO @puhui999:这个是不是也是【通用】条件哈?
+ /**
+ * 私有构造函数,防止实例化
+ */
+ private IotSceneRuleMatcherHelper() {
+ }
/**
* 评估条件是否匹配
@@ -35,7 +41,7 @@ public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher
* @return 是否匹配
*/
@SuppressWarnings("DataFlowIssue")
- protected boolean evaluateCondition(Object sourceValue, String operator, String paramValue) {
+ public static boolean evaluateCondition(Object sourceValue, String operator, String paramValue) {
try {
// 1. 校验操作符是否合法
IotSceneRuleConditionOperatorEnum operatorEnum = IotSceneRuleConditionOperatorEnum.operatorOf(operator);
@@ -80,7 +86,7 @@ public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher
* @param trigger 触发器配置
* @return 是否有效
*/
- protected boolean isBasicTriggerValid(IotSceneRuleDO.Trigger trigger) {
+ public static boolean isBasicTriggerValid(IotSceneRuleDO.Trigger trigger) {
return trigger != null && trigger.getType() != null;
}
@@ -90,29 +96,31 @@ public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher
* @param trigger 触发器配置
* @return 是否有效
*/
- protected boolean isTriggerOperatorAndValueValid(IotSceneRuleDO.Trigger trigger) {
+ public static boolean isTriggerOperatorAndValueValid(IotSceneRuleDO.Trigger trigger) {
return StrUtil.isNotBlank(trigger.getOperator()) && StrUtil.isNotBlank(trigger.getValue());
}
/**
* 记录触发器匹配成功日志
*
- * @param message 设备消息
- * @param trigger 触发器配置
+ * @param matcherName 匹配器名称
+ * @param message 设备消息
+ * @param trigger 触发器配置
*/
- protected void logTriggerMatchSuccess(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger) {
- log.debug("[{}][消息({}) 匹配触发器({}) 成功]", getMatcherName(), message.getRequestId(), trigger.getType());
+ public static void logTriggerMatchSuccess(String matcherName, IotDeviceMessage message, IotSceneRuleDO.Trigger trigger) {
+ log.debug("[{}][消息({}) 匹配触发器({}) 成功]", matcherName, message.getRequestId(), trigger.getType());
}
/**
* 记录触发器匹配失败日志
*
- * @param message 设备消息
- * @param trigger 触发器配置
- * @param reason 失败原因
+ * @param matcherName 匹配器名称
+ * @param message 设备消息
+ * @param trigger 触发器配置
+ * @param reason 失败原因
*/
- protected void logTriggerMatchFailure(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger, String reason) {
- log.debug("[{}][消息({}) 匹配触发器({}) 失败: {}]", getMatcherName(), message.getRequestId(), trigger.getType(), reason);
+ public static void logTriggerMatchFailure(String matcherName, IotDeviceMessage message, IotSceneRuleDO.Trigger trigger, String reason) {
+ log.debug("[{}][消息({}) 匹配触发器({}) 失败: {}]", matcherName, message.getRequestId(), trigger.getType(), reason);
}
// ========== 【条件】相关工具方法 ==========
@@ -123,7 +131,7 @@ public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher
* @param condition 触发条件
* @return 是否有效
*/
- protected boolean isBasicConditionValid(IotSceneRuleDO.TriggerCondition condition) {
+ public static boolean isBasicConditionValid(IotSceneRuleDO.TriggerCondition condition) {
return condition != null && condition.getType() != null;
}
@@ -133,29 +141,31 @@ public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher
* @param condition 触发条件
* @return 是否有效
*/
- protected boolean isConditionOperatorAndParamValid(IotSceneRuleDO.TriggerCondition condition) {
+ public static boolean isConditionOperatorAndParamValid(IotSceneRuleDO.TriggerCondition condition) {
return StrUtil.isNotBlank(condition.getOperator()) && StrUtil.isNotBlank(condition.getParam());
}
/**
* 记录条件匹配成功日志
*
- * @param message 设备消息
- * @param condition 触发条件
+ * @param matcherName 匹配器名称
+ * @param message 设备消息
+ * @param condition 触发条件
*/
- protected void logConditionMatchSuccess(IotDeviceMessage message, IotSceneRuleDO.TriggerCondition condition) {
- log.debug("[{}][消息({}) 匹配条件({}) 成功]", getMatcherName(), message.getRequestId(), condition.getType());
+ public static void logConditionMatchSuccess(String matcherName, IotDeviceMessage message, IotSceneRuleDO.TriggerCondition condition) {
+ log.debug("[{}][消息({}) 匹配条件({}) 成功]", matcherName, message.getRequestId(), condition.getType());
}
/**
* 记录条件匹配失败日志
*
- * @param message 设备消息
- * @param condition 触发条件
- * @param reason 失败原因
+ * @param matcherName 匹配器名称
+ * @param message 设备消息
+ * @param condition 触发条件
+ * @param reason 失败原因
*/
- protected void logConditionMatchFailure(IotDeviceMessage message, IotSceneRuleDO.TriggerCondition condition, String reason) {
- log.debug("[{}][消息({}) 匹配条件({}) 失败: {}]", getMatcherName(), message.getRequestId(), condition.getType(), reason);
+ public static void logConditionMatchFailure(String matcherName, IotDeviceMessage message, IotSceneRuleDO.TriggerCondition condition, String reason) {
+ log.debug("[{}][消息({}) 匹配条件({}) 失败: {}]", matcherName, message.getRequestId(), condition.getType(), reason);
}
// ========== 【通用】工具方法 ==========
@@ -167,7 +177,7 @@ public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher
* @param actualIdentifier 实际的标识符
* @return 是否匹配
*/
- protected boolean isIdentifierMatched(String expectedIdentifier, String actualIdentifier) {
+ public static boolean isIdentifierMatched(String expectedIdentifier, String actualIdentifier) {
return StrUtil.isNotBlank(expectedIdentifier) && expectedIdentifier.equals(actualIdentifier);
}
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/IotSceneRuleMatcherManager.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/IotSceneRuleMatcherManager.java
index a73e915d73..d077579f70 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/IotSceneRuleMatcherManager.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/IotSceneRuleMatcherManager.java
@@ -5,6 +5,8 @@ import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO;
import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleConditionTypeEnum;
import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum;
+import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.condition.IotSceneRuleConditionMatcher;
+import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.trigger.IotSceneRuleTriggerMatcher;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@@ -30,14 +32,14 @@ public class IotSceneRuleMatcherManager {
* Key: 触发器类型枚举
* Value: 对应的匹配器实例
*/
- private final Map
+ * 专门处理子条件的匹配逻辑,如设备状态、属性值、时间条件等
+ *
+ * 条件匹配器负责判断设备消息是否满足场景规则的附加条件,
+ * 在触发器匹配成功后进行进一步的条件筛选
+ *
+ * @author HUIHUI
+ */
+public interface IotSceneRuleConditionMatcher extends IotSceneRuleMatcher {
+
+ /**
+ * 获取支持的条件类型
+ *
+ * @return 条件类型枚举
+ */
+ IotSceneRuleConditionTypeEnum getSupportedConditionType();
+
+ /**
+ * 检查条件是否匹配消息
+ *
+ * 判断设备消息是否满足指定的触发条件
+ *
+ * @param message 设备消息
+ * @param condition 触发条件
+ * @return 是否匹配
+ */
+ boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.TriggerCondition condition);
+
+}
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DeviceEventPostTriggerMatcher.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DeviceEventPostTriggerMatcher.java
index edd5ea3a8e..957348e38f 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DeviceEventPostTriggerMatcher.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DeviceEventPostTriggerMatcher.java
@@ -6,7 +6,7 @@ import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils;
import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO;
import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum;
-import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.AbstractIotSceneRuleMatcher;
+import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatcherHelper;
import org.springframework.stereotype.Component;
/**
@@ -17,18 +17,13 @@ import org.springframework.stereotype.Component;
* @author HUIHUI
*/
@Component
-public class DeviceEventPostTriggerMatcher extends AbstractIotSceneRuleMatcher {
+public class DeviceEventPostTriggerMatcher implements IotSceneRuleTriggerMatcher {
/**
* 设备事件上报消息方法
*/
private static final String DEVICE_EVENT_POST_METHOD = IotDeviceMessageMethodEnum.EVENT_POST.getMethod();
- @Override
- public MatcherTypeEnum getMatcherType() {
- return MatcherTypeEnum.TRIGGER;
- }
-
@Override
public IotSceneRuleTriggerTypeEnum getSupportedTriggerType() {
return IotSceneRuleTriggerTypeEnum.DEVICE_EVENT_POST;
@@ -37,21 +32,21 @@ public class DeviceEventPostTriggerMatcher extends AbstractIotSceneRuleMatcher {
@Override
public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger) {
// 1. 基础参数校验
- if (!isBasicTriggerValid(trigger)) {
- logTriggerMatchFailure(message, trigger, "触发器基础参数无效");
+ if (!IotSceneRuleMatcherHelper.isBasicTriggerValid(trigger)) {
+ IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "触发器基础参数无效");
return false;
}
// 2. 检查消息方法是否匹配
if (!DEVICE_EVENT_POST_METHOD.equals(message.getMethod())) {
- logTriggerMatchFailure(message, trigger, "消息方法不匹配,期望: " + DEVICE_EVENT_POST_METHOD + ", 实际: " + message.getMethod());
+ IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "消息方法不匹配,期望: " + DEVICE_EVENT_POST_METHOD + ", 实际: " + message.getMethod());
return false;
}
// 3. 检查标识符是否匹配
String messageIdentifier = IotDeviceMessageUtils.getIdentifier(message);
- if (!isIdentifierMatched(trigger.getIdentifier(), messageIdentifier)) {
- logTriggerMatchFailure(message, trigger, "标识符不匹配,期望: " + trigger.getIdentifier() + ", 实际: " + messageIdentifier);
+ if (!IotSceneRuleMatcherHelper.isIdentifierMatched(trigger.getIdentifier(), messageIdentifier)) {
+ IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "标识符不匹配,期望: " + trigger.getIdentifier() + ", 实际: " + messageIdentifier);
return false;
}
@@ -60,18 +55,18 @@ public class DeviceEventPostTriggerMatcher extends AbstractIotSceneRuleMatcher {
if (StrUtil.isNotBlank(trigger.getOperator()) && StrUtil.isNotBlank(trigger.getValue())) {
Object eventData = message.getData();
if (eventData == null) {
- logTriggerMatchFailure(message, trigger, "消息中事件数据为空");
+ IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "消息中事件数据为空");
return false;
}
- boolean matched = evaluateCondition(eventData, trigger.getOperator(), trigger.getValue());
+ boolean matched = IotSceneRuleMatcherHelper.evaluateCondition(eventData, trigger.getOperator(), trigger.getValue());
if (!matched) {
- logTriggerMatchFailure(message, trigger, "事件数据条件不匹配");
+ IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "事件数据条件不匹配");
return false;
}
}
- logTriggerMatchSuccess(message, trigger);
+ IotSceneRuleMatcherHelper.logTriggerMatchSuccess(getMatcherName(), message, trigger);
return true;
}
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DevicePropertyPostTriggerMatcher.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DevicePropertyPostTriggerMatcher.java
index b01f7f409a..11638877dd 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DevicePropertyPostTriggerMatcher.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DevicePropertyPostTriggerMatcher.java
@@ -5,7 +5,7 @@ import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils;
import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO;
import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum;
-import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.AbstractIotSceneRuleMatcher;
+import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatcherHelper;
import org.springframework.stereotype.Component;
/**
@@ -16,7 +16,7 @@ import org.springframework.stereotype.Component;
* @author HUIHUI
*/
@Component
-public class DevicePropertyPostTriggerMatcher extends AbstractIotSceneRuleMatcher {
+public class DevicePropertyPostTriggerMatcher implements IotSceneRuleTriggerMatcher {
/**
* 设备属性上报消息方法
@@ -24,11 +24,6 @@ public class DevicePropertyPostTriggerMatcher extends AbstractIotSceneRuleMatche
// TODO @puhui999:是不是不用枚举哈?直接使用 IotDeviceMessageMethodEnum.PROPERTY_POST.getMethod()
private static final String DEVICE_PROPERTY_POST_METHOD = IotDeviceMessageMethodEnum.PROPERTY_POST.getMethod();
- @Override
- public MatcherTypeEnum getMatcherType() {
- return MatcherTypeEnum.TRIGGER;
- }
-
@Override
public IotSceneRuleTriggerTypeEnum getSupportedTriggerType() {
return IotSceneRuleTriggerTypeEnum.DEVICE_PROPERTY_POST;
@@ -37,43 +32,43 @@ public class DevicePropertyPostTriggerMatcher extends AbstractIotSceneRuleMatche
@Override
public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger) {
// 1. 基础参数校验
- if (!isBasicTriggerValid(trigger)) {
- logTriggerMatchFailure(message, trigger, "触发器基础参数无效");
+ if (!IotSceneRuleMatcherHelper.isBasicTriggerValid(trigger)) {
+ IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "触发器基础参数无效");
return false;
}
// 2. 检查消息方法是否匹配
if (!DEVICE_PROPERTY_POST_METHOD.equals(message.getMethod())) {
- logTriggerMatchFailure(message, trigger, "消息方法不匹配,期望: " + DEVICE_PROPERTY_POST_METHOD + ", 实际: " + message.getMethod());
+ IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "消息方法不匹配,期望: " + DEVICE_PROPERTY_POST_METHOD + ", 实际: " + message.getMethod());
return false;
}
// 3. 检查标识符是否匹配
String messageIdentifier = IotDeviceMessageUtils.getIdentifier(message);
- if (!isIdentifierMatched(trigger.getIdentifier(), messageIdentifier)) {
- logTriggerMatchFailure(message, trigger, "标识符不匹配,期望: " + trigger.getIdentifier() + ", 实际: " + messageIdentifier);
+ if (!IotSceneRuleMatcherHelper.isIdentifierMatched(trigger.getIdentifier(), messageIdentifier)) {
+ IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "标识符不匹配,期望: " + trigger.getIdentifier() + ", 实际: " + messageIdentifier);
return false;
}
// 4. 检查操作符和值是否有效
- if (!isTriggerOperatorAndValueValid(trigger)) {
- logTriggerMatchFailure(message, trigger, "操作符或值无效");
+ if (!IotSceneRuleMatcherHelper.isTriggerOperatorAndValueValid(trigger)) {
+ IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "操作符或值无效");
return false;
}
// 5. 获取属性值
Object propertyValue = message.getData();
if (propertyValue == null) {
- logTriggerMatchFailure(message, trigger, "消息中属性值为空");
+ IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "消息中属性值为空");
return false;
}
// 6. 使用条件评估器进行匹配
- boolean matched = evaluateCondition(propertyValue, trigger.getOperator(), trigger.getValue());
+ boolean matched = IotSceneRuleMatcherHelper.evaluateCondition(propertyValue, trigger.getOperator(), trigger.getValue());
if (matched) {
- logTriggerMatchSuccess(message, trigger);
+ IotSceneRuleMatcherHelper.logTriggerMatchSuccess(getMatcherName(), message, trigger);
} else {
- logTriggerMatchFailure(message, trigger, "属性值条件不匹配");
+ IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "属性值条件不匹配");
}
return matched;
}
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DeviceServiceInvokeTriggerMatcher.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DeviceServiceInvokeTriggerMatcher.java
index 074d4afa70..c349fd211e 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DeviceServiceInvokeTriggerMatcher.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DeviceServiceInvokeTriggerMatcher.java
@@ -5,7 +5,7 @@ import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils;
import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO;
import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum;
-import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.AbstractIotSceneRuleMatcher;
+import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatcherHelper;
import org.springframework.stereotype.Component;
/**
@@ -16,18 +16,13 @@ import org.springframework.stereotype.Component;
* @author HUIHUI
*/
@Component
-public class DeviceServiceInvokeTriggerMatcher extends AbstractIotSceneRuleMatcher {
+public class DeviceServiceInvokeTriggerMatcher implements IotSceneRuleTriggerMatcher {
/**
* 设备服务调用消息方法
*/
private static final String DEVICE_SERVICE_INVOKE_METHOD = IotDeviceMessageMethodEnum.SERVICE_INVOKE.getMethod();
- @Override
- public MatcherTypeEnum getMatcherType() {
- return MatcherTypeEnum.TRIGGER;
- }
-
@Override
public IotSceneRuleTriggerTypeEnum getSupportedTriggerType() {
return IotSceneRuleTriggerTypeEnum.DEVICE_SERVICE_INVOKE;
@@ -36,28 +31,28 @@ public class DeviceServiceInvokeTriggerMatcher extends AbstractIotSceneRuleMatch
@Override
public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger) {
// 1. 基础参数校验
- if (!isBasicTriggerValid(trigger)) {
- logTriggerMatchFailure(message, trigger, "触发器基础参数无效");
+ if (!IotSceneRuleMatcherHelper.isBasicTriggerValid(trigger)) {
+ IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "触发器基础参数无效");
return false;
}
// 2. 检查消息方法是否匹配
if (!DEVICE_SERVICE_INVOKE_METHOD.equals(message.getMethod())) {
- logTriggerMatchFailure(message, trigger, "消息方法不匹配,期望: " + DEVICE_SERVICE_INVOKE_METHOD + ", 实际: " + message.getMethod());
+ IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "消息方法不匹配,期望: " + DEVICE_SERVICE_INVOKE_METHOD + ", 实际: " + message.getMethod());
return false;
}
// 3. 检查标识符是否匹配
String messageIdentifier = IotDeviceMessageUtils.getIdentifier(message);
- if (!isIdentifierMatched(trigger.getIdentifier(), messageIdentifier)) {
- logTriggerMatchFailure(message, trigger, "标识符不匹配,期望: " + trigger.getIdentifier() + ", 实际: " + messageIdentifier);
+ if (!IotSceneRuleMatcherHelper.isIdentifierMatched(trigger.getIdentifier(), messageIdentifier)) {
+ IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "标识符不匹配,期望: " + trigger.getIdentifier() + ", 实际: " + messageIdentifier);
return false;
}
// 4. 对于服务调用触发器,通常只需要匹配服务标识符即可
// 不需要检查操作符和值,因为服务调用本身就是触发条件
- logTriggerMatchSuccess(message, trigger);
+ IotSceneRuleMatcherHelper.logTriggerMatchSuccess(getMatcherName(), message, trigger);
return true;
}
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DeviceStateUpdateTriggerMatcher.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DeviceStateUpdateTriggerMatcher.java
index 68d9ca4507..a435002252 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DeviceStateUpdateTriggerMatcher.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DeviceStateUpdateTriggerMatcher.java
@@ -4,7 +4,7 @@ import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageMethodEnum;
import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO;
import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum;
-import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.AbstractIotSceneRuleMatcher;
+import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatcherHelper;
import org.springframework.stereotype.Component;
/**
@@ -15,7 +15,7 @@ import org.springframework.stereotype.Component;
* @author HUIHUI
*/
@Component
-public class DeviceStateUpdateTriggerMatcher extends AbstractIotSceneRuleMatcher {
+public class DeviceStateUpdateTriggerMatcher implements IotSceneRuleTriggerMatcher {
// TODO @puhui999:是不是不用枚举哈;
/**
@@ -23,11 +23,6 @@ public class DeviceStateUpdateTriggerMatcher extends AbstractIotSceneRuleMatcher
*/
private static final String DEVICE_STATE_UPDATE_METHOD = IotDeviceMessageMethodEnum.STATE_UPDATE.getMethod();
- @Override
- public MatcherTypeEnum getMatcherType() {
- return MatcherTypeEnum.TRIGGER;
- }
-
@Override
public IotSceneRuleTriggerTypeEnum getSupportedTriggerType() {
return IotSceneRuleTriggerTypeEnum.DEVICE_STATE_UPDATE;
@@ -36,36 +31,36 @@ public class DeviceStateUpdateTriggerMatcher extends AbstractIotSceneRuleMatcher
@Override
public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger) {
// 1. 基础参数校验
- if (!isBasicTriggerValid(trigger)) {
- logTriggerMatchFailure(message, trigger, "触发器基础参数无效");
+ if (!IotSceneRuleMatcherHelper.isBasicTriggerValid(trigger)) {
+ IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "触发器基础参数无效");
return false;
}
// 2. 检查消息方法是否匹配
if (!DEVICE_STATE_UPDATE_METHOD.equals(message.getMethod())) {
- logTriggerMatchFailure(message, trigger, "消息方法不匹配,期望: " + DEVICE_STATE_UPDATE_METHOD + ", 实际: " + message.getMethod());
+ IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "消息方法不匹配,期望: " + DEVICE_STATE_UPDATE_METHOD + ", 实际: " + message.getMethod());
return false;
}
// 3. 检查操作符和值是否有效
- if (!isTriggerOperatorAndValueValid(trigger)) {
- logTriggerMatchFailure(message, trigger, "操作符或值无效");
+ if (!IotSceneRuleMatcherHelper.isTriggerOperatorAndValueValid(trigger)) {
+ IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "操作符或值无效");
return false;
}
// 4. 获取设备状态值
Object stateValue = message.getData();
if (stateValue == null) {
- logTriggerMatchFailure(message, trigger, "消息中设备状态值为空");
+ IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "消息中设备状态值为空");
return false;
}
// 5. 使用条件评估器进行匹配
- boolean matched = evaluateCondition(stateValue, trigger.getOperator(), trigger.getValue());
+ boolean matched = IotSceneRuleMatcherHelper.evaluateCondition(stateValue, trigger.getOperator(), trigger.getValue());
if (matched) {
- logTriggerMatchSuccess(message, trigger);
+ IotSceneRuleMatcherHelper.logTriggerMatchSuccess(getMatcherName(), message, trigger);
} else {
- logTriggerMatchFailure(message, trigger, "状态值条件不匹配");
+ IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "状态值条件不匹配");
}
return matched;
}
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/IotSceneRuleTriggerMatcher.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/IotSceneRuleTriggerMatcher.java
new file mode 100644
index 0000000000..322421738e
--- /dev/null
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/IotSceneRuleTriggerMatcher.java
@@ -0,0 +1,38 @@
+package cn.iocoder.yudao.module.iot.service.rule.scene.matcher.trigger;
+
+import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
+import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO;
+import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum;
+import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatcher;
+
+/**
+ * IoT 场景规则触发器匹配器接口
+ *
+ * 专门处理主触发条件的匹配逻辑,如设备消息类型、定时器等
+ *
+ * 触发器匹配器负责判断设备消息是否满足场景规则的主触发条件,
+ * 是场景规则执行的第一道门槛
+ *
+ * @author HUIHUI
+ */
+public interface IotSceneRuleTriggerMatcher extends IotSceneRuleMatcher {
+
+ /**
+ * 获取支持的触发器类型
+ *
+ * @return 触发器类型枚举
+ */
+ IotSceneRuleTriggerTypeEnum getSupportedTriggerType();
+
+ /**
+ * 检查触发器是否匹配消息
+ *
+ * 判断设备消息是否满足指定的触发器条件
+ *
+ * @param message 设备消息
+ * @param trigger 触发器配置
+ * @return 是否匹配
+ */
+ boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger);
+
+}
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/TimerTriggerMatcher.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/TimerTriggerMatcher.java
index 1ae0cee66c..6dfd3fc9e9 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/TimerTriggerMatcher.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/TimerTriggerMatcher.java
@@ -4,7 +4,7 @@ import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO;
import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum;
-import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.AbstractIotSceneRuleMatcher;
+import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatcherHelper;
import org.springframework.stereotype.Component;
/**
@@ -16,12 +16,7 @@ import org.springframework.stereotype.Component;
* @author HUIHUI
*/
@Component
-public class TimerTriggerMatcher extends AbstractIotSceneRuleMatcher {
-
- @Override
- public MatcherTypeEnum getMatcherType() {
- return MatcherTypeEnum.TRIGGER;
- }
+public class TimerTriggerMatcher implements IotSceneRuleTriggerMatcher {
@Override
public IotSceneRuleTriggerTypeEnum getSupportedTriggerType() {
@@ -31,14 +26,14 @@ public class TimerTriggerMatcher extends AbstractIotSceneRuleMatcher {
@Override
public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger) {
// 1. 基础参数校验
- if (!isBasicTriggerValid(trigger)) {
- logTriggerMatchFailure(message, trigger, "触发器基础参数无效");
+ if (!IotSceneRuleMatcherHelper.isBasicTriggerValid(trigger)) {
+ IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "触发器基础参数无效");
return false;
}
// 2. 检查 CRON 表达式是否存在
if (StrUtil.isBlank(trigger.getCronExpression())) {
- logTriggerMatchFailure(message, trigger, "定时触发器缺少 CRON 表达式");
+ IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "定时触发器缺少 CRON 表达式");
return false;
}
@@ -47,11 +42,11 @@ public class TimerTriggerMatcher extends AbstractIotSceneRuleMatcher {
// 4. 可以添加 CRON 表达式格式验证
if (!isValidCronExpression(trigger.getCronExpression())) {
- logTriggerMatchFailure(message, trigger, "CRON 表达式格式无效: " + trigger.getCronExpression());
+ IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "CRON 表达式格式无效: " + trigger.getCronExpression());
return false;
}
- logTriggerMatchSuccess(message, trigger);
+ IotSceneRuleMatcherHelper.logTriggerMatchSuccess(getMatcherName(), message, trigger);
return true;
}