review:【iot 物联网】场景联动相关实现
This commit is contained in:
@@ -60,7 +60,7 @@ public enum IotSceneRuleTriggerTypeEnum implements ArrayValuable<Integer> {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
|
||||
// TODO @puhui999:可以参考下别的枚举哈,方法名,和实现都可以更简洁;of(String type) { firstMatch
|
||||
/**
|
||||
* 根据类型值查找触发器类型枚举
|
||||
*
|
||||
|
||||
@@ -45,7 +45,6 @@ public class IotRedisRuleAction extends
|
||||
// 2. 根据数据结构类型执行不同的操作
|
||||
String messageJson = JsonUtils.toJsonString(message);
|
||||
IotRedisDataStructureEnum dataStructure = getDataStructureByType(config.getDataStructure());
|
||||
|
||||
switch (dataStructure) {
|
||||
case STREAM:
|
||||
executeStream(redisTemplate, config, messageJson);
|
||||
|
||||
@@ -58,12 +58,15 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService {
|
||||
@Resource
|
||||
private IotSceneRuleMapper sceneRuleMapper;
|
||||
|
||||
// TODO @puhui999:定时任务,基于它调度;
|
||||
@Resource(name = "iotSchedulerManager")
|
||||
private IotSchedulerManager schedulerManager;
|
||||
@Resource
|
||||
private IotProductService productService;
|
||||
@Resource
|
||||
private IotDeviceService deviceService;
|
||||
|
||||
// TODO @puhui999:sceneRuleMatcherManager 变量名
|
||||
@Resource
|
||||
private IotSceneRuleMatcherManager matcherManager;
|
||||
@Resource
|
||||
@@ -135,7 +138,7 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService {
|
||||
return sceneRuleMapper.selectListByStatus(status);
|
||||
}
|
||||
|
||||
// TODO 芋艿,缓存待实现
|
||||
// TODO 芋艿,缓存待实现 @puhui999
|
||||
@Override
|
||||
@TenantIgnore // 忽略租户隔离:因为 IotSceneRuleMessageHandler 调用时,一般未传递租户,所以需要忽略
|
||||
public List<IotSceneRuleDO> getSceneRuleListByProductIdAndDeviceIdFromCache(Long productId, Long deviceId) {
|
||||
@@ -177,7 +180,7 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService {
|
||||
|
||||
@Override
|
||||
public void executeSceneRuleByDevice(IotDeviceMessage message) {
|
||||
// TODO @芋艿:这里的 tenantId,通过设备获取;
|
||||
// TODO @芋艿:这里的 tenantId,通过设备获取;@puhui999:
|
||||
TenantUtils.execute(message.getTenantId(), () -> {
|
||||
// 1. 获得设备匹配的规则场景
|
||||
List<IotSceneRuleDO> sceneRules = getMatchedSceneRuleListByMessage(message);
|
||||
@@ -223,7 +226,7 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService {
|
||||
*/
|
||||
private List<IotSceneRuleDO> getMatchedSceneRuleListByMessage(IotDeviceMessage message) {
|
||||
// 1. 匹配设备
|
||||
// TODO @芋艿:可能需要 getSelf(); 缓存
|
||||
// TODO @芋艿:可能需要 getSelf(); 缓存 @puhui999;
|
||||
// 1.1 通过 deviceId 获取设备信息
|
||||
IotDeviceDO device = deviceService.getDeviceFromCache(message.getDeviceId());
|
||||
if (device == null) {
|
||||
@@ -342,7 +345,6 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService {
|
||||
private boolean isTriggerConditionMatched(IotDeviceMessage message, IotSceneRuleDO.TriggerCondition condition,
|
||||
IotSceneRuleDO sceneRule, IotSceneRuleDO.Trigger trigger) {
|
||||
try {
|
||||
// 使用重构后的条件匹配管理器进行匹配
|
||||
return matcherManager.isConditionMatched(message, condition);
|
||||
} catch (Exception e) {
|
||||
log.error("[isTriggerConditionMatched][规则场景编号({}) 的触发器({}) 条件匹配异常]",
|
||||
@@ -351,8 +353,7 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO @芋艿:【可优化】可以考虑增加下单测,边界太多了。
|
||||
|
||||
// TODO @puhui999:下面还需要么?
|
||||
/**
|
||||
* 判断触发器的条件参数是否匹配
|
||||
*
|
||||
|
||||
@@ -24,6 +24,8 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.
|
||||
@Slf4j
|
||||
public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher {
|
||||
|
||||
// TODO @puhui999:这个是不是也是【通用】条件哈?
|
||||
|
||||
/**
|
||||
* 评估条件是否匹配
|
||||
*
|
||||
@@ -32,6 +34,7 @@ public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher
|
||||
* @param paramValue 参数值(来自条件配置)
|
||||
* @return 是否匹配
|
||||
*/
|
||||
@SuppressWarnings("DataFlowIssue")
|
||||
protected boolean evaluateCondition(Object sourceValue, String operator, String paramValue) {
|
||||
try {
|
||||
// 1. 校验操作符是否合法
|
||||
@@ -48,6 +51,7 @@ public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher
|
||||
// 处理参数值
|
||||
if (StrUtil.isNotBlank(paramValue)) {
|
||||
// 处理多值情况(如 IN、BETWEEN 操作符)
|
||||
// TODO @puhui999:使用这个,会不会有问题?例如说:string 恰好有 , 分隔?
|
||||
if (paramValue.contains(",")) {
|
||||
List<String> paramValues = StrUtil.split(paramValue, ',');
|
||||
springExpressionVariables.put(IotSceneRuleConditionOperatorEnum.SPRING_EXPRESSION_VALUE_LIST,
|
||||
@@ -68,7 +72,7 @@ public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher
|
||||
}
|
||||
}
|
||||
|
||||
// ========== 触发器相关工具方法 ==========
|
||||
// ========== 【触发器】相关工具方法 ==========
|
||||
|
||||
/**
|
||||
* 检查基础触发器参数是否有效
|
||||
@@ -111,7 +115,7 @@ public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher
|
||||
log.debug("[{}][消息({}) 匹配触发器({}) 失败: {}]", getMatcherName(), message.getRequestId(), trigger.getType(), reason);
|
||||
}
|
||||
|
||||
// ========== 条件相关工具方法 ==========
|
||||
// ========== 【条件】相关工具方法 ==========
|
||||
|
||||
/**
|
||||
* 检查基础条件参数是否有效
|
||||
@@ -154,7 +158,7 @@ public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher
|
||||
log.debug("[{}][消息({}) 匹配条件({}) 失败: {}]", getMatcherName(), message.getRequestId(), condition.getType(), reason);
|
||||
}
|
||||
|
||||
// ========== 通用工具方法 ==========
|
||||
// ========== 【通用】工具方法 ==========
|
||||
|
||||
/**
|
||||
* 检查标识符是否匹配
|
||||
|
||||
@@ -56,15 +56,11 @@ public class CurrentTimeConditionMatcher extends AbstractIotSceneRuleMatcher {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 3. 获取当前时间
|
||||
// 3. 根据操作符类型进行不同的时间匹配
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
|
||||
// 4. 根据操作符类型进行不同的时间匹配
|
||||
String operator = condition.getOperator();
|
||||
String param = condition.getParam();
|
||||
|
||||
boolean matched = false;
|
||||
|
||||
boolean matched;
|
||||
try {
|
||||
if (operator.startsWith("date_time_")) {
|
||||
// 日期时间匹配(时间戳)
|
||||
@@ -82,13 +78,11 @@ public class CurrentTimeConditionMatcher extends AbstractIotSceneRuleMatcher {
|
||||
} else {
|
||||
logConditionMatchFailure(message, condition, "时间条件不匹配");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("[CurrentTimeConditionMatcher][时间条件匹配异常] operator: {}, param: {}", operator, param, e);
|
||||
logConditionMatchFailure(message, condition, "时间条件匹配异常: " + e.getMessage());
|
||||
matched = false;
|
||||
}
|
||||
|
||||
return matched;
|
||||
}
|
||||
|
||||
@@ -107,21 +101,20 @@ public class CurrentTimeConditionMatcher extends AbstractIotSceneRuleMatcher {
|
||||
try {
|
||||
String actualOperator = operator.substring("time_".length());
|
||||
|
||||
// TODO @puhui999:if return 简化;
|
||||
if ("between".equals(actualOperator)) {
|
||||
// 时间区间匹配
|
||||
String[] timeRange = param.split(",");
|
||||
if (timeRange.length != 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LocalTime startTime = parseTime(timeRange[0].trim());
|
||||
LocalTime endTime = parseTime(timeRange[1].trim());
|
||||
|
||||
return !currentTime.isBefore(startTime) && !currentTime.isAfter(endTime);
|
||||
} else {
|
||||
// 单个时间比较
|
||||
LocalTime targetTime = parseTime(param);
|
||||
|
||||
// TODO @puhui999:枚举类;
|
||||
switch (actualOperator) {
|
||||
case ">":
|
||||
return currentTime.isAfter(targetTime);
|
||||
@@ -138,6 +131,7 @@ public class CurrentTimeConditionMatcher extends AbstractIotSceneRuleMatcher {
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// TODO @puhui999:1)日志格式 [][];2)方法名不对哈;
|
||||
log.error("[CurrentTimeConditionMatcher][时间解析异常] param: {}", param, e);
|
||||
return false;
|
||||
}
|
||||
@@ -147,10 +141,10 @@ public class CurrentTimeConditionMatcher extends AbstractIotSceneRuleMatcher {
|
||||
* 解析时间字符串
|
||||
*/
|
||||
private LocalTime parseTime(String timeStr) {
|
||||
// TODO @puhui999:可以用 hutool Assert 类简化
|
||||
if (StrUtil.isBlank(timeStr)) {
|
||||
throw new IllegalArgumentException("时间字符串不能为空");
|
||||
}
|
||||
|
||||
// 尝试不同的时间格式
|
||||
try {
|
||||
if (timeStr.length() == 5) { // HH:mm
|
||||
|
||||
@@ -26,6 +26,7 @@ public class DevicePropertyConditionMatcher extends AbstractIotSceneRuleMatcher
|
||||
return IotSceneRuleConditionTypeEnum.DEVICE_PROPERTY;
|
||||
}
|
||||
|
||||
// TODO @puhui999:参数校验的,要不要 1.1 1.2 1.3 1.4 ?这样最终看到 2. 3. 就是核心逻辑列;
|
||||
@Override
|
||||
public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.TriggerCondition condition) {
|
||||
// 1. 基础参数校验
|
||||
@@ -56,13 +57,11 @@ public class DevicePropertyConditionMatcher extends AbstractIotSceneRuleMatcher
|
||||
|
||||
// 5. 使用条件评估器进行匹配
|
||||
boolean matched = evaluateCondition(propertyValue, condition.getOperator(), condition.getParam());
|
||||
|
||||
if (matched) {
|
||||
logConditionMatchSuccess(message, condition);
|
||||
} else {
|
||||
logConditionMatchFailure(message, condition, "设备属性条件不匹配");
|
||||
}
|
||||
|
||||
return matched;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ public class DevicePropertyPostTriggerMatcher extends AbstractIotSceneRuleMatche
|
||||
/**
|
||||
* 设备属性上报消息方法
|
||||
*/
|
||||
// TODO @puhui999:是不是不用枚举哈?直接使用 IotDeviceMessageMethodEnum.PROPERTY_POST.getMethod()
|
||||
private static final String DEVICE_PROPERTY_POST_METHOD = IotDeviceMessageMethodEnum.PROPERTY_POST.getMethod();
|
||||
|
||||
@Override
|
||||
@@ -68,13 +69,11 @@ public class DevicePropertyPostTriggerMatcher extends AbstractIotSceneRuleMatche
|
||||
|
||||
// 6. 使用条件评估器进行匹配
|
||||
boolean matched = evaluateCondition(propertyValue, trigger.getOperator(), trigger.getValue());
|
||||
|
||||
if (matched) {
|
||||
logTriggerMatchSuccess(message, trigger);
|
||||
} else {
|
||||
logTriggerMatchFailure(message, trigger, "属性值条件不匹配");
|
||||
}
|
||||
|
||||
return matched;
|
||||
}
|
||||
|
||||
|
||||
@@ -49,13 +49,11 @@ public class DeviceStateConditionMatcher extends AbstractIotSceneRuleMatcher {
|
||||
|
||||
// 4. 使用条件评估器进行匹配
|
||||
boolean matched = evaluateCondition(stateValue, condition.getOperator(), condition.getParam());
|
||||
|
||||
if (matched) {
|
||||
logConditionMatchSuccess(message, condition);
|
||||
} else {
|
||||
logConditionMatchFailure(message, condition, "设备状态条件不匹配");
|
||||
}
|
||||
|
||||
return matched;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ import org.springframework.stereotype.Component;
|
||||
@Component
|
||||
public class DeviceStateUpdateTriggerMatcher extends AbstractIotSceneRuleMatcher {
|
||||
|
||||
// TODO @puhui999:是不是不用枚举哈;
|
||||
/**
|
||||
* 设备状态更新消息方法
|
||||
*/
|
||||
@@ -60,13 +61,11 @@ public class DeviceStateUpdateTriggerMatcher extends AbstractIotSceneRuleMatcher
|
||||
|
||||
// 5. 使用条件评估器进行匹配
|
||||
boolean matched = evaluateCondition(stateValue, trigger.getOperator(), trigger.getValue());
|
||||
|
||||
if (matched) {
|
||||
logTriggerMatchSuccess(message, trigger);
|
||||
} else {
|
||||
logTriggerMatchFailure(message, trigger, "状态值条件不匹配");
|
||||
}
|
||||
|
||||
return matched;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,18 +18,23 @@ import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum;
|
||||
*/
|
||||
public interface IotSceneRuleMatcher {
|
||||
|
||||
// TODO @puhui999:MatcherTypeEnum;
|
||||
// TODO @puhui999:可以考虑根据类型,新建 trigger、condition 包,然后把对应的实现类放进去哈;
|
||||
/**
|
||||
* 匹配器类型枚举
|
||||
*/
|
||||
enum MatcherType {
|
||||
|
||||
/**
|
||||
* 触发器匹配器 - 用于匹配主触发条件
|
||||
*/
|
||||
TRIGGER,
|
||||
|
||||
/**
|
||||
* 条件匹配器 - 用于匹配子条件
|
||||
*/
|
||||
CONDITION
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,6 +44,10 @@ public interface IotSceneRuleMatcher {
|
||||
*/
|
||||
MatcherType getMatcherType();
|
||||
|
||||
// TODO @puhui999:【重要】有个思路,IotSceneRuleMatcher 拆分成 2 种 mather 接口;然后 AbstractIotSceneRuleMatcher 是个 Helper 工具类;
|
||||
|
||||
// TODO @puhui999:是不是和 AbstractSceneRuleMatcher 一样,分下块;
|
||||
|
||||
/**
|
||||
* 获取支持的触发器类型(仅触发器匹配器需要实现)
|
||||
*
|
||||
@@ -90,6 +99,7 @@ public interface IotSceneRuleMatcher {
|
||||
return 100;
|
||||
}
|
||||
|
||||
// TODO @puhui999:如果目前没自定义,体感可以删除哈;
|
||||
/**
|
||||
* 获取匹配器名称,用于日志和调试
|
||||
*
|
||||
|
||||
@@ -30,14 +30,14 @@ public class IotSceneRuleMatcherManager {
|
||||
* Key: 触发器类型枚举
|
||||
* Value: 对应的匹配器实例
|
||||
*/
|
||||
private final Map<IotSceneRuleTriggerTypeEnum, IotSceneRuleMatcher> triggerMatcherMap;
|
||||
private final Map<IotSceneRuleTriggerTypeEnum, IotSceneRuleMatcher> triggerMatchers;
|
||||
|
||||
/**
|
||||
* 条件匹配器映射表
|
||||
* Key: 条件类型枚举
|
||||
* Value: 对应的匹配器实例
|
||||
*/
|
||||
private final Map<IotSceneRuleConditionTypeEnum, IotSceneRuleMatcher> conditionMatcherMap;
|
||||
private final Map<IotSceneRuleConditionTypeEnum, IotSceneRuleMatcher> conditionMatchers;
|
||||
|
||||
/**
|
||||
* 所有匹配器列表(按优先级排序)
|
||||
@@ -47,8 +47,8 @@ public class IotSceneRuleMatcherManager {
|
||||
public IotSceneRuleMatcherManager(List<IotSceneRuleMatcher> matchers) {
|
||||
if (CollUtil.isEmpty(matchers)) {
|
||||
log.warn("[IotSceneRuleMatcherManager][没有找到任何匹配器]");
|
||||
this.triggerMatcherMap = new HashMap<>();
|
||||
this.conditionMatcherMap = new HashMap<>();
|
||||
this.triggerMatchers = new HashMap<>();
|
||||
this.conditionMatchers = new HashMap<>();
|
||||
this.allMatchers = new ArrayList<>();
|
||||
return;
|
||||
}
|
||||
@@ -63,13 +63,13 @@ public class IotSceneRuleMatcherManager {
|
||||
List<IotSceneRuleMatcher> triggerMatchers = this.allMatchers.stream()
|
||||
.filter(matcher -> matcher.getMatcherType() == IotSceneRuleMatcher.MatcherType.TRIGGER)
|
||||
.toList();
|
||||
|
||||
List<IotSceneRuleMatcher> conditionMatchers = this.allMatchers.stream()
|
||||
.filter(matcher -> matcher.getMatcherType() == IotSceneRuleMatcher.MatcherType.CONDITION)
|
||||
.toList();
|
||||
|
||||
// 构建触发器匹配器映射表
|
||||
this.triggerMatcherMap = triggerMatchers.stream()
|
||||
// TODO @puhui999:convertMap()
|
||||
this.triggerMatchers = triggerMatchers.stream()
|
||||
.collect(Collectors.toMap(
|
||||
IotSceneRuleMatcher::getSupportedTriggerType,
|
||||
Function.identity(),
|
||||
@@ -81,9 +81,8 @@ public class IotSceneRuleMatcherManager {
|
||||
},
|
||||
LinkedHashMap::new
|
||||
));
|
||||
|
||||
// 构建条件匹配器映射表
|
||||
this.conditionMatcherMap = conditionMatchers.stream()
|
||||
this.conditionMatchers = conditionMatchers.stream()
|
||||
.collect(Collectors.toMap(
|
||||
IotSceneRuleMatcher::getSupportedConditionType,
|
||||
Function.identity(),
|
||||
@@ -96,16 +95,13 @@ public class IotSceneRuleMatcherManager {
|
||||
LinkedHashMap::new
|
||||
));
|
||||
|
||||
// 日志输出初始化信息
|
||||
log.info("[IotSceneRuleMatcherManager][初始化完成,共加载 {} 个匹配器,其中触发器匹配器 {} 个,条件匹配器 {} 个]",
|
||||
this.allMatchers.size(), this.triggerMatcherMap.size(), this.conditionMatcherMap.size());
|
||||
|
||||
// 记录触发器匹配器详情
|
||||
this.triggerMatcherMap.forEach((type, matcher) ->
|
||||
this.allMatchers.size(), this.triggerMatchers.size(), this.conditionMatchers.size());
|
||||
this.triggerMatchers.forEach((type, matcher) ->
|
||||
log.info("[IotSceneRuleMatcherManager][触发器匹配器] 类型: {}, 匹配器: {}, 优先级: {}",
|
||||
type, matcher.getMatcherName(), matcher.getPriority()));
|
||||
|
||||
// 记录条件匹配器详情
|
||||
this.conditionMatcherMap.forEach((type, matcher) ->
|
||||
this.conditionMatchers.forEach((type, matcher) ->
|
||||
log.info("[IotSceneRuleMatcherManager][条件匹配器] 类型: {}, 匹配器: {}, 优先级: {}",
|
||||
type, matcher.getMatcherName(), matcher.getPriority()));
|
||||
}
|
||||
@@ -118,19 +114,17 @@ public class IotSceneRuleMatcherManager {
|
||||
* @return 是否匹配
|
||||
*/
|
||||
public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger) {
|
||||
// TODO @puhui999:日志优化下;claude 打出来的日志风格,和项目有点不一样哈;
|
||||
if (message == null || trigger == null || trigger.getType() == null) {
|
||||
log.debug("[isMatched][参数无效] message: {}, trigger: {}", message, trigger);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 根据触发器类型查找对应的匹配器
|
||||
IotSceneRuleTriggerTypeEnum triggerType = findTriggerTypeEnum(trigger.getType());
|
||||
if (triggerType == null) {
|
||||
log.warn("[isMatched][未知的触发器类型: {}]", trigger.getType());
|
||||
return false;
|
||||
}
|
||||
|
||||
IotSceneRuleMatcher matcher = triggerMatcherMap.get(triggerType);
|
||||
IotSceneRuleMatcher matcher = triggerMatchers.get(triggerType);
|
||||
if (matcher == null) {
|
||||
log.warn("[isMatched][触发器类型({})没有对应的匹配器]", triggerType);
|
||||
return false;
|
||||
@@ -165,7 +159,7 @@ public class IotSceneRuleMatcherManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
IotSceneRuleMatcher matcher = conditionMatcherMap.get(conditionType);
|
||||
IotSceneRuleMatcher matcher = conditionMatchers.get(conditionType);
|
||||
if (matcher == null) {
|
||||
log.warn("[isConditionMatched][条件类型({})没有对应的匹配器]", conditionType);
|
||||
return false;
|
||||
@@ -199,7 +193,7 @@ public class IotSceneRuleMatcherManager {
|
||||
* @return 支持的触发器类型列表
|
||||
*/
|
||||
public Set<IotSceneRuleTriggerTypeEnum> getSupportedTriggerTypes() {
|
||||
return new HashSet<>(triggerMatcherMap.keySet());
|
||||
return new HashSet<>(triggerMatchers.keySet());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -208,9 +202,11 @@ public class IotSceneRuleMatcherManager {
|
||||
* @return 支持的条件类型列表
|
||||
*/
|
||||
public Set<IotSceneRuleConditionTypeEnum> getSupportedConditionTypes() {
|
||||
return new HashSet<>(conditionMatcherMap.keySet());
|
||||
return new HashSet<>(conditionMatchers.keySet());
|
||||
}
|
||||
|
||||
// TODO @puhui999:用不到的方法,可以去掉先哈;
|
||||
|
||||
/**
|
||||
* 获取指定触发器类型的匹配器
|
||||
*
|
||||
@@ -218,7 +214,7 @@ public class IotSceneRuleMatcherManager {
|
||||
* @return 匹配器实例,如果不存在则返回 null
|
||||
*/
|
||||
public IotSceneRuleMatcher getTriggerMatcher(IotSceneRuleTriggerTypeEnum triggerType) {
|
||||
return triggerMatcherMap.get(triggerType);
|
||||
return triggerMatchers.get(triggerType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -228,9 +224,10 @@ public class IotSceneRuleMatcherManager {
|
||||
* @return 匹配器实例,如果不存在则返回 null
|
||||
*/
|
||||
public IotSceneRuleMatcher getConditionMatcher(IotSceneRuleConditionTypeEnum conditionType) {
|
||||
return conditionMatcherMap.get(conditionType);
|
||||
return conditionMatchers.get(conditionType);
|
||||
}
|
||||
|
||||
// TODO @puhui999:是不是不用这个哈;直接 @Getter,单测直接处理;
|
||||
/**
|
||||
* 获取所有匹配器的统计信息
|
||||
*
|
||||
@@ -239,14 +236,14 @@ public class IotSceneRuleMatcherManager {
|
||||
public Map<String, Object> getMatcherStatistics() {
|
||||
Map<String, Object> statistics = new HashMap<>();
|
||||
statistics.put("totalMatchers", allMatchers.size());
|
||||
statistics.put("triggerMatchers", triggerMatcherMap.size());
|
||||
statistics.put("conditionMatchers", conditionMatcherMap.size());
|
||||
statistics.put("triggerMatchers", triggerMatchers.size());
|
||||
statistics.put("conditionMatchers", conditionMatchers.size());
|
||||
statistics.put("supportedTriggerTypes", getSupportedTriggerTypes());
|
||||
statistics.put("supportedConditionTypes", getSupportedConditionTypes());
|
||||
|
||||
// 触发器匹配器详情
|
||||
Map<String, Object> triggerMatcherDetails = new HashMap<>();
|
||||
triggerMatcherMap.forEach((type, matcher) -> {
|
||||
triggerMatchers.forEach((type, matcher) -> {
|
||||
Map<String, Object> detail = new HashMap<>();
|
||||
detail.put("matcherName", matcher.getMatcherName());
|
||||
detail.put("priority", matcher.getPriority());
|
||||
@@ -257,7 +254,7 @@ public class IotSceneRuleMatcherManager {
|
||||
|
||||
// 条件匹配器详情
|
||||
Map<String, Object> conditionMatcherDetails = new HashMap<>();
|
||||
conditionMatcherMap.forEach((type, matcher) -> {
|
||||
conditionMatchers.forEach((type, matcher) -> {
|
||||
Map<String, Object> detail = new HashMap<>();
|
||||
detail.put("matcherName", matcher.getMatcherName());
|
||||
detail.put("priority", matcher.getPriority());
|
||||
|
||||
@@ -61,6 +61,7 @@ public class TimerTriggerMatcher extends AbstractIotSceneRuleMatcher {
|
||||
* @return 是否有效
|
||||
*/
|
||||
private boolean isValidCronExpression(String cronExpression) {
|
||||
// TODO @puhui999:CronExpression.isValidExpression(cronExpression);
|
||||
try {
|
||||
// 简单的 CRON 表达式格式验证
|
||||
// 标准 CRON 表达式应该有 6 或 7 个字段(秒 分 时 日 月 周 [年])
|
||||
|
||||
@@ -20,6 +20,8 @@ import static org.junit.jupiter.api.Assertions.*;
|
||||
*/
|
||||
public class IotSceneRuleTriggerMatcherTest extends BaseMockitoUnitTest {
|
||||
|
||||
// TODO @puhui999:public 都加下哈;
|
||||
|
||||
private IotSceneRuleMatcherManager matcherManager;
|
||||
|
||||
@BeforeEach
|
||||
@@ -42,13 +44,13 @@ public class IotSceneRuleTriggerMatcherTest extends BaseMockitoUnitTest {
|
||||
// 1. 准备测试数据
|
||||
IotDeviceMessage message = IotDeviceMessage.builder()
|
||||
.requestId("test-001")
|
||||
.method("thing.state.update")
|
||||
.data(1) // 在线状态
|
||||
.method("thing.state.update") // TODO @puhui999:这里的枚举;
|
||||
.data(1) // 在线状态 TODO @puhui999:这里的枚举;
|
||||
.build();
|
||||
|
||||
IotSceneRuleDO.Trigger trigger = new IotSceneRuleDO.Trigger();
|
||||
trigger.setType(IotSceneRuleTriggerTypeEnum.DEVICE_STATE_UPDATE.getType());
|
||||
trigger.setOperator("=");
|
||||
trigger.setOperator("="); // TODO @puhui999:这里的枚举;下面也是类似;
|
||||
trigger.setValue("1");
|
||||
|
||||
// 2. 执行测试
|
||||
|
||||
Reference in New Issue
Block a user