mirror of
https://gitee.com/dromara/RuoYi-Vue-Plus.git
synced 2026-09-18 01:25:28 +08:00
Pre Merge pull request !806 from AprilWind/dev
This commit is contained in:
commit
a0da9b4c61
@ -0,0 +1,116 @@
|
||||
package com.aizuda.snailjob.common.core.alarm.strategy;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.net.url.UrlBuilder;
|
||||
import cn.hutool.core.net.url.UrlPath;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.aizuda.snailjob.common.core.alarm.AlarmContext;
|
||||
import com.aizuda.snailjob.common.core.alarm.attribute.WebhookAttribute;
|
||||
import com.aizuda.snailjob.common.core.constant.SystemConstants;
|
||||
import com.aizuda.snailjob.common.core.enums.AlarmTypeEnum;
|
||||
import com.aizuda.snailjob.common.core.enums.ContentTypeEnum;
|
||||
import com.aizuda.snailjob.common.core.util.JsonUtil;
|
||||
import com.aizuda.snailjob.common.log.SnailJobLog;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Webhook 告警策略
|
||||
* <p>
|
||||
* 设计原则:
|
||||
* 1. 框架只负责投递,不关心业务协议
|
||||
* 2. Payload 由使用者完全定义
|
||||
* 3. 不绑定任何第三方 Webhook 规范
|
||||
*
|
||||
* @author AprilWind
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class WebhookAlarm extends AbstractAlarm<AlarmContext> {
|
||||
|
||||
/**
|
||||
* 构建 Webhook 请求的 Payload
|
||||
* <p>
|
||||
* 设计原则:
|
||||
* 1. 用户完全自定义 Payload(推荐做法):
|
||||
* - 如果 AlarmContext.notifyAttribute 中已经提供完整 JSON 字符串,
|
||||
* 框架会原样发送。
|
||||
* 2. 框架兜底结构(保证最基本可用):
|
||||
* - title: 告警标题
|
||||
* - text: 告警内容
|
||||
* - timestamp: 当前时间戳
|
||||
* 3. 支持根据 webhookUrl 的 path 或 query 自定义不同 Payload:
|
||||
* - /auth/webhook → 纯文本发送
|
||||
* - /markdown → 使用 Markdown 格式
|
||||
* - /third-party/alert → 第三方自定义协议
|
||||
* 4. 用户可扩展方式:
|
||||
* - 在 notifyAttribute 中增加自定义字段,例如 type、level 等
|
||||
* - 根据 webhookUrl 做路由,发送不同 Payload
|
||||
*
|
||||
* @param context AlarmContext 对象,包含 title、text、notifyAttribute 等信息
|
||||
* @return JSON 字符串,作为 Webhook 请求的 body
|
||||
*/
|
||||
private String buildPayload(AlarmContext context) {
|
||||
// 解析 notifyAttribute,获取 webhookUrl 等用户自定义信息
|
||||
Map<String, Object> notifyAttribute = JsonUtil.parseHashMap(context.getNotifyAttribute());
|
||||
String webhookUrl = Convert.toStr(notifyAttribute.get("webhookUrl"));
|
||||
|
||||
// 获取 URL path,用于根据不同路径自定义 Payload
|
||||
UrlPath path = UrlBuilder.ofHttp(webhookUrl).getPath();
|
||||
if (path != null) {
|
||||
// 如 "/auth/webhook" 或 "/markdown"
|
||||
String fullPath = path.toString();
|
||||
SnailJobLog.LOCAL.debug("Webhook URL path: [{}], 可以根据此路径自定义 payload", fullPath);
|
||||
// TODO: 根据 fullPath 自定义不同的 payload
|
||||
// 例如:
|
||||
// if (fullPath.endsWith("/markdown")) { 构建 Markdown payload }
|
||||
// else if (fullPath.endsWith("/third-party/alert")) { 构建第三方协议 payload }
|
||||
}
|
||||
|
||||
// 框架兜底 Payload(保证最基本可用)
|
||||
Map<String, Object> defaultPayload = Map.of(
|
||||
"title", context.getTitle(),
|
||||
"text", context.getText(),
|
||||
"timestamp", System.currentTimeMillis());
|
||||
return JsonUtil.toJsonString(defaultPayload);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getAlarmType() {
|
||||
return AlarmTypeEnum.WEBHOOK.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean syncSendMessage(AlarmContext alarmContext) {
|
||||
|
||||
WebhookAttribute webhookAttribute = JsonUtil.parseObject(alarmContext.getNotifyAttribute(), WebhookAttribute.class);
|
||||
try {
|
||||
String webhookMessage = buildPayload(alarmContext);
|
||||
HttpRequest post = HttpUtil.createPost(webhookAttribute.getWebhookUrl());
|
||||
HttpRequest request = post.body(webhookMessage, ContentTypeEnum.valueOf(webhookAttribute.getContentType()).getMediaType().toString())
|
||||
.header(SystemConstants.SECRET, webhookAttribute.getSecret());
|
||||
HttpResponse execute = request.execute();
|
||||
SnailJobLog.LOCAL.info("Sending Webhook alert result. webHook:[{}], result: [{}]", webhookAttribute.getWebhookUrl(), execute.body());
|
||||
if (execute.isOk()) {
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
SnailJobLog.LOCAL.error("Sending Webhook alert exception. webHook:[{}]", webhookAttribute, e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean asyncSendMessage(List<AlarmContext> alarmContexts) {
|
||||
for (AlarmContext alarmContext : alarmContexts) {
|
||||
asyncSendMessage(alarmContext);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user