Commit a4be3bb84d0a24169f085a643edbd24eedb35aa5
1 parent
06749a18
【代码新增】IoT:增加 IotRuleSceneMessageHandler 处理规则场景,尝试基于 Spring El 表达式实现初步计算(部分场景) trigger 条件匹配
Showing
7 changed files
with
372 additions
and
4 deletions
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/rule/IotRuleSceneTriggerConditionParameterOperatorEnum.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.enums.rule; | |
| 2 | + | |
| 3 | +import cn.hutool.core.util.ArrayUtil; | |
| 4 | +import cn.iocoder.yudao.framework.common.core.ArrayValuable; | |
| 5 | +import lombok.Getter; | |
| 6 | +import lombok.RequiredArgsConstructor; | |
| 7 | + | |
| 8 | +import java.util.Arrays; | |
| 9 | + | |
| 10 | +/** | |
| 11 | + * Iot 场景触发条件参数的操作符枚举 | |
| 12 | + * | |
| 13 | + * @author 芋道源码 | |
| 14 | + */ | |
| 15 | +@RequiredArgsConstructor | |
| 16 | +@Getter | |
| 17 | +public enum IotRuleSceneTriggerConditionParameterOperatorEnum implements ArrayValuable<String> { | |
| 18 | + | |
| 19 | + EQUALS("=", "%s == %s"), | |
| 20 | + NOT_EQUALS("!=", "%s != %s"), | |
| 21 | + | |
| 22 | + GREATER_THAN(">", "%s > %s"), | |
| 23 | + GREATER_THAN_OR_EQUALS(">=", "%s >= %s"), | |
| 24 | + | |
| 25 | + LESS_THAN("<", "%s < %s"), | |
| 26 | + LESS_THAN_OR_EQUALS("<=", "%s <= %s"), | |
| 27 | + | |
| 28 | + IN("in", "%s in { %s }"), | |
| 29 | + NOT_IN("not in", "%s not in { %s }"), | |
| 30 | + | |
| 31 | + BETWEEN("between", "(%s >= %s) && (%s <= %s)"), | |
| 32 | + NOT_BETWEEN("not between", "!(%s between %s and %s)"), | |
| 33 | + | |
| 34 | + LIKE("like", "%s like %s"), // 字符串匹配 | |
| 35 | + NOT_NULL("not null", ""); // 非空 | |
| 36 | + | |
| 37 | + private final String operator; | |
| 38 | + private final String springExpression; | |
| 39 | + | |
| 40 | + public static final String[] ARRAYS = Arrays.stream(values()).map(IotRuleSceneTriggerConditionParameterOperatorEnum::getOperator).toArray(String[]::new); | |
| 41 | + | |
| 42 | + public static IotRuleSceneTriggerConditionParameterOperatorEnum operatorOf(String operator) { | |
| 43 | + return ArrayUtil.firstMatch(item -> item.getOperator().equals(operator), values()); | |
| 44 | + } | |
| 45 | + | |
| 46 | + @Override | |
| 47 | + public String[] array() { | |
| 48 | + return ARRAYS; | |
| 49 | + } | |
| 50 | + | |
| 51 | +} | ... | ... |
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/rule/IotRuleSceneTriggerTypeEnum.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.enums.rule; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.core.ArrayValuable; | |
| 4 | +import lombok.Getter; | |
| 5 | +import lombok.RequiredArgsConstructor; | |
| 6 | + | |
| 7 | +import java.util.Arrays; | |
| 8 | + | |
| 9 | +/** | |
| 10 | + * Iot 场景流转的触发类型枚举 | |
| 11 | + * | |
| 12 | + * @author 芋道源码 | |
| 13 | + */ | |
| 14 | +@RequiredArgsConstructor | |
| 15 | +@Getter | |
| 16 | +public enum IotRuleSceneTriggerTypeEnum implements ArrayValuable<Integer> { | |
| 17 | + | |
| 18 | + DEVICE(1), // 设备触发 | |
| 19 | + TIMER(2); // 定时触发 | |
| 20 | + | |
| 21 | + private final Integer type; | |
| 22 | + | |
| 23 | + public static final Integer[] ARRAYS = Arrays.stream(values()).map(IotRuleSceneTriggerTypeEnum::getType).toArray(Integer[]::new); | |
| 24 | + | |
| 25 | + @Override | |
| 26 | + public Integer[] array() { | |
| 27 | + return ARRAYS; | |
| 28 | + } | |
| 29 | + | |
| 30 | +} | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/rule/IotRuleSceneDO.java
| ... | ... | @@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; |
| 6 | 6 | import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; |
| 7 | 7 | import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum; |
| 8 | 8 | import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageTypeEnum; |
| 9 | +import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneTriggerConditionParameterOperatorEnum; | |
| 9 | 10 | import com.baomidou.mybatisplus.annotation.KeySequence; |
| 10 | 11 | import com.baomidou.mybatisplus.annotation.TableField; |
| 11 | 12 | import com.baomidou.mybatisplus.annotation.TableId; |
| ... | ... | @@ -17,7 +18,7 @@ import java.util.List; |
| 17 | 18 | import java.util.Map; |
| 18 | 19 | |
| 19 | 20 | /** |
| 20 | - * IoT 场景联动 DO | |
| 21 | + * IoT 规则场景(场景联动) DO | |
| 21 | 22 | * |
| 22 | 23 | * @author 芋道源码 |
| 23 | 24 | */ |
| ... | ... | @@ -72,7 +73,7 @@ public class IotRuleSceneDO extends BaseDO { |
| 72 | 73 | /** |
| 73 | 74 | * 触发类型 |
| 74 | 75 | * |
| 75 | - * TODO @芋艿:device、job | |
| 76 | + * 枚举 {@link cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneTriggerTypeEnum} | |
| 76 | 77 | */ |
| 77 | 78 | private Integer type; |
| 78 | 79 | |
| ... | ... | @@ -147,12 +148,15 @@ public class IotRuleSceneDO extends BaseDO { |
| 147 | 148 | /** |
| 148 | 149 | * 操作符 |
| 149 | 150 | * |
| 150 | - * TODO 芋艿:枚举 | |
| 151 | + * 枚举 {@link IotRuleSceneTriggerConditionParameterOperatorEnum} | |
| 151 | 152 | */ |
| 152 | 153 | private String operator; |
| 153 | 154 | |
| 154 | 155 | /** |
| 155 | - * 值 | |
| 156 | + * 比较值 | |
| 157 | + * | |
| 158 | + * 如果有多个值,则使用 "," 分隔,类似 "1,2,3"。 | |
| 159 | + * 例如说,{@link IotRuleSceneTriggerConditionParameterOperatorEnum#IN}、{@link IotRuleSceneTriggerConditionParameterOperatorEnum#BETWEEN} | |
| 156 | 160 | */ |
| 157 | 161 | private String value; |
| 158 | 162 | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/rule/IotRuleSceneMapper.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.dal.mysql.rule; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | |
| 4 | +import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; | |
| 5 | +import org.apache.ibatis.annotations.Mapper; | |
| 6 | + | |
| 7 | +@Mapper | |
| 8 | +public interface IotRuleSceneMapper extends BaseMapperX<IotRuleSceneDO> { | |
| 9 | + | |
| 10 | +} | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/rule/IotRuleSceneMessageHandler.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.mq.consumer.rule; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | |
| 4 | +import cn.iocoder.yudao.module.iot.service.rule.IotRuleSceneService; | |
| 5 | +import jakarta.annotation.Resource; | |
| 6 | +import lombok.extern.slf4j.Slf4j; | |
| 7 | +import org.springframework.context.event.EventListener; | |
| 8 | +import org.springframework.scheduling.annotation.Async; | |
| 9 | +import org.springframework.stereotype.Component; | |
| 10 | + | |
| 11 | +/** | |
| 12 | + * 针对 {@link IotDeviceMessage} 的消费者,处理规则场景 | |
| 13 | + * | |
| 14 | + * @author 芋道源码 | |
| 15 | + */ | |
| 16 | +@Component | |
| 17 | +@Slf4j | |
| 18 | +public class IotRuleSceneMessageHandler { | |
| 19 | + | |
| 20 | + @Resource | |
| 21 | + private IotRuleSceneService ruleSceneService; | |
| 22 | + | |
| 23 | + @EventListener | |
| 24 | + @Async | |
| 25 | + public void onMessage(IotDeviceMessage message) { | |
| 26 | + log.info("[onMessage][消息内容({})]", message); | |
| 27 | + ruleSceneService.executeRuleScene(message); | |
| 28 | + } | |
| 29 | + | |
| 30 | +} | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/IotRuleSceneService.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.service.rule; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; | |
| 4 | +import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | |
| 5 | + | |
| 6 | +import java.util.List; | |
| 7 | + | |
| 8 | +/** | |
| 9 | + * IoT 规则场景 Service 接口 | |
| 10 | + * | |
| 11 | + * @author 芋道源码 | |
| 12 | + */ | |
| 13 | +public interface IotRuleSceneService { | |
| 14 | + | |
| 15 | + /** | |
| 16 | + * 【缓存】获得指定设备的场景列表 | |
| 17 | + * | |
| 18 | + * @param productKey 产品 Key | |
| 19 | + * @param deviceName 设备名称 | |
| 20 | + * @return 场景列表 | |
| 21 | + */ | |
| 22 | + List<IotRuleSceneDO> getRuleSceneListByProductKeyAndDeviceNameFromCache(String productKey, String deviceName); | |
| 23 | + | |
| 24 | + /** | |
| 25 | + * 执行规则场景 | |
| 26 | + * | |
| 27 | + * @param message 消息 | |
| 28 | + */ | |
| 29 | + void executeRuleScene(IotDeviceMessage message); | |
| 30 | + | |
| 31 | +} | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/IotRuleSceneServiceImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.service.rule; | |
| 2 | + | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 4 | +import cn.hutool.core.collection.ListUtil; | |
| 5 | +import cn.hutool.core.text.CharPool; | |
| 6 | +import cn.hutool.core.util.ObjUtil; | |
| 7 | +import cn.hutool.core.util.StrUtil; | |
| 8 | +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; | |
| 9 | +import cn.iocoder.yudao.framework.common.util.spring.SpringExpressionUtils; | |
| 10 | +import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; | |
| 11 | +import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; | |
| 12 | +import cn.iocoder.yudao.module.iot.dal.mysql.rule.IotRuleSceneMapper; | |
| 13 | +import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum; | |
| 14 | +import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageTypeEnum; | |
| 15 | +import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneTriggerConditionParameterOperatorEnum; | |
| 16 | +import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneTriggerTypeEnum; | |
| 17 | +import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | |
| 18 | +import jakarta.annotation.Resource; | |
| 19 | +import lombok.extern.slf4j.Slf4j; | |
| 20 | +import org.springframework.stereotype.Service; | |
| 21 | +import org.springframework.validation.annotation.Validated; | |
| 22 | + | |
| 23 | +import java.util.List; | |
| 24 | +import java.util.Map; | |
| 25 | + | |
| 26 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList; | |
| 27 | + | |
| 28 | +/** | |
| 29 | + * IoT 规则场景 Service 实现类 | |
| 30 | + * | |
| 31 | + * @author 芋道源码 | |
| 32 | + */ | |
| 33 | +@Service | |
| 34 | +@Validated | |
| 35 | +@Slf4j | |
| 36 | +public class IotRuleSceneServiceImpl implements IotRuleSceneService { | |
| 37 | + | |
| 38 | + @Resource | |
| 39 | + private IotRuleSceneMapper ruleSceneMapper; | |
| 40 | + | |
| 41 | + // TODO 芋艿,缓存待实现 | |
| 42 | + @Override | |
| 43 | + @TenantIgnore // 忽略租户隔离:因为 IotRuleSceneMessageHandler 调用时,一般未传递租户,所以需要忽略 | |
| 44 | + public List<IotRuleSceneDO> getRuleSceneListByProductKeyAndDeviceNameFromCache(String productKey, String deviceName) { | |
| 45 | + if (true) { | |
| 46 | + IotRuleSceneDO ruleScene01 = new IotRuleSceneDO(); | |
| 47 | + ruleScene01.setTriggers(CollUtil.newArrayList()); | |
| 48 | + IotRuleSceneDO.Trigger trigger01 = new IotRuleSceneDO.Trigger(); | |
| 49 | + trigger01.setType(IotRuleSceneTriggerTypeEnum.DEVICE.getType()); | |
| 50 | + trigger01.setConditions(CollUtil.newArrayList()); | |
| 51 | + IotRuleSceneDO.TriggerCondition condition01 = new IotRuleSceneDO.TriggerCondition(); | |
| 52 | + condition01.setType(IotDeviceMessageTypeEnum.PROPERTY.getType()); | |
| 53 | + condition01.setIdentifier(IotDeviceMessageIdentifierEnum.PROPERTY_REPORT.getIdentifier()); | |
| 54 | + condition01.setParameters(CollUtil.newArrayList()); | |
| 55 | + IotRuleSceneDO.TriggerConditionParameter parameter011 = new IotRuleSceneDO.TriggerConditionParameter(); | |
| 56 | + parameter011.setIdentifier("width"); | |
| 57 | + parameter011.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.EQUALS.getOperator()); | |
| 58 | + parameter011.setValue("1"); | |
| 59 | + condition01.getParameters().add(parameter011); | |
| 60 | + IotRuleSceneDO.TriggerConditionParameter parameter012 = new IotRuleSceneDO.TriggerConditionParameter(); | |
| 61 | + parameter012.setIdentifier("width"); | |
| 62 | + parameter012.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_EQUALS.getOperator()); | |
| 63 | + parameter012.setValue("2"); | |
| 64 | + condition01.getParameters().add(parameter012); | |
| 65 | + IotRuleSceneDO.TriggerConditionParameter parameter013 = new IotRuleSceneDO.TriggerConditionParameter(); | |
| 66 | + parameter013.setIdentifier("width"); | |
| 67 | + parameter013.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.GREATER_THAN.getOperator()); | |
| 68 | + parameter013.setValue("0"); | |
| 69 | + condition01.getParameters().add(parameter013); | |
| 70 | + IotRuleSceneDO.TriggerConditionParameter parameter014 = new IotRuleSceneDO.TriggerConditionParameter(); | |
| 71 | + parameter014.setIdentifier("width"); | |
| 72 | + parameter014.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.GREATER_THAN_OR_EQUALS.getOperator()); | |
| 73 | + parameter014.setValue("0"); | |
| 74 | + condition01.getParameters().add(parameter014); | |
| 75 | + IotRuleSceneDO.TriggerConditionParameter parameter015 = new IotRuleSceneDO.TriggerConditionParameter(); | |
| 76 | + parameter015.setIdentifier("width"); | |
| 77 | + parameter015.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.LESS_THAN.getOperator()); | |
| 78 | + parameter015.setValue("2"); | |
| 79 | + condition01.getParameters().add(parameter015); | |
| 80 | + IotRuleSceneDO.TriggerConditionParameter parameter016 = new IotRuleSceneDO.TriggerConditionParameter(); | |
| 81 | + parameter016.setIdentifier("width"); | |
| 82 | + parameter016.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.LESS_THAN_OR_EQUALS.getOperator()); | |
| 83 | + parameter016.setValue("2"); | |
| 84 | + condition01.getParameters().add(parameter016); | |
| 85 | + IotRuleSceneDO.TriggerConditionParameter parameter017 = new IotRuleSceneDO.TriggerConditionParameter(); | |
| 86 | + parameter017.setIdentifier("width"); | |
| 87 | + parameter017.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.IN.getOperator()); | |
| 88 | + parameter017.setValue("1,2,3"); | |
| 89 | + condition01.getParameters().add(parameter017); | |
| 90 | + IotRuleSceneDO.TriggerConditionParameter parameter018 = new IotRuleSceneDO.TriggerConditionParameter(); | |
| 91 | + parameter018.setIdentifier("width"); | |
| 92 | + parameter018.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_IN.getOperator()); | |
| 93 | + parameter018.setValue("0,2,3"); | |
| 94 | + condition01.getParameters().add(parameter018); | |
| 95 | + IotRuleSceneDO.TriggerConditionParameter parameter019 = new IotRuleSceneDO.TriggerConditionParameter(); | |
| 96 | + parameter019.setIdentifier("width"); | |
| 97 | + parameter019.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.BETWEEN.getOperator()); | |
| 98 | + parameter019.setValue("1,3"); | |
| 99 | + condition01.getParameters().add(parameter019); | |
| 100 | + IotRuleSceneDO.TriggerConditionParameter parameter020 = new IotRuleSceneDO.TriggerConditionParameter(); | |
| 101 | + parameter020.setIdentifier("width"); | |
| 102 | + parameter020.setOperator(IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_BETWEEN.getOperator()); | |
| 103 | + parameter020.setValue("2,3"); | |
| 104 | + condition01.getParameters().add(parameter020); | |
| 105 | + trigger01.getConditions().add(condition01); | |
| 106 | + ruleScene01.getTriggers().add(trigger01); | |
| 107 | + | |
| 108 | + return ListUtil.toList(ruleScene01); | |
| 109 | + } | |
| 110 | + | |
| 111 | + List<IotRuleSceneDO> list = ruleSceneMapper.selectList(); | |
| 112 | + // TODO @芋艿:需要考虑开启状态 | |
| 113 | + return filterList(list, ruleScene -> { | |
| 114 | + for (IotRuleSceneDO.Trigger trigger : ruleScene.getTriggers()) { | |
| 115 | + if (ObjUtil.notEqual(trigger.getProductKey(), productKey)) { | |
| 116 | + continue; | |
| 117 | + } | |
| 118 | + if (CollUtil.isEmpty(trigger.getDeviceNames()) // 无设备名称限制 | |
| 119 | + || trigger.getDeviceNames().contains(deviceName)) { // 包含设备名称 | |
| 120 | + return true; | |
| 121 | + } | |
| 122 | + } | |
| 123 | + return false; | |
| 124 | + }); | |
| 125 | + } | |
| 126 | + | |
| 127 | + @Override | |
| 128 | + public void executeRuleScene(IotDeviceMessage message) { | |
| 129 | + // 1. 获得设备匹配的规则场景 | |
| 130 | + List<IotRuleSceneDO> ruleScenes = getMatchedRuleSceneList(message); | |
| 131 | + if (CollUtil.isEmpty(ruleScenes)) { | |
| 132 | + return; | |
| 133 | + } | |
| 134 | + } | |
| 135 | + | |
| 136 | + /** | |
| 137 | + * 获得匹配的规则场景列表 | |
| 138 | + * | |
| 139 | + * @param message 设备消息 | |
| 140 | + * @return 规则场景列表 | |
| 141 | + */ | |
| 142 | + @SuppressWarnings("unchecked") | |
| 143 | + private List<IotRuleSceneDO> getMatchedRuleSceneList(IotDeviceMessage message) { | |
| 144 | + // 1. 匹配设备 | |
| 145 | + // TODO @芋艿:可能需要 getSelf(); 缓存 | |
| 146 | + List<IotRuleSceneDO> ruleScenes = getRuleSceneListByProductKeyAndDeviceNameFromCache( | |
| 147 | + message.getProductKey(), message.getDeviceName()); | |
| 148 | + if (CollUtil.isEmpty(ruleScenes)) { | |
| 149 | + return ruleScenes; | |
| 150 | + } | |
| 151 | + | |
| 152 | + // 2. 匹配 trigger 触发器的条件 | |
| 153 | + return filterList(ruleScenes, ruleScene -> { | |
| 154 | + for (IotRuleSceneDO.Trigger trigger : ruleScene.getTriggers()) { | |
| 155 | + // 非设备触发,不匹配 | |
| 156 | + if (ObjUtil.notEqual(trigger.getType(), IotRuleSceneTriggerTypeEnum.DEVICE.getType())) { | |
| 157 | + return false; | |
| 158 | + } | |
| 159 | + // TODO 芋艿:产品、设备的匹配,要不要这里在做一次???貌似和 1. 部分重复了 | |
| 160 | + // 条件为空,说明没有匹配的条件,因此不匹配 | |
| 161 | + if (CollUtil.isEmpty(trigger.getConditions())) { | |
| 162 | + return false; | |
| 163 | + } | |
| 164 | + IotRuleSceneDO.TriggerCondition found = CollUtil.findOne(trigger.getConditions(), condition -> { | |
| 165 | + if (ObjUtil.notEqual(message.getType(), condition.getType()) | |
| 166 | + || ObjUtil.notEqual(message.getIdentifier(), condition.getIdentifier())) { | |
| 167 | + return false; | |
| 168 | + } | |
| 169 | + // TODO @芋艿:设备上线,需要测试下。 | |
| 170 | + for (IotRuleSceneDO.TriggerConditionParameter parameter : condition.getParameters()) { | |
| 171 | + // 计算是否匹配 | |
| 172 | + IotRuleSceneTriggerConditionParameterOperatorEnum operator = | |
| 173 | + IotRuleSceneTriggerConditionParameterOperatorEnum.operatorOf(parameter.getOperator()); | |
| 174 | + if (operator == null) { | |
| 175 | + log.error("[getMatchedRuleSceneList][规则场景编号({}) 的触发器({}) 存在错误的操作符({})]", | |
| 176 | + ruleScene.getId(), trigger, parameter.getOperator()); | |
| 177 | + return false; | |
| 178 | + } | |
| 179 | + Object messageValue = ((Map<String, Object>) message.getData()).get(parameter.getIdentifier()); | |
| 180 | + if (messageValue == null) { | |
| 181 | + return false; | |
| 182 | + } | |
| 183 | + String springExpression; | |
| 184 | + if (ObjectUtils.equalsAny(operator, IotRuleSceneTriggerConditionParameterOperatorEnum.BETWEEN, | |
| 185 | + IotRuleSceneTriggerConditionParameterOperatorEnum.NOT_BETWEEN)) { | |
| 186 | + String[] parameterValues = StrUtil.splitToArray(parameter.getValue(), CharPool.COMMA); | |
| 187 | + springExpression = String.format(operator.getSpringExpression(), messageValue, parameterValues[0], | |
| 188 | + messageValue, parameterValues[1]); | |
| 189 | + } else { | |
| 190 | + springExpression = String.format(operator.getSpringExpression(), messageValue, parameter.getValue()); | |
| 191 | + } | |
| 192 | + // TODO @芋艿:【需优化】需要考虑 struct、时间等参数的比较 | |
| 193 | + try { | |
| 194 | + System.out.println(SpringExpressionUtils.parseExpression(springExpression)); | |
| 195 | + } catch (Exception e) { | |
| 196 | + log.error("[getMatchedRuleSceneList][消息({}) 规则场景编号({}) 的触发器({}) 的匹配表达式({}) 计算异常]", | |
| 197 | + message, ruleScene.getId(), trigger, springExpression, e); | |
| 198 | + } | |
| 199 | + } | |
| 200 | + return true; | |
| 201 | + }); | |
| 202 | + if (found == null) { | |
| 203 | + return false; | |
| 204 | + } | |
| 205 | + log.info("[getMatchedRuleSceneList][消息({}) 匹配到规则场景编号({}) 的触发器({})]", message, ruleScene.getId(), trigger); | |
| 206 | + return true; | |
| 207 | + } | |
| 208 | + return false; | |
| 209 | + }); | |
| 210 | + } | |
| 211 | + | |
| 212 | +} | ... | ... |