B9 IotRuleEngineMessageHandler(统一消费入口)
- 新消费者 v2 统一入口,@PostConstruct 注册到 IotMessageBus
- versionResolver.shouldUseV2 三态路由(V1/V2/HYBRID),绝不双跑
- device null 时 WARN + skip;RuleEngine 异常 try-catch 吞掉防重试风暴
- v1 三消费者(DataRule/SceneRule/CleanRule)增加前置 v2 bypass 判断
- 6 个单元测试(global-v1/v2/hybrid 白名单命中/未命中/device-null/引擎异常)
B14 告警缓存 + SET NX PX 分布式锁 + 有效性判断
- IotAlarmLockService:SET NX PX + Lua 原子解锁,锁冲突抛 ALARM_LOCK_CONFLICT
- IotAlarmCacheService:Redis Hash iot:alarm:state:{id},TTL 7天,cache miss 从DB重建
- AlarmStateValidator:isEffectiveTrigger/isEffectiveClear 时序校验,防旧消息重置已清除告警
- IotAlarmRecordServiceImpl:trigger/clear/ack/archive 全部在锁内,DB写后立即同步缓存
- 新增 ALARM_LOCK_CONFLICT 错误码;AlarmTriggerRequest 增加 timestamp 字段
- 17 个单元测试(锁 4 + 缓存 5 + 校验 9 + 集成 3)
B16 NotifyAction 4 通道集成 + 模板解析
- NotifyChannel SPI 接口 + Sms/Email/InApp/Webhook 四实现(@Component 注册)
- WebhookNotifyChannel:JDK 17 HttpClient 10s 超时 + SSRF 强制 HTTPS 校验
- NotifyDispatcher:独立 ForkJoinPool(8) 并行分发,30s 整体超时,部分失败不阻塞
- 模板变量统一走 TemplateResolver(评审 C5),缺失变量降级为空串
- NotifyAction 移除 stub,委托 NotifyDispatcher
- viewsh-module-system-api 依赖引入;13 个测试(Dispatcher 7 + Webhook SSRF 6)
测试:iot-rule 177/177 全绿;iot-server 251/251 全绿(含 Skipped 161 旧 v1 测试)
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
88 lines
3.1 KiB
XML
88 lines
3.1 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||
<parent>
|
||
<artifactId>viewsh-module-iot</artifactId>
|
||
<groupId>com.viewsh</groupId>
|
||
<version>${revision}</version>
|
||
</parent>
|
||
<modelVersion>4.0.0</modelVersion>
|
||
|
||
<artifactId>viewsh-module-iot-rule</artifactId>
|
||
<packaging>jar</packaging>
|
||
|
||
<name>${project.artifactId}</name>
|
||
<description>IoT 规则引擎独立模块(DAG + SPI + 抖动抑制 + Aviator 脚本)</description>
|
||
|
||
<dependencies>
|
||
<!-- 内部模块:只依赖 api(DTO/枚举)和 core(消息总线/影子接口) -->
|
||
<dependency>
|
||
<groupId>com.viewsh</groupId>
|
||
<artifactId>viewsh-module-iot-api</artifactId>
|
||
<version>${revision}</version>
|
||
</dependency>
|
||
<dependency>
|
||
<groupId>com.viewsh</groupId>
|
||
<artifactId>viewsh-module-iot-core</artifactId>
|
||
<version>${revision}</version>
|
||
</dependency>
|
||
|
||
<!-- B16 通知集成:SMS / 邮件 / 站内信 Feign API -->
|
||
<dependency>
|
||
<groupId>com.viewsh</groupId>
|
||
<artifactId>viewsh-module-system-api</artifactId>
|
||
<version>${revision}</version>
|
||
</dependency>
|
||
|
||
<!-- 【关键】Aviator 表达式引擎 -->
|
||
<dependency>
|
||
<groupId>com.googlecode.aviator</groupId>
|
||
<artifactId>aviator</artifactId>
|
||
<version>5.3.3</version>
|
||
</dependency>
|
||
|
||
<!-- Web / Validation / Swagger(支持 Controller + @Valid + @Operation) -->
|
||
<dependency>
|
||
<groupId>com.viewsh</groupId>
|
||
<artifactId>viewsh-spring-boot-starter-web</artifactId>
|
||
</dependency>
|
||
<!-- Security(支持 @PreAuthorize) -->
|
||
<dependency>
|
||
<groupId>com.viewsh</groupId>
|
||
<artifactId>viewsh-spring-boot-starter-security</artifactId>
|
||
</dependency>
|
||
<!-- 多租户(支持 TenantContextHolder) -->
|
||
<dependency>
|
||
<groupId>com.viewsh</groupId>
|
||
<artifactId>viewsh-spring-boot-starter-biz-tenant</artifactId>
|
||
</dependency>
|
||
|
||
<!-- Micrometer 指标(RuleEngine 节点执行 Timer / 失败计数) -->
|
||
<dependency>
|
||
<groupId>io.micrometer</groupId>
|
||
<artifactId>micrometer-core</artifactId>
|
||
</dependency>
|
||
|
||
<!-- DB 相关 -->
|
||
<dependency>
|
||
<groupId>com.viewsh</groupId>
|
||
<artifactId>viewsh-spring-boot-starter-mybatis</artifactId>
|
||
</dependency>
|
||
|
||
<!-- 缓存相关 -->
|
||
<dependency>
|
||
<groupId>com.viewsh</groupId>
|
||
<artifactId>viewsh-spring-boot-starter-redis</artifactId>
|
||
</dependency>
|
||
|
||
<!-- 测试 -->
|
||
<dependency>
|
||
<groupId>com.viewsh</groupId>
|
||
<artifactId>viewsh-spring-boot-starter-test</artifactId>
|
||
<scope>test</scope>
|
||
</dependency>
|
||
</dependencies>
|
||
|
||
</project>
|