diff --git a/common/src/main/java/org/dromara/hertzbeat/common/entity/dto/Message.java b/common/src/main/java/org/dromara/hertzbeat/common/entity/dto/Message.java index 4ccc0cdf6ce..f309819b630 100644 --- a/common/src/main/java/org/dromara/hertzbeat/common/entity/dto/Message.java +++ b/common/src/main/java/org/dromara/hertzbeat/common/entity/dto/Message.java @@ -90,4 +90,4 @@ private Message(byte code, String msg) { private Message(T data) { this.data = data; } -} +} \ No newline at end of file diff --git a/common/src/main/java/org/dromara/hertzbeat/common/entity/manager/NoticeRule.java b/common/src/main/java/org/dromara/hertzbeat/common/entity/manager/NoticeRule.java index 3111c8ff2c7..1ffa1b92dd8 100644 --- a/common/src/main/java/org/dromara/hertzbeat/common/entity/manager/NoticeRule.java +++ b/common/src/main/java/org/dromara/hertzbeat/common/entity/manager/NoticeRule.java @@ -80,6 +80,17 @@ public class NoticeRule { @NotNull private String receiverName; + @Schema(title = "Template ID", + description = "模板ID", + example = "4324324", accessMode = READ_WRITE) + private Long templateId; + + @Schema(title = "Template identification", + description = "通知模板标识", + example = "demo", accessMode = READ_WRITE) + @Length(max = 100) + private String templateName; + @Schema(title = "Whether to enable this policy", description = "是否启用此策略", example = "true", accessMode = READ_WRITE) diff --git a/common/src/main/java/org/dromara/hertzbeat/common/entity/manager/NoticeTemplate.java b/common/src/main/java/org/dromara/hertzbeat/common/entity/manager/NoticeTemplate.java new file mode 100644 index 00000000000..bc954122a49 --- /dev/null +++ b/common/src/main/java/org/dromara/hertzbeat/common/entity/manager/NoticeTemplate.java @@ -0,0 +1,118 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.dromara.hertzbeat.common.entity.manager; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.hibernate.validator.constraints.Length; +import org.springframework.data.annotation.CreatedBy; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedBy; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import javax.persistence.*; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; + +import static io.swagger.v3.oas.annotations.media.Schema.AccessMode.READ_ONLY; +import static io.swagger.v3.oas.annotations.media.Schema.AccessMode.READ_WRITE; + +/** + * Notification strategy entity + * 通知策略 + * + * @author eden4701 + */ +@Entity +@Table(name = "hzb_notice_template") +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Schema(description = "Notify Policy Template | 通知模板实体") +@EntityListeners(AuditingEntityListener.class) +public class NoticeTemplate { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Schema(title = "Notification Template Entity Primary Key Index ID", + description = "通知模板实体主键索引ID", + example = "87584674384", accessMode = READ_ONLY) + private Long id; + + @Schema(title = "Template name", + description = "模板名称", + example = "dispatch-1", accessMode = READ_WRITE) + @Length(max = 100) + @NotBlank + private String name; + + @Schema(title = "Notification information method: 0-SMS 1-Email 2-webhook 3-WeChat Official Account 4-Enterprise WeChat Robot 5-DingTalk Robot 6-FeiShu Robot 7-Telegram Bot 8-SlackWebHook 9-Discord Bot 10-Enterprise WeChat app message", + description = "通知信息方式: 0-手机短信 1-邮箱 2-webhook 3-微信公众号 4-企业微信机器人 5-钉钉机器人 6-飞书机器人 7-Telegram机器人 8-SlackWebHook 9-Discord机器人 10-企业微信-应用消息", + accessMode = READ_WRITE) + @Min(0) + @NotNull + private Byte type; + + @Schema(title = "Is it a preset template: true- preset template false- custom template.", + description = "是否为预设模板: true-预设模板 false-自定义模板", + accessMode = READ_WRITE) + @NotNull + private Boolean presetTemplate; + + + @Schema(title = "Template content", + description = "模板内容", + example = "[${title}]\n" + + "${targetLabel} : ${target}\n" + + "<#if (monitorId??)>${monitorIdLabel} : ${monitorId} \n" + + "<#if (monitorName??)>${monitorNameLabel} : ${monitorName} \n" + + "${priorityLabel} : ${priority}\n" + + "${triggerTimeLabel} : ${triggerTime}\n" + + "${contentLabel} : ${content}", accessMode = READ_WRITE) + @Length(max = 100000) + @NotBlank + @Column(name = "template_content", columnDefinition = "MEDIUMTEXT") + private String templateContent; + + @Schema(title = "The creator of this record", description = "此条记录创建者", example = "tom", accessMode = READ_ONLY) + @CreatedBy + private String creator; + + @Schema(title = "This record was last modified by", + description = "此条记录最新修改者", + example = "tom", accessMode = READ_ONLY) + @LastModifiedBy + private String modifier; + + @Schema(title = "This record creation time (millisecond timestamp)", + description = "记录创建时间", accessMode = READ_ONLY) + @CreatedDate + private LocalDateTime gmtCreate; + + @Schema(title = "Record the latest modification time (timestamp in milliseconds)", + description = "记录最新修改时间", accessMode = READ_ONLY) + @LastModifiedDate + private LocalDateTime gmtUpdate; +} diff --git a/common/src/main/java/org/dromara/hertzbeat/common/util/Pair.java b/common/src/main/java/org/dromara/hertzbeat/common/util/Pair.java index b11465d462f..1bbbc49cd15 100644 --- a/common/src/main/java/org/dromara/hertzbeat/common/util/Pair.java +++ b/common/src/main/java/org/dromara/hertzbeat/common/util/Pair.java @@ -9,7 +9,7 @@ public class Pair { private K left; private final V right; - private Pair(K left, V right) { + public Pair(K left, V right) { this.left = left; this.right = right; } diff --git a/manager/pom.xml b/manager/pom.xml index 35cf3dd92bf..1842c8153ed 100644 --- a/manager/pom.xml +++ b/manager/pom.xml @@ -90,6 +90,11 @@ org.springframework.boot spring-boot-starter-thymeleaf + + + org.springframework.boot + spring-boot-starter-freemarker + net.sourceforge.nekohtml nekohtml diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/AlertNotifyHandler.java b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/AlertNotifyHandler.java index 219084a8faf..215a38d319a 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/AlertNotifyHandler.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/AlertNotifyHandler.java @@ -19,22 +19,23 @@ import org.dromara.hertzbeat.common.entity.alerter.Alert; import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; +import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate; import org.dromara.hertzbeat.manager.support.exception.AlertNoticeException; /** * @author Musk.Chen - * */ public interface AlertNotifyHandler { /** * 发送报警通知 * - * @param receiver Notification configuration information 通知配置信息 - * @param alert Alarm information 告警信息 + * @param receiver Notification configuration information 通知配置信息 + * @param noticeTemplate Notification configuration information 通知配置信息 + * @param alert Alarm information 告警信息 * @throws AlertNoticeException when send receiver error */ - void send(NoticeReceiver receiver, Alert alert) throws AlertNoticeException; + void send(NoticeReceiver receiver, NoticeTemplate noticeTemplate, Alert alert) throws AlertNoticeException; /** * 通知类型 diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/AlertStoreHandler.java b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/AlertStoreHandler.java index 3f9b6117363..94faf44700a 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/AlertStoreHandler.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/AlertStoreHandler.java @@ -23,7 +23,6 @@ * 报警持久化 * * @author Musk.Chen - * */ public interface AlertStoreHandler { diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/DispatcherAlarm.java b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/DispatcherAlarm.java index aa94838913d..cade9a606a3 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/DispatcherAlarm.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/DispatcherAlarm.java @@ -18,13 +18,14 @@ package org.dromara.hertzbeat.manager.component.alerter; import com.google.common.collect.Maps; -import org.dromara.hertzbeat.common.queue.CommonDataQueue; +import lombok.extern.slf4j.Slf4j; import org.dromara.hertzbeat.alert.AlerterWorkerPool; import org.dromara.hertzbeat.common.entity.alerter.Alert; import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; +import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate; +import org.dromara.hertzbeat.common.queue.CommonDataQueue; import org.dromara.hertzbeat.manager.service.NoticeConfigService; import org.dromara.hertzbeat.manager.support.exception.AlertNoticeException; -import lombok.extern.slf4j.Slf4j; import org.dromara.hertzbeat.manager.support.exception.IgnoreException; import org.springframework.beans.factory.InitializingBean; import org.springframework.stereotype.Component; @@ -37,7 +38,6 @@ * 告警信息入库分发 * * @author tom - * */ @Component @Slf4j @@ -79,19 +79,35 @@ public void afterPropertiesSet() throws Exception { * @param alert alert msg * @return send success or failed */ - public boolean sendNoticeMsg(NoticeReceiver receiver, Alert alert) { + public boolean sendNoticeMsg(NoticeReceiver receiver, NoticeTemplate noticeTemplate, Alert alert) { if (receiver == null || receiver.getType() == null) { log.warn("DispatcherAlarm-sendNoticeMsg params is empty alert:[{}], receiver:[{}]", alert, receiver); return false; } byte type = receiver.getType(); if (alertNotifyHandlerMap.containsKey(type)) { - alertNotifyHandlerMap.get(type).send(receiver, alert); + alertNotifyHandlerMap.get(type).send(receiver, noticeTemplate, alert); return true; } return false; } + private List matchReceiverIdByNoticeRules(Alert alert) { + return noticeConfigService.getReceiverIdFilterRule(alert); + } + + private List matchTemplateIdByNoticeRules(Alert alert) { + return noticeConfigService.getTemplateIdFilterRule(alert); + } + + private NoticeReceiver getOneReciverById(List ids) { + return noticeConfigService.getOneReciverByIdInFilterRule(ids); + } + + private NoticeTemplate getOneTemplateById(List ids) { + return noticeConfigService.getOneTemplateByIdInFilterRule(ids); + } + private List matchReceiverByNoticeRules(Alert alert) { return noticeConfigService.getReceiverFilterRule(alert); } @@ -119,17 +135,25 @@ public void run() { } private void sendNotify(Alert alert) { - // Forward configured email WeChat webhook - List receivers = matchReceiverByNoticeRules(alert); + List receivers = matchReceiverIdByNoticeRules(alert); + List templates = matchTemplateIdByNoticeRules(alert); // todo Send notification here temporarily single thread 发送通知这里暂时单线程 - for (NoticeReceiver receiver : receivers) { + for (int i = 0; i < receivers.size(); i++) { try { - sendNoticeMsg(receiver, alert); + if((templates.subList(i, i + 1)).get(0)==null){ + sendNoticeMsg(getOneReciverById(receivers.subList(i, i + 1)), + null, alert); + } + else { + sendNoticeMsg(getOneReciverById(receivers.subList(i, i + 1)), + getOneTemplateById(templates.subList(i, i + 1)), alert); + } } catch (AlertNoticeException e) { log.warn("DispatchTask sendNoticeMsg error, message: {}", e.getMessage()); } } + } } -} +} \ No newline at end of file diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/AbstractAlertNotifyHandlerImpl.java b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/AbstractAlertNotifyHandlerImpl.java index 65be6726a7b..451163b9dad 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/AbstractAlertNotifyHandlerImpl.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/AbstractAlertNotifyHandlerImpl.java @@ -17,67 +17,93 @@ package org.dromara.hertzbeat.manager.component.alerter.impl; +import freemarker.cache.StringTemplateLoader; +import freemarker.template.Configuration; +import freemarker.template.TemplateException; import lombok.extern.slf4j.Slf4j; import org.dromara.hertzbeat.alert.AlerterProperties; import org.dromara.hertzbeat.common.entity.alerter.Alert; +import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate; import org.dromara.hertzbeat.common.support.event.SystemConfigChangeEvent; -import org.dromara.hertzbeat.common.util.CommonUtil; import org.dromara.hertzbeat.common.util.ResourceBundleUtil; import org.dromara.hertzbeat.manager.component.alerter.AlertNotifyHandler; import org.springframework.context.event.EventListener; +import org.springframework.ui.freemarker.FreeMarkerTemplateUtils; import org.springframework.web.client.RestTemplate; -import org.thymeleaf.TemplateEngine; -import org.thymeleaf.context.Context; import javax.annotation.Resource; +import java.io.File; +import java.io.IOException; import java.time.Instant; import java.time.ZoneId; import java.time.format.DateTimeFormatter; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; import java.util.ResourceBundle; - /** * @author gcdd1993 * @version 2.1 * Created by Musk.Chen on 2023/1/16 */ @Slf4j -public abstract class AbstractAlertNotifyHandlerImpl implements AlertNotifyHandler { +abstract class AbstractAlertNotifyHandlerImpl implements AlertNotifyHandler { - protected ResourceBundle bundle = ResourceBundleUtil.getBundle("alerter"); protected static final DateTimeFormatter DTF = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); - - @Resource - protected TemplateEngine templateEngine; - + protected ResourceBundle bundle = ResourceBundleUtil.getBundle("alerter"); @Resource protected RestTemplate restTemplate; @Resource protected AlerterProperties alerterProperties; - protected String renderContent(Alert alert) { - Context context = new Context(); - context.setVariable("title", "[" + bundle.getString("alerter.notify.title") + "]"); - if (alert.getTags() != null) { - alert.getTags().forEach(context::setVariable); - } - context.setVariable("monitorIdLabel", bundle.getString("alerter.notify.monitorId")); - context.setVariable("monitorNameLabel", bundle.getString("alerter.notify.monitorName")); - context.setVariable("targetLabel", bundle.getString("alerter.notify.target")); - context.setVariable("target", alert.getTarget()); - context.setVariable("priorityLabel", bundle.getString("alerter.notify.priority")); - context.setVariable("priority", bundle.getString("alerter.priority." + alert.getPriority())); + protected String renderContent(NoticeTemplate noticeTemplate, Alert alert) throws TemplateException, IOException { - context.setVariable("triggerTimeLabel", bundle.getString("alerter.notify.triggerTime")); - context.setVariable("triggerTime", DTF.format(Instant.ofEpochMilli(alert.getLastAlarmTime()).atZone(ZoneId.systemDefault()).toLocalDateTime())); + StringTemplateLoader stringLoader = new StringTemplateLoader(); + freemarker.template.Template templateRes=null; + Configuration cfg = new Configuration(); + Map model = new HashMap<>(16); + model.put("title", bundle.getString("alerter.notify.title")); - context.setVariable("contentLabel", bundle.getString("alerter.notify.content")); - context.setVariable("content", alert.getContent()); + if (alert.getTags() != null) { + String monitorId = alert.getTags().get("monitorId"); + if (monitorId != null) { + model.put("monitorId", monitorId); + } + String monitorName = alert.getTags().get("monitorName"); + if (monitorName != null) { + model.put("monitorName", monitorName); + } + } - return CommonUtil.removeBlankLine(templateEngine.process(templateName(), context)); + model.put("monitorIdLabel", bundle.getString("alerter.notify.monitorId")); + model.put("monitorNameLabel", bundle.getString("alerter.notify.monitorName")); + model.put("target", alert.getTarget()); + model.put("targetLabel", bundle.getString("alerter.notify.target")); + model.put("priorityLabel", bundle.getString("alerter.notify.priority")); + model.put("priority", bundle.getString("alerter.priority." + alert.getPriority())); + model.put("triggerTimeLabel", bundle.getString("alerter.notify.triggerTime")); + model.put("triggerTime", DTF.format(Instant.ofEpochMilli(alert.getLastAlarmTime()).atZone(ZoneId.systemDefault()).toLocalDateTime())); + model.put("contentLabel", bundle.getString("alerter.notify.content")); + model.put("content", alert.getContent()); + if(noticeTemplate==null){ + String path = this.getClass().getResource("/").getPath(); + cfg.setDirectoryForTemplateLoading(new File(path+"templates/")); + cfg.setDefaultEncoding("utf-8"); + templateRes = cfg.getTemplate(templateName()+".txt"); + } + else { + String templateName = "freemakerTemplate"; + stringLoader.putTemplate(templateName, noticeTemplate.getTemplateContent()); + cfg.setTemplateLoader(stringLoader); + templateRes= cfg.getTemplate(templateName, Locale.CHINESE); + } + String template = FreeMarkerTemplateUtils.processTemplateIntoString(templateRes, model); + return template.replaceAll("((\r\n)|\n)[\\s\t ]*(\\1)+", "$1"); } + /** * Get the Thymeleaf template name * 获取Thymeleaf模板名称 @@ -85,10 +111,13 @@ protected String renderContent(Alert alert) { * @return Thymeleaf模板名称 */ protected abstract String templateName(); - + @EventListener(SystemConfigChangeEvent.class) public void onEvent(SystemConfigChangeEvent event) { log.info("{} receive system config change event: {}.", this.getClass().getName(), event.getSource()); this.bundle = ResourceBundleUtil.getBundle("alerter"); } + } + + diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/CommonRobotNotifyResp.java b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/CommonRobotNotifyResp.java index 552bea757e0..98004e017e4 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/CommonRobotNotifyResp.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/CommonRobotNotifyResp.java @@ -24,8 +24,8 @@ /** * common robot http response entity - * @author tom * + * @author tom */ @Data @AllArgsConstructor diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/DbAlertStoreHandlerImpl.java b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/DbAlertStoreHandlerImpl.java index 4f4a1e3fe7d..6d4d03d6af0 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/DbAlertStoreHandlerImpl.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/DbAlertStoreHandlerImpl.java @@ -17,14 +17,14 @@ package org.dromara.hertzbeat.manager.component.alerter.impl; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.dromara.hertzbeat.alert.service.AlertService; +import org.dromara.hertzbeat.common.constants.CommonConstants; import org.dromara.hertzbeat.common.entity.alerter.Alert; import org.dromara.hertzbeat.common.entity.manager.Monitor; -import org.dromara.hertzbeat.common.constants.CommonConstants; import org.dromara.hertzbeat.manager.component.alerter.AlertStoreHandler; import org.dromara.hertzbeat.manager.service.MonitorService; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; import org.dromara.hertzbeat.manager.support.exception.IgnoreException; import org.springframework.stereotype.Component; @@ -40,11 +40,11 @@ @RequiredArgsConstructor @Slf4j final class DbAlertStoreHandlerImpl implements AlertStoreHandler { - + private final MonitorService monitorService; - + private final AlertService alertService; - + @Override public void store(Alert alert) { Map tags = alert.getTags(); diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/DingTalkRobotAlertNotifyHandlerImpl.java b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/DingTalkRobotAlertNotifyHandlerImpl.java index 95a5951c9f5..60e2e60b89d 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/DingTalkRobotAlertNotifyHandlerImpl.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/DingTalkRobotAlertNotifyHandlerImpl.java @@ -17,12 +17,13 @@ package org.dromara.hertzbeat.manager.component.alerter.impl; -import org.dromara.hertzbeat.common.entity.alerter.Alert; -import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; -import org.dromara.hertzbeat.manager.support.exception.AlertNoticeException; import lombok.Data; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.dromara.hertzbeat.common.entity.alerter.Alert; +import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; +import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate; +import org.dromara.hertzbeat.manager.support.exception.AlertNoticeException; import org.springframework.http.*; import org.springframework.stereotype.Component; @@ -31,19 +32,18 @@ * 通过钉钉机器人发送告警信息 * * @author Musk.Chen - * */ @Component @RequiredArgsConstructor @Slf4j -public class DingTalkRobotAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl { +final class DingTalkRobotAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl { @Override - public void send(NoticeReceiver receiver, Alert alert) { + public void send(NoticeReceiver receiver, NoticeTemplate noticeTemplate, Alert alert) { try { DingTalkWebHookDto dingTalkWebHookDto = new DingTalkWebHookDto(); MarkdownDTO markdownDTO = new MarkdownDTO(); - markdownDTO.setText(renderContent(alert)); + markdownDTO.setText(renderContent(noticeTemplate, alert)); markdownDTO.setTitle(bundle.getString("alerter.notify.title")); dingTalkWebHookDto.setMarkdown(markdownDTO); HttpHeaders headers = new HttpHeaders(); @@ -77,6 +77,7 @@ public byte type() { @Override protected String templateName() { return "alertNotifyDingTalkRobot"; + } /** @@ -84,7 +85,6 @@ protected String templateName() { * * @author 花城 * @version 1.0 - * */ @Data private static class DingTalkWebHookDto { diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/DiscordBotAlertNotifyHandlerImpl.java b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/DiscordBotAlertNotifyHandlerImpl.java index 6970ec8c894..df8926c9f48 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/DiscordBotAlertNotifyHandlerImpl.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/DiscordBotAlertNotifyHandlerImpl.java @@ -1,13 +1,14 @@ package org.dromara.hertzbeat.manager.component.alerter.impl; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import org.dromara.hertzbeat.common.entity.alerter.Alert; -import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; -import org.dromara.hertzbeat.manager.support.exception.AlertNoticeException; import lombok.Builder; import lombok.Data; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.dromara.hertzbeat.common.entity.alerter.Alert; +import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; +import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate; +import org.dromara.hertzbeat.manager.support.exception.AlertNoticeException; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -23,15 +24,15 @@ @Component @RequiredArgsConstructor @Slf4j -public class DiscordBotAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl { +final class DiscordBotAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl { @Override - public void send(NoticeReceiver receiver, Alert alert) throws AlertNoticeException { + public void send(NoticeReceiver receiver, NoticeTemplate noticeTemplate, Alert alert) throws AlertNoticeException { try { var notifyBody = DiscordNotifyDTO.builder() .embeds(List.of(EmbedDTO.builder() .title("[" + bundle.getString("alerter.notify.title") + "]") - .description(renderContent(alert)) + .description(renderContent(noticeTemplate, alert)) .build())) .build(); var url = String.format(alerterProperties.getDiscordNotifyUrl(), receiver.getDiscordChannelId()); diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/EmailAlertNotifyHandlerImpl.java b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/EmailAlertNotifyHandlerImpl.java index 946f63ae119..a57e7a0a6cc 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/EmailAlertNotifyHandlerImpl.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/EmailAlertNotifyHandlerImpl.java @@ -23,6 +23,7 @@ import org.dromara.hertzbeat.common.entity.alerter.Alert; import org.dromara.hertzbeat.common.entity.manager.GeneralConfig; import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; +import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate; import org.dromara.hertzbeat.common.support.event.SystemConfigChangeEvent; import org.dromara.hertzbeat.common.util.ResourceBundleUtil; import org.dromara.hertzbeat.manager.component.alerter.AlertNotifyHandler; @@ -54,19 +55,19 @@ public class EmailAlertNotifyHandlerImpl implements AlertNotifyHandler { private final JavaMailSender javaMailSender; private final MailService mailService; - + @Value("${spring.mail.host:smtp.demo.com}") private String host; - + @Value("${spring.mail.username:demo}") private String username; - + @Value("${spring.mail.password:demo}") private String password; - + @Value("${spring.mail.port:465}") private Integer port; - + @Value("${spring.mail.properties.mail.smtp.ssl.enable:true}") private boolean sslEnable = true; @@ -79,7 +80,7 @@ public class EmailAlertNotifyHandlerImpl implements AlertNotifyHandler { private ResourceBundle bundle = ResourceBundleUtil.getBundle("alerter"); @Override - public void send(NoticeReceiver receiver, Alert alert) throws AlertNoticeException { + public void send(NoticeReceiver receiver, NoticeTemplate noticeTemplate, Alert alert) throws AlertNoticeException { try { //获取sender JavaMailSenderImpl sender = (JavaMailSenderImpl) javaMailSender; @@ -98,10 +99,10 @@ public void send(NoticeReceiver receiver, Alert alert) throws AlertNoticeExcepti sender.setPassword(emailNoticeSenderConfig.getEmailPassword()); Properties props = sender.getJavaMailProperties(); props.put("mail.smtp.ssl.enable", emailNoticeSenderConfig.isEmailSsl()); - fromUsername = emailNoticeSenderConfig.getEmailUsername(); + fromUsername = emailNoticeSenderConfig.getEmailUsername(); useDatabase = true; } - } + } if (!useDatabase) { // 若数据库未配置则启用yml配置 sender.setHost(host); @@ -123,7 +124,7 @@ public void send(NoticeReceiver receiver, Alert alert) throws AlertNoticeExcepti messageHelper.setTo(receiver.getEmail()); messageHelper.setSentDate(new Date()); //Build email templates 构建邮件模版 - String process = mailService.buildAlertHtmlTemplate(alert); + String process = mailService.buildAlertHtmlTemplate(alert,noticeTemplate); //Set Email Content Template 设置邮件内容模版 messageHelper.setText(process, true); javaMailSender.send(mimeMessage); @@ -136,10 +137,10 @@ public void send(NoticeReceiver receiver, Alert alert) throws AlertNoticeExcepti public byte type() { return 1; } - + @EventListener(SystemConfigChangeEvent.class) public void onEvent(SystemConfigChangeEvent event) { log.info("{} receive system config change event: {}.", this.getClass().getName(), event.getSource()); this.bundle = ResourceBundleUtil.getBundle("alerter"); } -} +} \ No newline at end of file diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/FlyBookAlertNotifyHandlerImpl.java b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/FlyBookAlertNotifyHandlerImpl.java index 1a1cc6a4575..65b8817c21e 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/FlyBookAlertNotifyHandlerImpl.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/FlyBookAlertNotifyHandlerImpl.java @@ -18,12 +18,13 @@ package org.dromara.hertzbeat.manager.component.alerter.impl; import com.fasterxml.jackson.annotation.JsonProperty; -import org.dromara.hertzbeat.common.entity.alerter.Alert; -import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; -import org.dromara.hertzbeat.manager.support.exception.AlertNoticeException; import lombok.Data; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.dromara.hertzbeat.common.entity.alerter.Alert; +import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; +import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate; +import org.dromara.hertzbeat.manager.support.exception.AlertNoticeException; import org.springframework.http.*; import org.springframework.stereotype.Component; @@ -35,15 +36,14 @@ * 通过飞书发送告警信息 * * @author Musk.Chen - * */ @Component @RequiredArgsConstructor @Slf4j -public class FlyBookAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl { +final class FlyBookAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl { @Override - public void send(NoticeReceiver receiver, Alert alert) { + public void send(NoticeReceiver receiver, NoticeTemplate noticeTemplate, Alert alert) { try { FlyBookWebHookDto flyBookWebHookDto = new FlyBookWebHookDto(); Content content = new Content(); @@ -56,7 +56,7 @@ public void send(NoticeReceiver receiver, Alert alert) { List contents1 = new ArrayList<>(); FlyBookContent flyBookContent = new FlyBookContent(); flyBookContent.setTag("text"); - flyBookContent.setText(renderContent(alert)); + flyBookContent.setText(renderContent(noticeTemplate, alert)); contents1.add(flyBookContent); FlyBookContent bookContent = new FlyBookContent(); bookContent.setTag("a"); @@ -70,7 +70,7 @@ public void send(NoticeReceiver receiver, Alert alert) { String webHookUrl = alerterProperties.getFlyBookWebHookUrl() + receiver.getWechatId(); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); - HttpEntity flyEntity = new HttpEntity<>(flyBookWebHookDto, headers); + HttpEntity flyEntity = new HttpEntity<>(flyBookWebHookDto, headers); ResponseEntity entity = restTemplate.postForEntity(webHookUrl, flyEntity, CommonRobotNotifyResp.class); if (entity.getStatusCode() == HttpStatus.OK) { diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/HuaweiCloudSmnAlertNotifyHandlerImpl.java b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/HuaweiCloudSmnAlertNotifyHandlerImpl.java index 1c4797a2e0c..1c96e39bdab 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/HuaweiCloudSmnAlertNotifyHandlerImpl.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/HuaweiCloudSmnAlertNotifyHandlerImpl.java @@ -26,31 +26,35 @@ import lombok.extern.slf4j.Slf4j; import org.dromara.hertzbeat.common.entity.alerter.Alert; import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; +import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate; +import org.dromara.hertzbeat.common.util.ResourceBundleUtil; import org.dromara.hertzbeat.manager.support.exception.AlertNoticeException; import org.springframework.stereotype.Component; import java.util.Map; +import java.util.ResourceBundle; import java.util.concurrent.ConcurrentHashMap; /** * @author Musk.Chen - * */ @Component @RequiredArgsConstructor @Slf4j -public class HuaweiCloudSmnAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl { +final class HuaweiCloudSmnAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl { + private final ResourceBundle bundle = ResourceBundleUtil.getBundle("alerter"); + private final Map smnClientMap = new ConcurrentHashMap<>(); @Override - public void send(NoticeReceiver receiver, Alert alert) { + public void send(NoticeReceiver receiver, NoticeTemplate noticeTemplate, Alert alert) { try { var smnClient = getSmnClient(receiver); var request = new PublishMessageRequest() .withTopicUrn(receiver.getSmnTopicUrn()); var body = new PublishMessageRequestBody() .withSubject(bundle.getString("alerter.notify.title")) - .withMessage(renderContent(alert)); + .withMessage(renderContent(noticeTemplate, alert)); request.withBody(body); var response = smnClient.publishMessage(request); log.debug("huaweiCloud smn alert response: {}", response); diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/ServerChanAlertNotifyHandlerImpl.java b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/ServerChanAlertNotifyHandlerImpl.java index 01072ad4a48..019a4bd20cb 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/ServerChanAlertNotifyHandlerImpl.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/ServerChanAlertNotifyHandlerImpl.java @@ -5,17 +5,20 @@ import lombok.extern.slf4j.Slf4j; import org.dromara.hertzbeat.common.entity.alerter.Alert; import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; +import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate; import org.dromara.hertzbeat.manager.support.exception.AlertNoticeException; import org.springframework.http.*; import org.springframework.stereotype.Component; + /** * Server酱发送 + * * @author zqr10159 */ @Component @RequiredArgsConstructor @Slf4j -public class ServerChanAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl{ +public class ServerChanAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl { /** * 发送报警通知 * @@ -24,20 +27,20 @@ public class ServerChanAlertNotifyHandlerImpl extends AbstractAlertNotifyHandler * @throws AlertNoticeException when send receiver error */ @Override - public void send(NoticeReceiver receiver, Alert alert) throws AlertNoticeException { + public void send(NoticeReceiver receiver, NoticeTemplate noticeTemplate, Alert alert) throws AlertNoticeException { try { ServerChanAlertNotifyHandlerImpl.ServerChanWebHookDto serverChanWebHookDto = new ServerChanAlertNotifyHandlerImpl.ServerChanWebHookDto(); serverChanWebHookDto.setTitle(bundle.getString("alerter.notify.title")); - serverChanWebHookDto.setDesp(renderContent(alert)); + serverChanWebHookDto.setDesp(renderContent(noticeTemplate, alert)); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); HttpEntity httpEntity = new HttpEntity<>(serverChanWebHookDto, headers); - String webHookUrl = String.format(alerterProperties.getServerChanNotifyUrl(),receiver.getServerChanToken()); + String webHookUrl = String.format(alerterProperties.getServerChanNotifyUrl(), receiver.getServerChanToken()); ResponseEntity responseEntity = restTemplate.postForEntity(webHookUrl, httpEntity, CommonRobotNotifyResp.class); System.out.println(responseEntity); if (responseEntity.getStatusCode() == HttpStatus.OK) { - log.debug("Send ServerChan webHook: {} Success", webHookUrl); + log.debug("Send ServerChan webHook: {} Success", webHookUrl); } else { log.warn("Send ServerChan webHook: {} Failed: {}", webHookUrl, responseEntity.getBody()); throw new AlertNoticeException("Http StatusCode " + responseEntity.getStatusCode()); diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/SlackAlertNotifyHandlerImpl.java b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/SlackAlertNotifyHandlerImpl.java index 1e783c9d4d3..27b2adb5e03 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/SlackAlertNotifyHandlerImpl.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/SlackAlertNotifyHandlerImpl.java @@ -17,13 +17,14 @@ package org.dromara.hertzbeat.manager.component.alerter.impl; -import org.dromara.hertzbeat.common.entity.alerter.Alert; -import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; -import org.dromara.hertzbeat.manager.support.exception.AlertNoticeException; import lombok.Builder; import lombok.Data; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.dromara.hertzbeat.common.entity.alerter.Alert; +import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; +import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate; +import org.dromara.hertzbeat.manager.support.exception.AlertNoticeException; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -44,15 +45,15 @@ @Component @RequiredArgsConstructor @Slf4j -public class SlackAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl { +final class SlackAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl { private static final String SUCCESS = "ok"; private final RestTemplate restTemplate; @Override - public void send(NoticeReceiver receiver, Alert alert) throws AlertNoticeException { + public void send(NoticeReceiver receiver, NoticeTemplate noticeTemplate, Alert alert) throws AlertNoticeException { try { var slackNotify = SlackNotifyDTO.builder() - .text(renderContent(alert)) + .text(renderContent(noticeTemplate, alert)) .build(); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/SmsAlertNotifyHandlerImpl.java b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/SmsAlertNotifyHandlerImpl.java index 5ec20257655..c37929d9b94 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/SmsAlertNotifyHandlerImpl.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/SmsAlertNotifyHandlerImpl.java @@ -17,15 +17,16 @@ package org.dromara.hertzbeat.manager.component.alerter.impl; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.dromara.hertzbeat.common.constants.CommonConstants; import org.dromara.hertzbeat.common.entity.alerter.Alert; import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; +import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate; import org.dromara.hertzbeat.common.service.TencentSmsClient; -import org.dromara.hertzbeat.common.constants.CommonConstants; import org.dromara.hertzbeat.common.util.ResourceBundleUtil; import org.dromara.hertzbeat.manager.component.alerter.AlertNotifyHandler; import org.dromara.hertzbeat.manager.support.exception.AlertNoticeException; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.stereotype.Component; @@ -33,20 +34,19 @@ /** * @author Musk.Chen - * */ @Component @RequiredArgsConstructor @Slf4j @ConditionalOnProperty("common.sms.tencent.app-id") -public class SmsAlertNotifyHandlerImpl implements AlertNotifyHandler { +final class SmsAlertNotifyHandlerImpl implements AlertNotifyHandler { private final TencentSmsClient tencentSmsClient; private final ResourceBundle bundle = ResourceBundleUtil.getBundle("alerter"); @Override - public void send(NoticeReceiver receiver, Alert alert) { + public void send(NoticeReceiver receiver, NoticeTemplate noticeTemplate, Alert alert) { // SMS notification 短信通知 try { String monitorName = null; diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/TelegramBotAlertNotifyHandlerImpl.java b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/TelegramBotAlertNotifyHandlerImpl.java index 55cf535b854..f38e67334ba 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/TelegramBotAlertNotifyHandlerImpl.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/TelegramBotAlertNotifyHandlerImpl.java @@ -19,16 +19,18 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; -import org.dromara.hertzbeat.common.entity.alerter.Alert; -import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; -import org.dromara.hertzbeat.manager.support.exception.AlertNoticeException; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.dromara.hertzbeat.common.entity.alerter.Alert; +import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; +import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate; +import org.dromara.hertzbeat.manager.support.exception.AlertNoticeException; import org.springframework.http.*; import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; /** * Send alarm information by Telegram Bot @@ -41,15 +43,16 @@ @Component @RequiredArgsConstructor @Slf4j -public class TelegramBotAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl { +final class TelegramBotAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl { + private final RestTemplate restTemplate; @Override - public void send(NoticeReceiver receiver, Alert alert) throws AlertNoticeException { + public void send(NoticeReceiver receiver, NoticeTemplate noticeTemplate, Alert alert) throws AlertNoticeException { try { String url = String.format(alerterProperties.getTelegramBotApiUrl(), receiver.getTgBotToken()); TelegramBotNotifyDTO notifyBody = TelegramBotNotifyDTO.builder() .chatId(receiver.getTgUserId()) - .text(renderContent(alert)) + .text(renderContent(noticeTemplate, alert)) .disableWebPagePreview(true) .build(); HttpHeaders headers = new HttpHeaders(); diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/WeChatAlertNotifyHandlerImpl.java b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/WeChatAlertNotifyHandlerImpl.java index 4f5432b0739..bb2f2f37748 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/WeChatAlertNotifyHandlerImpl.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/WeChatAlertNotifyHandlerImpl.java @@ -19,15 +19,15 @@ import org.dromara.hertzbeat.common.entity.alerter.Alert; import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; +import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate; import org.dromara.hertzbeat.manager.component.alerter.AlertNotifyHandler; /** * @author Musk.Chen - * */ -public class WeChatAlertNotifyHandlerImpl implements AlertNotifyHandler { +final class WeChatAlertNotifyHandlerImpl implements AlertNotifyHandler { @Override - public void send(NoticeReceiver receiver, Alert alert) { + public void send(NoticeReceiver receiver, NoticeTemplate noticeTemplate, Alert alert) { // todo } diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/WeWorkAppAlertNotifyHandlerImpl.java b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/WeWorkAppAlertNotifyHandlerImpl.java index 7af24d1c8df..e8cd5b63a3e 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/WeWorkAppAlertNotifyHandlerImpl.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/WeWorkAppAlertNotifyHandlerImpl.java @@ -5,6 +5,7 @@ import org.dromara.hertzbeat.common.constants.CommonConstants; import org.dromara.hertzbeat.common.entity.alerter.Alert; import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; +import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate; import org.dromara.hertzbeat.common.util.JsonUtil; import org.dromara.hertzbeat.manager.pojo.dto.WeChatAppDTO; import org.dromara.hertzbeat.manager.pojo.dto.WeChatAppReq; @@ -47,7 +48,7 @@ public class WeWorkAppAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerI private final RestTemplate restTemplate; @Override - public void send(NoticeReceiver receiver, Alert alert) throws AlertNoticeException { + public void send(NoticeReceiver receiver, NoticeTemplate noticeTemplate,Alert alert) throws AlertNoticeException { String corpId = receiver.getCorpId(); Integer agentId = receiver.getAgentId(); String appSecret = receiver.getAppSecret(); @@ -57,7 +58,7 @@ public void send(NoticeReceiver receiver, Alert alert) throws AlertNoticeExcepti if (Objects.nonNull(entityResponse.getBody())) { String accessToken = entityResponse.getBody().getAccessToken(); WeChatAppDTO.MarkdownDTO markdown = new WeChatAppDTO.MarkdownDTO(); - markdown.setContent(renderContent(alert)); + markdown.setContent(renderContent(noticeTemplate,alert)); WeChatAppDTO weChatAppDTO = WeChatAppDTO.builder() .toUser(DEFAULT_ALL) .msgType(WeChatAppDTO.MARKDOWN) diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/WeWorkRobotAlertNotifyHandlerImpl.java b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/WeWorkRobotAlertNotifyHandlerImpl.java index 6834058ac6f..578762b8476 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/WeWorkRobotAlertNotifyHandlerImpl.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/WeWorkRobotAlertNotifyHandlerImpl.java @@ -17,12 +17,13 @@ package org.dromara.hertzbeat.manager.component.alerter.impl; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.dromara.hertzbeat.common.entity.alerter.Alert; import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; +import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate; import org.dromara.hertzbeat.manager.pojo.dto.WeWorkWebHookDto; import org.dromara.hertzbeat.manager.support.exception.AlertNoticeException; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; import org.springframework.http.*; import org.springframework.stereotype.Component; @@ -31,7 +32,6 @@ * 通过企业微信发送告警信息 * * @author Musk.Chen - * */ @Component @RequiredArgsConstructor @@ -39,11 +39,11 @@ final class WeWorkRobotAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl { @Override - public void send(NoticeReceiver receiver, Alert alert) { + public void send(NoticeReceiver receiver, NoticeTemplate noticeTemplate, Alert alert) { try { WeWorkWebHookDto weWorkWebHookDTO = new WeWorkWebHookDto(); WeWorkWebHookDto.MarkdownDTO markdownDTO = new WeWorkWebHookDto.MarkdownDTO(); - markdownDTO.setContent(renderContent(alert)); + markdownDTO.setContent(renderContent(noticeTemplate, alert)); weWorkWebHookDTO.setMarkdown(markdownDTO); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/WebHookAlertNotifyHandlerImpl.java b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/WebHookAlertNotifyHandlerImpl.java index 2e9a65254b8..f91dbc9bb30 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/WebHookAlertNotifyHandlerImpl.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/component/alerter/impl/WebHookAlertNotifyHandlerImpl.java @@ -17,28 +17,28 @@ package org.dromara.hertzbeat.manager.component.alerter.impl; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.dromara.hertzbeat.common.entity.alerter.Alert; import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; +import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate; import org.dromara.hertzbeat.manager.component.alerter.AlertNotifyHandler; import org.dromara.hertzbeat.manager.support.exception.AlertNoticeException; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; import org.springframework.http.*; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; /** * @author Musk.Chen - * */ @Component @RequiredArgsConstructor @Slf4j -public class WebHookAlertNotifyHandlerImpl implements AlertNotifyHandler { +final class WebHookAlertNotifyHandlerImpl implements AlertNotifyHandler { private final RestTemplate restTemplate; @Override - public void send(NoticeReceiver receiver, Alert alert) { + public void send(NoticeReceiver receiver, NoticeTemplate noticeTemplate, Alert alert) { try { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/controller/NoticeConfigController.java b/manager/src/main/java/org/dromara/hertzbeat/manager/controller/NoticeConfigController.java index 5d49ca4b56a..b4c4248feea 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/controller/NoticeConfigController.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/controller/NoticeConfigController.java @@ -23,6 +23,8 @@ import org.dromara.hertzbeat.common.entity.dto.Message; import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; import org.dromara.hertzbeat.common.entity.manager.NoticeRule; +import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate; +import org.dromara.hertzbeat.common.util.Pair; import org.dromara.hertzbeat.manager.service.NoticeConfigService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.jpa.domain.Specification; @@ -31,11 +33,19 @@ import javax.persistence.criteria.Predicate; import javax.validation.Valid; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.Optional; import static org.dromara.hertzbeat.common.constants.CommonConstants.FAIL_CODE; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; + /** * Message Notification Configuration API * 消息通知配置API @@ -49,7 +59,6 @@ public class NoticeConfigController { @Autowired private NoticeConfigService noticeConfigService; - @PostMapping(path = "/receiver") @Operation(summary = "Add a recipient", description = "新增一个接收人") public ResponseEntity> addNewNoticeReceiver(@Valid @RequestBody NoticeReceiver noticeReceiver) { @@ -140,6 +149,78 @@ public ResponseEntity>> getRules( return ResponseEntity.ok(message); } + + @PostMapping(path = "/template") + @Operation(summary = "Add a notification template", description = "新增一个通知模板") + public ResponseEntity> addNewNoticeTemplate(@Valid @RequestBody NoticeTemplate noticeTemplate) { + noticeConfigService.addNoticeTemplate(noticeTemplate); + return ResponseEntity.ok(Message.success("Add success")); + } + + @PutMapping(path = "/template") + @Operation(summary = "Modify existing notification template information", description = "修改已存在的通知模板信息") + public ResponseEntity> editNoticeTemplate(@Valid @RequestBody NoticeTemplate noticeTemplate) { + noticeConfigService.editNoticeTemplate(noticeTemplate); + return ResponseEntity.ok(Message.success("Edit success")); + } + + @DeleteMapping(path = "/template/{id}") + @Operation(summary = "Delete existing notification template information", description = "删除已存在的通知模板信息") + public ResponseEntity> deleteNoticeTemplate( + @Parameter(description = "en: Notification template ID,zh: 通知模板ID", example = "6565463543") @PathVariable("id") final Long templateId) { + // Returns success if it does not exist or if the deletion is successful + // todo 不存在或删除成功都返回成功 + Optional noticeTemplate = noticeConfigService.getNoticeTemplatesById(templateId); + if (noticeTemplate == null) { + return ResponseEntity.ok(Message.success("The specified notification template could not be queried, please check whether the parameters are correct")); + } + noticeConfigService.deleteNoticeTemplate(templateId); + return ResponseEntity.ok(Message.success("Delete success")); + } + + @GetMapping(path = "/templates") + @Operation(summary = "Get a list of message notification templates based on query filter items", + description = "根据查询过滤项获取消息通知模板列表") + public ResponseEntity>> getTemplates( + @Parameter(description = "en: Template name,zh: 模板名称,模糊查询", example = "rule1") @RequestParam(required = false) final String name) { + + Specification specification = (root, query, criteriaBuilder) -> { + Predicate predicate = criteriaBuilder.conjunction(); + if (name != null && !"".equals(name)) { + Predicate predicateName = criteriaBuilder.like(root.get("name"), "%" + name + "%"); + predicate = criteriaBuilder.and(predicateName); + } + return predicate; + }; + List templatePage = noticeConfigService.getNoticeTemplates(specification); + Message> message = Message.success(templatePage); + return ResponseEntity.ok(message); + } + + @GetMapping(path = "/default_templates") + @Operation(summary = "Get a list of message notification templates based on query filter items", + description = "根据查询过滤项获取预设消息通知模板列表") + public ResponseEntity >> getDefaultTemplates( + @Parameter(description = "en: Template name,zh: 模板名称,模糊查询", example = "rule1") @RequestParam(required = false) final String name) throws IOException { + List defaultTemplatePage=new ArrayList<>(); + Long intitId=1000L; + String path="manager/src/main/resources/templates/"; + File file = new File(path); + String[] fs=file.list(); + for(String f:fs){ + NoticeTemplate tmp=new NoticeTemplate(); + tmp.setId(intitId); + tmp.setName(f.replace(".txt", "").replace(".html", "")); + tmp.setPresetTemplate(true); + tmp.setTemplateContent(Files.readString(Paths.get(path+f))); + intitId++; + defaultTemplatePage.add(tmp); + } + + Message > message = Message.success(defaultTemplatePage); + return ResponseEntity.ok(message); + } + @PostMapping(path = "/receiver/send-test-msg") @Operation(summary = "Send test msg to receiver", description = "给指定接收人发送测试消息") public ResponseEntity> sendTestMsg(@Valid @RequestBody NoticeReceiver noticeReceiver) { @@ -149,4 +230,4 @@ public ResponseEntity> sendTestMsg(@Valid @RequestBody NoticeRecei } return ResponseEntity.ok(Message.fail(FAIL_CODE, "Notify service not available, please check config!")); } -} +} \ No newline at end of file diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/dao/NoticeTemplateDao.java b/manager/src/main/java/org/dromara/hertzbeat/manager/dao/NoticeTemplateDao.java new file mode 100644 index 00000000000..2b42d6455b1 --- /dev/null +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/dao/NoticeTemplateDao.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.dromara.hertzbeat.manager.dao; + +import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +/** + * NoticeTemplate数据库操作 + * + * @author Eden + */ +public interface NoticeTemplateDao extends JpaRepository, JpaSpecificationExecutor { + /** + * 通过模板类型和预设模板标识查找通知模板 + * + * @param type Byte type 模板类型 + * @param defaultTemplate Boolean defaultTemplate 预设模板标识 + * @return 通知模板 + */ + NoticeTemplate findNoticeTemplateByTypeAndPresetTemplate(Byte type, Boolean defaultTemplate); + + +} diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/pojo/dto/WeChatAppDTO.java b/manager/src/main/java/org/dromara/hertzbeat/manager/pojo/dto/WeChatAppDTO.java index 9e9b18a9676..c404d796323 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/pojo/dto/WeChatAppDTO.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/pojo/dto/WeChatAppDTO.java @@ -62,4 +62,4 @@ public static class TextDTO { private String content; } -} +} \ No newline at end of file diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/service/MailService.java b/manager/src/main/java/org/dromara/hertzbeat/manager/service/MailService.java index fed7207381b..dfa340d8046 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/service/MailService.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/service/MailService.java @@ -17,14 +17,17 @@ package org.dromara.hertzbeat.manager.service; +import freemarker.template.TemplateException; import org.dromara.hertzbeat.common.entity.alerter.Alert; +import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate; + +import java.io.IOException; /** * Email delivery service 邮箱发送服务 * * @author 花城 * @version 1.0 - * */ public interface MailService { @@ -32,8 +35,11 @@ public interface MailService { * Build an alert email template * 构建告警邮件模版 * - * @param alert Alarm data element information 告警数据元信息 + * @param alert Alarm data element information 告警数据元信息 + * @param noticeTemplate NoticeTemplate information 模板信息 * @return content of email 邮件内容 + * @throws IOException IOException information IO异常 + * @throws TemplateException Freemarker TemplateException information Freemarker模板异常 */ - String buildAlertHtmlTemplate(Alert alert); + String buildAlertHtmlTemplate(Alert alert, NoticeTemplate noticeTemplate) throws IOException, TemplateException; } diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/service/NoticeConfigService.java b/manager/src/main/java/org/dromara/hertzbeat/manager/service/NoticeConfigService.java index 47fb7f08b20..01dc8504c12 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/service/NoticeConfigService.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/service/NoticeConfigService.java @@ -20,16 +20,17 @@ import org.dromara.hertzbeat.common.entity.alerter.Alert; import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; import org.dromara.hertzbeat.common.entity.manager.NoticeRule; +import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate; import org.springframework.data.jpa.domain.Specification; import java.util.List; +import java.util.Optional; /** * Message notification configuration interface * 消息通知配置接口 * * @author tom - * */ public interface NoticeConfigService { @@ -41,6 +42,16 @@ public interface NoticeConfigService { * @return Search result 查询结果 */ List getNoticeReceivers(Specification specification); +// Map getNoticeReceiversAndTemplate(Specification specification); + + /** + * Dynamic conditional query + * 动态条件查询 + * + * @param specification Query conditions 查询条件 + * @return Search result 查询结果 + */ + List getNoticeTemplates(Specification specification); /** * Dynamic conditional query @@ -108,6 +119,42 @@ public interface NoticeConfigService { */ List getReceiverFilterRule(Alert alert); + /** + * According to the alarm information matching all notification policies, filter out the recipients' ID who need to be notified + * 根据告警信息与所有通知策略匹配,过滤出需要通知的接收人ID + * + * @param alert Alarm information 告警信息 + * @return Receiver ID 接收人 + */ + List getReceiverIdFilterRule(Alert alert); + + /** + * According to the alarm information matching all notification policies, filter out the templates' ID + * 根据告警信息与所有通知策略匹配,过滤出需要通知模板ID + * + * @param alert Alarm information 告警信息 + * @return Template ID 通知模板 + */ + List getTemplateIdFilterRule(Alert alert); + + /** + * Query the recipient information according to the recipient ID List + * 根据接收人ID列表查询接收人信息 + * + * @param ids Reciver ID List 接收人ID列表 + * @return Receiver 接收人 + */ + NoticeReceiver getOneReciverByIdInFilterRule(List ids); + + /** + * Query the template information according to the template ID List + * 根据通知模板ID列表查询模板信息 + * + * @param ids Template ID List 接收人ID列表 + * @return Template 通知模板 + */ + NoticeTemplate getOneTemplateByIdInFilterRule(List ids); + /** * Query recipient information based on recipient ID (primary key Id) * 根据接收人ID(主键Id)查询接收人信息 @@ -126,11 +173,59 @@ public interface NoticeConfigService { */ NoticeRule getNoticeRulesById(Long ruleId); + /** + * Add a notification template + * 新增一个通知接收人 + * + * @param noticeTemplate template information 接收人信息 + */ + void addNoticeTemplate(NoticeTemplate noticeTemplate); + + /** + * Modify notification templates + * 修改通知接收人 + * + * @param noticeTemplate template information 接收人信息 + */ + void editNoticeTemplate(NoticeTemplate noticeTemplate); + + /** + * Delete template information based on Template ID + * 根据通知模板ID删除通知模板信息 + * + * @param templateId Template ID 接收人ID + */ + void deleteNoticeTemplate(Long templateId); + + + /** + * Query specific notification templates according to the template ID (primary key ID) + * 根据模板ID(主键ID)查询具体通知规则 + * + * @param templateId Template ID 模板ID(主键ID) + * @return Notification Template Entity 通知模板实体 + */ + Optional getNoticeTemplatesById(Long templateId); + + /** + * Query specific notification templates according to the template type and default + * 根据模板类型和预设模板标识查询具体通知规则 + * + * @param type Template type 模板类型 + * @param defaultTemplate Preset template identification 预设模板标识 + * @return Notification Template Entity 通知模板实体 + */ + NoticeTemplate findNoticeTemplateByTypeAndDefault(Byte type, Boolean defaultTemplate); + + /** * alert Send test message * 告警 发送测试消息 + * * @param noticeReceiver recipient information 接收人信息 * @return true send success | false send fail */ boolean sendTestMsg(NoticeReceiver noticeReceiver); + + } diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/service/impl/MailServiceImpl.java b/manager/src/main/java/org/dromara/hertzbeat/manager/service/impl/MailServiceImpl.java index 939641e23a6..46ce5f30c28 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/service/impl/MailServiceImpl.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/service/impl/MailServiceImpl.java @@ -17,22 +17,26 @@ package org.dromara.hertzbeat.manager.service.impl; +import freemarker.cache.StringTemplateLoader; +import freemarker.template.Configuration; +import freemarker.template.TemplateException; import org.dromara.hertzbeat.alert.AlerterProperties; import org.dromara.hertzbeat.common.entity.alerter.Alert; import org.dromara.hertzbeat.common.constants.CommonConstants; -import org.dromara.hertzbeat.common.support.event.SystemConfigChangeEvent; +import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate; import org.dromara.hertzbeat.common.util.ResourceBundleUtil; import org.dromara.hertzbeat.manager.service.MailService; import lombok.extern.slf4j.Slf4j; -import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; +import org.springframework.ui.freemarker.FreeMarkerTemplateUtils; import org.thymeleaf.TemplateEngine; import org.thymeleaf.context.Context; import javax.annotation.Resource; +import java.io.File; +import java.io.IOException; import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.ResourceBundle; +import java.util.*; /** * Mailbox sending service interface implementation class @@ -46,16 +50,14 @@ @Service public class MailServiceImpl implements MailService { - @Resource - private TemplateEngine templateEngine; - @Resource private AlerterProperties alerterProperties; private ResourceBundle bundle = ResourceBundleUtil.getBundle("alerter"); - @Override - public String buildAlertHtmlTemplate(final Alert alert) { + public String buildAlertHtmlTemplate(final Alert alert, NoticeTemplate noticeTemplate) throws IOException, TemplateException { + freemarker.template.Template templateMail=null; + Configuration cfg = new Configuration(); String monitorId = null; String monitorName = null; if (alert.getTags() != null) { @@ -65,31 +67,39 @@ public String buildAlertHtmlTemplate(final Alert alert) { monitorId = monitorId == null? "External Alarm, No ID" : monitorId; monitorName = monitorName == null? "External Alarm, No Name" : monitorName; // Introduce thymeleaf context parameters to render pages - // 引入thymeleaf上下文参数渲染页面 - Context context = new Context(); - context.setVariable("nameTitle", bundle.getString("alerter.notify.title")); - context.setVariable("nameTarget", bundle.getString("alerter.notify.target")); - context.setVariable("nameMonitorId", bundle.getString("alerter.notify.monitorId")); - context.setVariable("nameMonitorName", bundle.getString("alerter.notify.monitorName")); - context.setVariable("namePriority", bundle.getString("alerter.notify.priority")); - context.setVariable("nameTriggerTime", bundle.getString("alerter.notify.triggerTime")); - context.setVariable("nameContent", bundle.getString("alerter.notify.content")); - context.setVariable("nameConsole", bundle.getString("alerter.notify.console")); - context.setVariable("target", alert.getTarget()); - context.setVariable("monitorId", monitorId); - context.setVariable("monitorName", monitorName); - context.setVariable("priority", bundle.getString("alerter.priority." + alert.getPriority())); - context.setVariable("content", alert.getContent()); - context.setVariable("consoleUrl", alerterProperties.getConsoleUrl()); + Map model = new HashMap<>(16); + model.put("nameTitle", bundle.getString("alerter.notify.title")); + model.put("nameMonitorId", bundle.getString("alerter.notify.monitorId")); + model.put("nameMonitorName", bundle.getString("alerter.notify.monitorName")); + model.put("target", alert.getTarget()); + model.put("monitorId", monitorId); + model.put("monitorName", monitorName); + model.put("nameTarget", bundle.getString("alerter.notify.target")); + model.put("nameConsole", bundle.getString("alerter.notify.console")); + model.put("namePriority", bundle.getString("alerter.notify.priority")); + model.put("priority", bundle.getString("alerter.priority." + alert.getPriority())); + model.put("nameTriggerTime", bundle.getString("alerter.notify.triggerTime")); + model.put("consoleUrl", alerterProperties.getConsoleUrl()); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - String alarmTime = simpleDateFormat.format(new Date(alert.getLastAlarmTime())); - context.setVariable("lastTriggerTime", alarmTime); - return templateEngine.process("mailAlarm", context); - } - - @EventListener(SystemConfigChangeEvent.class) - public void onEvent(SystemConfigChangeEvent event) { - log.info("{} receive system config change event: {}.", this.getClass().getName(), event.getSource()); - this.bundle = ResourceBundleUtil.getBundle("alerter"); + String triggerTime = simpleDateFormat.format(new Date(alert.getLastAlarmTime())); + model.put("lastTriggerTime",triggerTime); + model.put("nameContent", bundle.getString("alerter.notify.content")); + model.put("content", alert.getContent()); + if(noticeTemplate==null){ + String path = this.getClass().getResource("/").getPath(); + cfg.setDirectoryForTemplateLoading(new File(path+"templates/")); + cfg.setDefaultEncoding("utf-8"); + templateMail = cfg.getTemplate("mailAlarm.html"); + } + else { + StringTemplateLoader stringLoader = new StringTemplateLoader(); + String templateName = "mailTemplate"; + stringLoader.putTemplate(templateName, noticeTemplate.getTemplateContent()); + cfg.setTemplateLoader(stringLoader); + templateMail= cfg.getTemplate(templateName, Locale.CHINESE); + } + String template = FreeMarkerTemplateUtils.processTemplateIntoString(templateMail, model); + return template; } + } diff --git a/manager/src/main/java/org/dromara/hertzbeat/manager/service/impl/NoticeConfigServiceImpl.java b/manager/src/main/java/org/dromara/hertzbeat/manager/service/impl/NoticeConfigServiceImpl.java index 013018179b9..7064c5b0a70 100644 --- a/manager/src/main/java/org/dromara/hertzbeat/manager/service/impl/NoticeConfigServiceImpl.java +++ b/manager/src/main/java/org/dromara/hertzbeat/manager/service/impl/NoticeConfigServiceImpl.java @@ -17,20 +17,23 @@ package org.dromara.hertzbeat.manager.service.impl; +import lombok.extern.slf4j.Slf4j; import org.dromara.hertzbeat.common.cache.CacheFactory; import org.dromara.hertzbeat.common.cache.ICacheService; -import org.dromara.hertzbeat.common.entity.alerter.Alert; import org.dromara.hertzbeat.common.constants.CommonConstants; +import org.dromara.hertzbeat.common.entity.alerter.Alert; +import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; +import org.dromara.hertzbeat.common.entity.manager.NoticeRule; +import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate; import org.dromara.hertzbeat.manager.component.alerter.DispatcherAlarm; import org.dromara.hertzbeat.manager.dao.NoticeReceiverDao; import org.dromara.hertzbeat.manager.dao.NoticeRuleDao; -import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; -import org.dromara.hertzbeat.common.entity.manager.NoticeRule; +import org.dromara.hertzbeat.manager.dao.NoticeTemplateDao; import org.dromara.hertzbeat.manager.service.NoticeConfigService; -import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.data.jpa.domain.Specification; +import org.springframework.data.repository.NoRepositoryBean; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -38,6 +41,7 @@ import java.time.LocalTime; import java.util.List; import java.util.Objects; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -45,11 +49,11 @@ * 消息通知配置实现 * * @author tom - * */ @Service @Transactional(rollbackFor = Exception.class) @Slf4j +@NoRepositoryBean public class NoticeConfigServiceImpl implements NoticeConfigService { private static final String ALERT_TEST_TARGET = "Test Target"; @@ -61,16 +65,23 @@ public class NoticeConfigServiceImpl implements NoticeConfigService { @Autowired private NoticeRuleDao noticeRuleDao; - + @Autowired + private NoticeTemplateDao noticeTemplateDao; @Autowired @Lazy private DispatcherAlarm dispatcherAlarm; + @Override public List getNoticeReceivers(Specification specification) { return noticeReceiverDao.findAll(specification); } + @Override + public List getNoticeTemplates(Specification specification) { + return noticeTemplateDao.findAll(specification); + } + @Override public List getNoticeRules(Specification specification) { return noticeRuleDao.findAll(specification); @@ -170,6 +181,135 @@ public List getReceiverFilterRule(Alert alert) { return noticeReceiverDao.findAllById(filterReceivers); } + public List getReceiverIdFilterRule(Alert alert) { + // use cache + ICacheService noticeCache = CacheFactory.getNoticeCache(); + List rules = (List) noticeCache.get(CommonConstants.CACHE_NOTICE_RULE); + if (rules == null) { + rules = noticeRuleDao.findNoticeRulesByEnableTrue(); + noticeCache.put(CommonConstants.CACHE_NOTICE_RULE, rules); + } + + // The temporary rule is to forward all, and then implement more matching rules: alarm status selection, monitoring type selection, etc. + // 规则是全部转发, 告警状态选择, 监控类型选择等(按照tags标签和告警级别过滤匹配) + List filterReceivers = rules.stream() + .filter(rule -> { + LocalDateTime nowDate = LocalDateTime.now(); + // filter day + int currentDayOfWeek = nowDate.toLocalDate().getDayOfWeek().getValue(); + if (rule.getDays() != null && !rule.getDays().isEmpty()) { + boolean dayMatch = rule.getDays().stream().anyMatch(item -> item == currentDayOfWeek); + if (!dayMatch) { + return false; + } + } + // filter time + if (rule.getPeriodStart() != null && rule.getPeriodEnd() != null) { + LocalTime nowTime = nowDate.toLocalTime(); + + if (nowTime.isBefore(rule.getPeriodStart().toLocalTime()) + || nowTime.isAfter(rule.getPeriodEnd().toLocalTime())) { + return false; + } + } + + if (rule.isFilterAll()) { + return true; + } + // filter priorities + if (rule.getPriorities() != null && !rule.getPriorities().isEmpty()) { + boolean priorityMatch = rule.getPriorities().stream().anyMatch(item -> item != null && item == alert.getPriority()); + if (!priorityMatch) { + return false; + } + } + // filter tags + if (rule.getTags() != null && !rule.getTags().isEmpty()) { + return rule.getTags().stream().anyMatch(tagItem -> { + if (!alert.getTags().containsKey(tagItem.getName())) { + return false; + } + String alertTagValue = alert.getTags().get(tagItem.getName()); + return Objects.equals(tagItem.getValue(), alertTagValue); + }); + } + return true; + }) + .map(NoticeRule::getReceiverId) + .collect(Collectors.toList()); + + return filterReceivers; + } + + public NoticeReceiver getOneReciverByIdInFilterRule(List ids) { + return noticeReceiverDao.findAllById(ids).get(0); + } + + public NoticeTemplate getOneTemplateByIdInFilterRule(List ids) { + return noticeTemplateDao.findAllById(ids).get(0); + } + + public List getTemplateIdFilterRule(Alert alert) { + // use cache + ICacheService noticeCache = CacheFactory.getNoticeCache(); + List rules = (List) noticeCache.get(CommonConstants.CACHE_NOTICE_RULE); + if (rules == null) { + rules = noticeRuleDao.findNoticeRulesByEnableTrue(); + noticeCache.put(CommonConstants.CACHE_NOTICE_RULE, rules); + } + + // The temporary rule is to forward all, and then implement more matching rules: alarm status selection, monitoring type selection, etc. + // 规则是全部转发, 告警状态选择, 监控类型选择等(按照tags标签和告警级别过滤匹配) + List filterTemplates = rules.stream() + .filter(rule -> { + LocalDateTime nowDate = LocalDateTime.now(); + // filter day + int currentDayOfWeek = nowDate.toLocalDate().getDayOfWeek().getValue(); + if (rule.getDays() != null && !rule.getDays().isEmpty()) { + boolean dayMatch = rule.getDays().stream().anyMatch(item -> item == currentDayOfWeek); + if (!dayMatch) { + return false; + } + } + // filter time + if (rule.getPeriodStart() != null && rule.getPeriodEnd() != null) { + LocalTime nowTime = nowDate.toLocalTime(); + + if (nowTime.isBefore(rule.getPeriodStart().toLocalTime()) + || nowTime.isAfter(rule.getPeriodEnd().toLocalTime())) { + return false; + } + } + + if (rule.isFilterAll()) { + return true; + } + // filter priorities + if (rule.getPriorities() != null && !rule.getPriorities().isEmpty()) { + boolean priorityMatch = rule.getPriorities().stream().anyMatch(item -> item != null && item == alert.getPriority()); + if (!priorityMatch) { + return false; + } + } + // filter tags + if (rule.getTags() != null && !rule.getTags().isEmpty()) { + return rule.getTags().stream().anyMatch(tagItem -> { + if (!alert.getTags().containsKey(tagItem.getName())) { + return false; + } + String alertTagValue = alert.getTags().get(tagItem.getName()); + return Objects.equals(tagItem.getValue(), alertTagValue); + }); + } + return true; + }) + .map(NoticeRule::getTemplateId) + .collect(Collectors.toList()); + return filterTemplates; + + } + + @Override public NoticeReceiver getReceiverById(Long receiverId) { return noticeReceiverDao.getReferenceById(receiverId); @@ -180,6 +320,34 @@ public NoticeRule getNoticeRulesById(Long ruleId) { return noticeRuleDao.getReferenceById(ruleId); } + @Override + public void addNoticeTemplate(NoticeTemplate noticeTemplate) { + noticeTemplateDao.save(noticeTemplate); + clearNoticeRulesCache(); + } + + @Override + public void editNoticeTemplate(NoticeTemplate noticeTemplate) { + noticeTemplateDao.save(noticeTemplate); + clearNoticeRulesCache(); + } + + @Override + public void deleteNoticeTemplate(Long templateId) { + noticeTemplateDao.deleteById(templateId); + clearNoticeRulesCache(); + } + + @Override + public Optional getNoticeTemplatesById(Long templateId) { + return noticeTemplateDao.findById(templateId); + } + + @Override + public NoticeTemplate findNoticeTemplateByTypeAndDefault(Byte type, Boolean defaultTemplate) { + return noticeTemplateDao.findNoticeTemplateByTypeAndPresetTemplate(type, defaultTemplate); + } + @Override public boolean sendTestMsg(NoticeReceiver noticeReceiver) { Alert alert = new Alert(); @@ -189,7 +357,10 @@ public boolean sendTestMsg(NoticeReceiver noticeReceiver) { alert.setFirstAlarmTime(System.currentTimeMillis()); alert.setLastAlarmTime(System.currentTimeMillis()); alert.setPriority(CommonConstants.ALERT_PRIORITY_CODE_CRITICAL); - return dispatcherAlarm.sendNoticeMsg(noticeReceiver, alert); + Byte type = noticeReceiver.getType(); + Boolean defaultTemplate = true; + NoticeTemplate noticeTemplate = findNoticeTemplateByTypeAndDefault(type, defaultTemplate); + return dispatcherAlarm.sendNoticeMsg(noticeReceiver, noticeTemplate, alert); } private void clearNoticeRulesCache() { diff --git a/manager/src/main/resources/application.yml b/manager/src/main/resources/application.yml index 479c25a3cfa..9762e1bca80 100644 --- a/manager/src/main/resources/application.yml +++ b/manager/src/main/resources/application.yml @@ -172,4 +172,4 @@ alerter: scheduler: server: enabled: true - port: 1158 + port: 1158 \ No newline at end of file diff --git a/manager/src/main/resources/templates/alertNotifyDingTalkRobot.txt b/manager/src/main/resources/templates/alertNotifyDingTalkRobot.txt index 0e3fd4ef92c..fe2a16ce78a 100644 --- a/manager/src/main/resources/templates/alertNotifyDingTalkRobot.txt +++ b/manager/src/main/resources/templates/alertNotifyDingTalkRobot.txt @@ -1,7 +1,7 @@ -#### [(${title})] -##### **[(${targetLabel})]** : [(${target})] -[# th:if="${monitorId != null}"] ##### **[(${monitorIdLabel})]** : [(${monitorId})][/] -[# th:if="${monitorName != null}"] ##### **[(${monitorNameLabel})]** : [(${monitorName})][/] - ##### **[(${priorityLabel})]** : [(${priority})] - ##### **[(${triggerTimeLabel})]** : [(${triggerTime})] - ##### **[(${contentLabel})]** : [(${content})] \ No newline at end of file +#### [${title}] +##### **${targetLabel}** : ${target} +<#if (monitorId??)>##### **${monitorIdLabel}** : ${monitorId} +<#if (monitorName??)>##### **${monitorNameLabel}** : ${monitorName} +##### **${priorityLabel}** : ${priority} +##### **${triggerTimeLabel}** : ${triggerTime} +##### **${contentLabel}** : ${content} \ No newline at end of file diff --git a/manager/src/main/resources/templates/alertNotifyDiscordBot.txt b/manager/src/main/resources/templates/alertNotifyDiscordBot.txt index cdf2587ccc1..787aa16de7f 100644 --- a/manager/src/main/resources/templates/alertNotifyDiscordBot.txt +++ b/manager/src/main/resources/templates/alertNotifyDiscordBot.txt @@ -1,6 +1,6 @@ -[(${targetLabel})] : [(${target})] -[# th:if="${monitorId != null}"][(${monitorIdLabel})] : [(${monitorId})][/] -[# th:if="${monitorName != null}"][(${monitorNameLabel})] : [(${monitorName})][/] -[(${priorityLabel})] : [(${priority})] -[(${triggerTimeLabel})] : [(${triggerTime})] -[(${contentLabel})] : [(${content})] \ No newline at end of file +${targetLabel} : ${target} +<#if (monitorId??)>${monitorIdLabel} : ${monitorId} +<#if (monitorName??)>${monitorNameLabel} : ${monitorName} +${priorityLabel} : ${priority} +${triggerTimeLabel} : ${triggerTime} +${contentLabel} : ${content} \ No newline at end of file diff --git a/manager/src/main/resources/templates/alertNotifyFlyBook.txt b/manager/src/main/resources/templates/alertNotifyFlyBook.txt index cdf2587ccc1..787aa16de7f 100644 --- a/manager/src/main/resources/templates/alertNotifyFlyBook.txt +++ b/manager/src/main/resources/templates/alertNotifyFlyBook.txt @@ -1,6 +1,6 @@ -[(${targetLabel})] : [(${target})] -[# th:if="${monitorId != null}"][(${monitorIdLabel})] : [(${monitorId})][/] -[# th:if="${monitorName != null}"][(${monitorNameLabel})] : [(${monitorName})][/] -[(${priorityLabel})] : [(${priority})] -[(${triggerTimeLabel})] : [(${triggerTime})] -[(${contentLabel})] : [(${content})] \ No newline at end of file +${targetLabel} : ${target} +<#if (monitorId??)>${monitorIdLabel} : ${monitorId} +<#if (monitorName??)>${monitorNameLabel} : ${monitorName} +${priorityLabel} : ${priority} +${triggerTimeLabel} : ${triggerTime} +${contentLabel} : ${content} \ No newline at end of file diff --git a/manager/src/main/resources/templates/alertNotifyServerChan.txt b/manager/src/main/resources/templates/alertNotifyServerChan.txt index 0e3fd4ef92c..fe2a16ce78a 100644 --- a/manager/src/main/resources/templates/alertNotifyServerChan.txt +++ b/manager/src/main/resources/templates/alertNotifyServerChan.txt @@ -1,7 +1,7 @@ -#### [(${title})] -##### **[(${targetLabel})]** : [(${target})] -[# th:if="${monitorId != null}"] ##### **[(${monitorIdLabel})]** : [(${monitorId})][/] -[# th:if="${monitorName != null}"] ##### **[(${monitorNameLabel})]** : [(${monitorName})][/] - ##### **[(${priorityLabel})]** : [(${priority})] - ##### **[(${triggerTimeLabel})]** : [(${triggerTime})] - ##### **[(${contentLabel})]** : [(${content})] \ No newline at end of file +#### [${title}] +##### **${targetLabel}** : ${target} +<#if (monitorId??)>##### **${monitorIdLabel}** : ${monitorId} +<#if (monitorName??)>##### **${monitorNameLabel}** : ${monitorName} +##### **${priorityLabel}** : ${priority} +##### **${triggerTimeLabel}** : ${triggerTime} +##### **${contentLabel}** : ${content} \ No newline at end of file diff --git a/manager/src/main/resources/templates/alertNotifySlack.txt b/manager/src/main/resources/templates/alertNotifySlack.txt index 5633717fa58..e0b43268ae9 100644 --- a/manager/src/main/resources/templates/alertNotifySlack.txt +++ b/manager/src/main/resources/templates/alertNotifySlack.txt @@ -1,7 +1,7 @@ -*[(${title})]* -[(${targetLabel})] : [(${target})] -[# th:if="${monitorId != null}"][(${monitorIdLabel})] : `[(${monitorId})]`[/] -[# th:if="${monitorName != null}"][(${monitorNameLabel})] : [(${monitorName})][/] -[(${priorityLabel})] : [(${priority})] -[(${triggerTimeLabel})] : [(${triggerTime})] -[(${contentLabel})] : [(${content})] \ No newline at end of file +*[${title}]* +${targetLabel} : ${target} +<#if (monitorId??)>${monitorIdLabel} : ${monitorId} +<#if (monitorName??)>${monitorNameLabel} : ${monitorName} +${priorityLabel} : ${priority} +${triggerTimeLabel} : ${triggerTime} +${contentLabel} : ${content} \ No newline at end of file diff --git a/manager/src/main/resources/templates/alertNotifySmn.txt b/manager/src/main/resources/templates/alertNotifySmn.txt index 273685b8f72..9b36c38e0f9 100644 --- a/manager/src/main/resources/templates/alertNotifySmn.txt +++ b/manager/src/main/resources/templates/alertNotifySmn.txt @@ -1,7 +1,7 @@ -[(${title})] -[(${targetLabel})] : [(${target})] -[# th:if="${monitorId != null}"][(${monitorIdLabel})] : [(${monitorId})][/] -[# th:if="${monitorName != null}"][(${monitorNameLabel})] : [(${monitorName})][/] -[(${priorityLabel})] : [(${priority})] -[(${triggerTimeLabel})] : [(${triggerTime})] -[(${contentLabel})] : [(${content})] \ No newline at end of file +[${title}] +${targetLabel} : ${target} +<#if (monitorId??)>${monitorIdLabel} : ${monitorId} +<#if (monitorName??)>${monitorNameLabel} : ${monitorName} +${priorityLabel} : ${priority} +${triggerTimeLabel} : ${triggerTime} +${contentLabel} : ${content} \ No newline at end of file diff --git a/manager/src/main/resources/templates/alertNotifyTelegramBot.txt b/manager/src/main/resources/templates/alertNotifyTelegramBot.txt index 273685b8f72..9b36c38e0f9 100644 --- a/manager/src/main/resources/templates/alertNotifyTelegramBot.txt +++ b/manager/src/main/resources/templates/alertNotifyTelegramBot.txt @@ -1,7 +1,7 @@ -[(${title})] -[(${targetLabel})] : [(${target})] -[# th:if="${monitorId != null}"][(${monitorIdLabel})] : [(${monitorId})][/] -[# th:if="${monitorName != null}"][(${monitorNameLabel})] : [(${monitorName})][/] -[(${priorityLabel})] : [(${priority})] -[(${triggerTimeLabel})] : [(${triggerTime})] -[(${contentLabel})] : [(${content})] \ No newline at end of file +[${title}] +${targetLabel} : ${target} +<#if (monitorId??)>${monitorIdLabel} : ${monitorId} +<#if (monitorName??)>${monitorNameLabel} : ${monitorName} +${priorityLabel} : ${priority} +${triggerTimeLabel} : ${triggerTime} +${contentLabel} : ${content} \ No newline at end of file diff --git a/manager/src/main/resources/templates/alertNotifyWeWorkApp.txt b/manager/src/main/resources/templates/alertNotifyWeWorkApp.txt index c1af79a441f..9b36c38e0f9 100644 --- a/manager/src/main/resources/templates/alertNotifyWeWorkApp.txt +++ b/manager/src/main/resources/templates/alertNotifyWeWorkApp.txt @@ -1,7 +1,7 @@ -[(${title})] -[(${targetLabel})] : [(${target})] -[# th:if="${monitorId != null}"][(${monitorIdLabel})] : [(${monitorId})][/] -[# th:if="${monitorName != null}"][(${monitorNameLabel})] : [(${monitorName})][/] -[(${priorityLabel})] : [(${priority})] -[(${triggerTimeLabel})] : [(${triggerTime})] -[(${contentLabel})] : [(${content})] \ No newline at end of file +[${title}] +${targetLabel} : ${target} +<#if (monitorId??)>${monitorIdLabel} : ${monitorId} +<#if (monitorName??)>${monitorNameLabel} : ${monitorName} +${priorityLabel} : ${priority} +${triggerTimeLabel} : ${triggerTime} +${contentLabel} : ${content} \ No newline at end of file diff --git a/manager/src/main/resources/templates/alertNotifyWeWorkRobot.txt b/manager/src/main/resources/templates/alertNotifyWeWorkRobot.txt index c1af79a441f..9b36c38e0f9 100644 --- a/manager/src/main/resources/templates/alertNotifyWeWorkRobot.txt +++ b/manager/src/main/resources/templates/alertNotifyWeWorkRobot.txt @@ -1,7 +1,7 @@ -[(${title})] -[(${targetLabel})] : [(${target})] -[# th:if="${monitorId != null}"][(${monitorIdLabel})] : [(${monitorId})][/] -[# th:if="${monitorName != null}"][(${monitorNameLabel})] : [(${monitorName})][/] -[(${priorityLabel})] : [(${priority})] -[(${triggerTimeLabel})] : [(${triggerTime})] -[(${contentLabel})] : [(${content})] \ No newline at end of file +[${title}] +${targetLabel} : ${target} +<#if (monitorId??)>${monitorIdLabel} : ${monitorId} +<#if (monitorName??)>${monitorNameLabel} : ${monitorName} +${priorityLabel} : ${priority} +${triggerTimeLabel} : ${triggerTime} +${contentLabel} : ${content} \ No newline at end of file diff --git a/manager/src/main/resources/templates/mailAlarm.html b/manager/src/main/resources/templates/mailAlarm.html index d7e7b93256c..6fa15fa0ddd 100644 --- a/manager/src/main/resources/templates/mailAlarm.html +++ b/manager/src/main/resources/templates/mailAlarm.html @@ -581,7 +581,7 @@ class="tblCell">
- HertzBeat Alert Notify + ${nameTitle}
@@ -628,61 +628,61 @@ style="padding-right: 10px; color: #817878; font-weight: 500;"> - - Monitor Target + + ${nameTarget} + >${target} - - Monitor ID + + ${nameMonitorId} - + ${monitorId} - - Monitor Name + + ${nameMonitorName} - + ${monitorName} - - Alert Priority + + ${namePriority} + >${priority} - - Trigger Time + + ${nameTriggerTime} + >${lastTriggerTime}
+ >${content}
@@ -723,9 +723,8 @@ Console Login + href="${consoleUrl}" + data-link-type="web">${nameConsole}
diff --git a/manager/src/test/java/org/dromara/hertzbeat/manager/component/alerter/impl/DingTalkRobotAlertNotifyHandlerImplTest.java b/manager/src/test/java/org/dromara/hertzbeat/manager/component/alerter/impl/DingTalkRobotAlertNotifyHandlerImplTest.java index d2b586b7900..da068ba842d 100644 --- a/manager/src/test/java/org/dromara/hertzbeat/manager/component/alerter/impl/DingTalkRobotAlertNotifyHandlerImplTest.java +++ b/manager/src/test/java/org/dromara/hertzbeat/manager/component/alerter/impl/DingTalkRobotAlertNotifyHandlerImplTest.java @@ -3,6 +3,7 @@ import org.dromara.hertzbeat.common.entity.alerter.Alert; import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; import org.dromara.hertzbeat.common.constants.CommonConstants; +import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate; import org.dromara.hertzbeat.manager.AbstractSpringIntegrationTest; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; @@ -32,6 +33,16 @@ void send() { receiver.setId(1L); receiver.setName("Mock 告警"); receiver.setAccessToken(ddAccessToken); + NoticeTemplate noticeTemplate=new NoticeTemplate(); + noticeTemplate.setId(1L); + noticeTemplate.setName("dingding"); + noticeTemplate.setTemplateContent("#### [${title}]\n" + + "##### **${targetLabel}** : ${target}\n" + + "<#if (monitorId??)>##### **${monitorIdLabel}** : ${monitorId} \n" + + "<#if (monitorName??)>##### **${monitorNameLabel}** : ${monitorName} \n" + + "##### **${priorityLabel}** : ${priority}\n" + + "##### **${triggerTimeLabel}** : ${triggerTime}\n" + + "##### **${contentLabel}** : ${content}"); Alert alert = new Alert(); alert.setId(1L); alert.setTarget("Mock Target"); @@ -43,7 +54,7 @@ void send() { alert.setPriority((byte) 0); alert.setLastAlarmTime(System.currentTimeMillis()); - dingTalkRobotAlertNotifyHandler.send(receiver, alert); + dingTalkRobotAlertNotifyHandler.send(receiver,noticeTemplate, alert); } } diff --git a/manager/src/test/java/org/dromara/hertzbeat/manager/component/alerter/impl/DiscordBotAlertNotifyHandlerImplTest.java b/manager/src/test/java/org/dromara/hertzbeat/manager/component/alerter/impl/DiscordBotAlertNotifyHandlerImplTest.java index b717ecf081e..03fec0161cb 100644 --- a/manager/src/test/java/org/dromara/hertzbeat/manager/component/alerter/impl/DiscordBotAlertNotifyHandlerImplTest.java +++ b/manager/src/test/java/org/dromara/hertzbeat/manager/component/alerter/impl/DiscordBotAlertNotifyHandlerImplTest.java @@ -3,6 +3,7 @@ import org.dromara.hertzbeat.common.entity.alerter.Alert; import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; import org.dromara.hertzbeat.common.constants.CommonConstants; +import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate; import org.dromara.hertzbeat.manager.AbstractSpringIntegrationTest; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; @@ -36,6 +37,15 @@ void send() { receiver.setName("Mock 告警"); receiver.setDiscordChannelId(discordChannelId); receiver.setDiscordBotToken(discordBotToken); + var noticeTemplate=new NoticeTemplate(); + noticeTemplate.setId(1L); + noticeTemplate.setName("DiscordBot"); + noticeTemplate.setTemplateContent("${targetLabel} : ${target}\n" + + "<#if (monitorId??)>${monitorIdLabel} : ${monitorId} \n" + + "<#if (monitorName??)>${monitorNameLabel} : ${monitorName} \n" + + "${priorityLabel} : ${priority}\n" + + "${triggerTimeLabel} : ${triggerTime}\n" + + "${contentLabel} : ${content}"); var alert = new Alert(); alert.setId(1L); alert.setTarget("Mock Target"); @@ -48,6 +58,6 @@ void send() { alert.setPriority((byte) 0); alert.setLastAlarmTime(System.currentTimeMillis()); - discordBotAlertNotifyHandler.send(receiver, alert); + discordBotAlertNotifyHandler.send(receiver, noticeTemplate,alert); } } diff --git a/manager/src/test/java/org/dromara/hertzbeat/manager/component/alerter/impl/FlyBookAlertNotifyHandlerImplTest.java b/manager/src/test/java/org/dromara/hertzbeat/manager/component/alerter/impl/FlyBookAlertNotifyHandlerImplTest.java index 232598f58f7..6d859430c7d 100644 --- a/manager/src/test/java/org/dromara/hertzbeat/manager/component/alerter/impl/FlyBookAlertNotifyHandlerImplTest.java +++ b/manager/src/test/java/org/dromara/hertzbeat/manager/component/alerter/impl/FlyBookAlertNotifyHandlerImplTest.java @@ -3,6 +3,7 @@ import org.dromara.hertzbeat.common.entity.alerter.Alert; import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; import org.dromara.hertzbeat.common.constants.CommonConstants; +import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate; import org.dromara.hertzbeat.manager.AbstractSpringIntegrationTest; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; @@ -32,6 +33,15 @@ void send() { receiver.setId(1L); receiver.setName("Mock 告警"); receiver.setWechatId(flyBookId); + NoticeTemplate noticeTemplate=new NoticeTemplate(); + noticeTemplate.setId(1L); + noticeTemplate.setName("FlyBook"); + noticeTemplate.setTemplateContent("{targetLabel} : ${target}\n" + + "<#if (monitorId??)>${monitorIdLabel} : ${monitorId} \n" + + "<#if (monitorName??)>${monitorNameLabel} : ${monitorName} \n" + + "${priorityLabel} : ${priority}\n" + + "${triggerTimeLabel} : ${triggerTime}\n" + + "${contentLabel} : ${content}"); Alert alert = new Alert(); alert.setId(1L); alert.setTarget("Mock Target"); @@ -43,7 +53,7 @@ void send() { alert.setPriority((byte) 0); alert.setLastAlarmTime(System.currentTimeMillis()); - flyBookAlertNotifyHandler.send(receiver, alert); + flyBookAlertNotifyHandler.send(receiver,noticeTemplate, alert); } } diff --git a/manager/src/test/java/org/dromara/hertzbeat/manager/component/alerter/impl/HuaweiCloudSmnAlertNotifyHandlerImplTest.java b/manager/src/test/java/org/dromara/hertzbeat/manager/component/alerter/impl/HuaweiCloudSmnAlertNotifyHandlerImplTest.java index 9478a184d27..417202fcfba 100644 --- a/manager/src/test/java/org/dromara/hertzbeat/manager/component/alerter/impl/HuaweiCloudSmnAlertNotifyHandlerImplTest.java +++ b/manager/src/test/java/org/dromara/hertzbeat/manager/component/alerter/impl/HuaweiCloudSmnAlertNotifyHandlerImplTest.java @@ -19,6 +19,7 @@ import org.dromara.hertzbeat.common.constants.CommonConstants; import org.dromara.hertzbeat.common.entity.alerter.Alert; import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; +import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate; import org.dromara.hertzbeat.manager.AbstractSpringIntegrationTest; import org.junit.jupiter.api.Test; import org.springframework.util.StringUtils; @@ -71,6 +72,16 @@ void send() throws InterruptedException { receiver.setSmnProjectId(smnProjectId); receiver.setSmnRegion(smnRegion); receiver.setSmnTopicUrn(smnTopicUrn); + var noticeTemplate=new NoticeTemplate(); + noticeTemplate.setId(1L); + noticeTemplate.setName("HuaWeiCloud"); + noticeTemplate.setTemplateContent("[${title}]\n" + + "${targetLabel} : ${target}\n" + + "<#if (monitorId??)>${monitorIdLabel} : ${monitorId} \n" + + "<#if (monitorName??)>${monitorNameLabel} : ${monitorName} \n" + + "${priorityLabel} : ${priority}\n" + + "${triggerTimeLabel} : ${triggerTime}\n" + + "${contentLabel} : ${content}"); var alert = new Alert(); alert.setId(1L); alert.setTarget("Mock Target"); @@ -83,6 +94,6 @@ void send() throws InterruptedException { alert.setPriority((byte) 0); alert.setLastAlarmTime(System.currentTimeMillis()); - huaweiyunSmnAlertNotifyHandler.send(receiver, alert); + huaweiyunSmnAlertNotifyHandler.send(receiver, noticeTemplate,alert); } } diff --git a/manager/src/test/java/org/dromara/hertzbeat/manager/component/alerter/impl/SlackAlertNotifyHandlerImplTest.java b/manager/src/test/java/org/dromara/hertzbeat/manager/component/alerter/impl/SlackAlertNotifyHandlerImplTest.java index 3d0c0d025f8..9c99ac45c0b 100644 --- a/manager/src/test/java/org/dromara/hertzbeat/manager/component/alerter/impl/SlackAlertNotifyHandlerImplTest.java +++ b/manager/src/test/java/org/dromara/hertzbeat/manager/component/alerter/impl/SlackAlertNotifyHandlerImplTest.java @@ -3,6 +3,7 @@ import org.dromara.hertzbeat.common.entity.alerter.Alert; import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; import org.dromara.hertzbeat.common.constants.CommonConstants; +import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate; import org.dromara.hertzbeat.manager.AbstractSpringIntegrationTest; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; @@ -38,6 +39,16 @@ void send() { var alert = new Alert(); alert.setId(1L); alert.setTarget("Mock Target"); + var noticeTemplate=new NoticeTemplate(); + noticeTemplate.setId(1L); + noticeTemplate.setName("Slack"); + noticeTemplate.setTemplateContent("*[${title}]*\n" + + "${targetLabel} : ${target}\n" + + "<#if (monitorId??)>${monitorIdLabel} : ${monitorId} \n" + + "<#if (monitorName??)>${monitorNameLabel} : ${monitorName} \n" + + "${priorityLabel} : ${priority}\n" + + "${triggerTimeLabel} : ${triggerTime}\n" + + "${contentLabel} : ${content}"); var map = Map.of( CommonConstants.TAG_MONITOR_ID, "Mock monitor id", CommonConstants.TAG_MONITOR_NAME, "Mock monitor name" @@ -47,6 +58,6 @@ void send() { alert.setPriority((byte) 0); alert.setLastAlarmTime(System.currentTimeMillis()); - slackAlertNotifyHandler.send(receiver, alert); + slackAlertNotifyHandler.send(receiver, noticeTemplate,alert); } } diff --git a/manager/src/test/java/org/dromara/hertzbeat/manager/component/alerter/impl/TelegramBotAlertNotifyHandlerImplTest.java b/manager/src/test/java/org/dromara/hertzbeat/manager/component/alerter/impl/TelegramBotAlertNotifyHandlerImplTest.java index e094a0da421..23a8a53cbe6 100644 --- a/manager/src/test/java/org/dromara/hertzbeat/manager/component/alerter/impl/TelegramBotAlertNotifyHandlerImplTest.java +++ b/manager/src/test/java/org/dromara/hertzbeat/manager/component/alerter/impl/TelegramBotAlertNotifyHandlerImplTest.java @@ -3,6 +3,7 @@ import org.dromara.hertzbeat.common.entity.alerter.Alert; import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; import org.dromara.hertzbeat.common.constants.CommonConstants; +import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate; import org.dromara.hertzbeat.manager.AbstractSpringIntegrationTest; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; @@ -39,6 +40,16 @@ void send() { Alert alert = new Alert(); alert.setId(1L); alert.setTarget("Mock Target"); + NoticeTemplate noticeTemplate=new NoticeTemplate(); + noticeTemplate.setId(1L); + noticeTemplate.setName("Telegram"); + noticeTemplate.setTemplateContent("[${title}]\n" + + "${targetLabel} : ${target}\n" + + "<#if (monitorId??)>${monitorIdLabel} : ${monitorId} \n" + + "<#if (monitorName??)>${monitorNameLabel} : ${monitorName} \n" + + "${priorityLabel} : ${priority}\n" + + "${triggerTimeLabel} : ${triggerTime}\n" + + "${contentLabel} : ${content}"); Map map = new HashMap<>(); map.put(CommonConstants.TAG_MONITOR_ID, "Mock monitor id"); map.put(CommonConstants.TAG_MONITOR_NAME, "Mock monitor name"); @@ -47,6 +58,6 @@ void send() { alert.setPriority((byte) 0); alert.setLastAlarmTime(System.currentTimeMillis()); - telegramBotAlertNotifyHandler.send(receiver, alert); + telegramBotAlertNotifyHandler.send(receiver, noticeTemplate,alert); } } diff --git a/manager/src/test/java/org/dromara/hertzbeat/manager/component/alerter/impl/WeChatAppAlertNotifyHandlerImplTest.java b/manager/src/test/java/org/dromara/hertzbeat/manager/component/alerter/impl/WeChatAppAlertNotifyHandlerImplTest.java index 7e15b371a6a..0ce1ebce774 100644 --- a/manager/src/test/java/org/dromara/hertzbeat/manager/component/alerter/impl/WeChatAppAlertNotifyHandlerImplTest.java +++ b/manager/src/test/java/org/dromara/hertzbeat/manager/component/alerter/impl/WeChatAppAlertNotifyHandlerImplTest.java @@ -4,6 +4,7 @@ import org.dromara.hertzbeat.common.entity.alerter.Alert; import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; import org.dromara.hertzbeat.common.constants.CommonConstants; +import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate; import org.dromara.hertzbeat.manager.AbstractSpringIntegrationTest; import org.junit.jupiter.api.Test; import org.springframework.util.StringUtils; @@ -44,6 +45,10 @@ public void send() { Alert alert = new Alert(); alert.setId(1L); alert.setTarget("Mock Target"); + NoticeTemplate noticeTemplate=new NoticeTemplate(); + noticeTemplate.setId(1L); + noticeTemplate.setName("WeChatApp"); + noticeTemplate.setTemplateContent(""); Map map = new HashMap<>(); map.put(CommonConstants.TAG_MONITOR_ID, "Mock monitor id"); map.put(CommonConstants.TAG_MONITOR_NAME, "Mock monitor name"); @@ -52,7 +57,7 @@ public void send() { alert.setPriority((byte) 0); alert.setLastAlarmTime(System.currentTimeMillis()); - weChatAppAlertNotifyHandler.send(receiver, alert); + weChatAppAlertNotifyHandler.send(receiver, noticeTemplate, alert); } diff --git a/manager/src/test/java/org/dromara/hertzbeat/manager/component/alerter/impl/WeWorkRobotAlertNotifyHandlerImplTest.java b/manager/src/test/java/org/dromara/hertzbeat/manager/component/alerter/impl/WeWorkRobotAlertNotifyHandlerImplTest.java index cd401520a79..482ca00d05a 100644 --- a/manager/src/test/java/org/dromara/hertzbeat/manager/component/alerter/impl/WeWorkRobotAlertNotifyHandlerImplTest.java +++ b/manager/src/test/java/org/dromara/hertzbeat/manager/component/alerter/impl/WeWorkRobotAlertNotifyHandlerImplTest.java @@ -3,6 +3,7 @@ import org.dromara.hertzbeat.common.entity.alerter.Alert; import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; import org.dromara.hertzbeat.common.constants.CommonConstants; +import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate; import org.dromara.hertzbeat.manager.AbstractSpringIntegrationTest; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; @@ -35,6 +36,16 @@ void send() { Alert alert = new Alert(); alert.setId(1L); alert.setTarget("Mock Target"); + NoticeTemplate noticeTemplate=new NoticeTemplate(); + noticeTemplate.setId(1L); + noticeTemplate.setName("WeWork"); + noticeTemplate.setTemplateContent("[${title}]\n" + + "${targetLabel} : ${target}\n" + + "<#if (monitorId??)>${monitorIdLabel} : ${monitorId} \n" + + "<#if (monitorName??)>${monitorNameLabel} : ${monitorName} \n" + + "${priorityLabel} : ${priority}\n" + + "${triggerTimeLabel} : ${triggerTime}\n" + + "${contentLabel} : ${content}"); Map map = new HashMap<>(); map.put(CommonConstants.TAG_MONITOR_ID, "Mock monitor id"); map.put(CommonConstants.TAG_MONITOR_NAME, "Mock monitor name"); @@ -43,7 +54,7 @@ void send() { alert.setPriority((byte) 0); alert.setLastAlarmTime(System.currentTimeMillis()); - weWorkRobotAlertNotifyHandler.send(receiver, alert); + weWorkRobotAlertNotifyHandler.send(receiver, noticeTemplate, alert); } } diff --git a/manager/src/test/java/org/dromara/hertzbeat/manager/controller/NoticeConfigControllerTest.java b/manager/src/test/java/org/dromara/hertzbeat/manager/controller/NoticeConfigControllerTest.java index ef68cffd283..5316323674f 100644 --- a/manager/src/test/java/org/dromara/hertzbeat/manager/controller/NoticeConfigControllerTest.java +++ b/manager/src/test/java/org/dromara/hertzbeat/manager/controller/NoticeConfigControllerTest.java @@ -1,6 +1,7 @@ package org.dromara.hertzbeat.manager.controller; import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; +import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate; import org.dromara.hertzbeat.common.entity.manager.TagItem; import org.dromara.hertzbeat.common.entity.manager.NoticeRule; import org.dromara.hertzbeat.common.constants.CommonConstants; @@ -51,6 +52,8 @@ public NoticeRule getNoticeRule(){ noticeRule.setName("dispatch-1"); noticeRule.setReceiverId(4324324L); noticeRule.setReceiverName("tom"); + noticeRule.setTemplateId(4324324L); + noticeRule.setTemplateName("test"); noticeRule.setCreator("tom"); noticeRule.setModifier("tom"); noticeRule.setTags(tags); @@ -59,16 +62,34 @@ public NoticeRule getNoticeRule(){ } public NoticeReceiver getNoticeReceiver(){ + NoticeReceiver noticeReceiver = new NoticeReceiver(); - noticeReceiver.setName("tom"); - noticeReceiver.setPhone("18923435643"); - noticeReceiver.setEmail("tom@qq.com"); - noticeReceiver.setHookUrl("https://www.tancloud.cn"); - noticeReceiver.setType((byte) 1); + noticeReceiver.setName("tom"); + noticeReceiver.setId(5L); + noticeReceiver.setAccessToken("c03a568a306f8fd84dab51ff03cf6af6ba676a3be940c904e1df2de34853739d"); + noticeReceiver.setEmail("2762242004@qq.com"); + noticeReceiver.setHookUrl("https://www.tancloud.cn"); + noticeReceiver.setType((byte) 5); return noticeReceiver; } + public NoticeTemplate getNoticeTemplate(){ + NoticeTemplate template = new NoticeTemplate(); + template.setId(5L); + template.setName("Dingding"); + template.setTemplateContent("[${title}]\n" + + "${targetLabel} : ${target}\n" + + "<#if (monitorId??)>${monitorIdLabel} : ${monitorId} \n" + + "<#if (monitorName??)>${monitorNameLabel} : ${monitorName} \n" + + "${priorityLabel} : ${priority}\n" + + "${triggerTimeLabel} : ${triggerTime}\n" + + "${contentLabel} : ${content}"); + template.setType((byte) 5); + + return template; + + } @BeforeEach @@ -81,8 +102,8 @@ void addNewNoticeReceiver() throws Exception { NoticeReceiver noticeReceiver = getNoticeReceiver(); System.out.println(noticeReceiver); this.mockMvc.perform(MockMvcRequestBuilders.post("/api/notice/receiver") - .contentType(MediaType.APPLICATION_JSON) - .content(JsonUtil.toJson(noticeReceiver))) + .contentType(MediaType.APPLICATION_JSON) + .content(JsonUtil.toJson(noticeReceiver))) .andExpect(status().isOk()) .andExpect(jsonPath("$.code").value((int) CommonConstants.SUCCESS_CODE)) .andExpect(jsonPath("$.msg").value("Add success")) diff --git a/manager/src/test/java/org/dromara/hertzbeat/manager/dao/NoticeRuleDaoTest.java b/manager/src/test/java/org/dromara/hertzbeat/manager/dao/NoticeRuleDaoTest.java index 60f518b92bb..5c8adbfcebb 100644 --- a/manager/src/test/java/org/dromara/hertzbeat/manager/dao/NoticeRuleDaoTest.java +++ b/manager/src/test/java/org/dromara/hertzbeat/manager/dao/NoticeRuleDaoTest.java @@ -38,6 +38,8 @@ void setUp() { .priorities(Collections.emptyList()) .receiverId(1L) .receiverName("mock receiver") + .templateId(1L) + .receiverName("mock template") .tags(Collections.emptyList()) .build(); enabled = noticeRuleDao.saveAndFlush(enabled); @@ -56,6 +58,8 @@ void setUp() { .priorities(Collections.emptyList()) .receiverId(1L) .receiverName("mock receiver") + .templateId(1L) + .receiverName("mock template") .tags(Collections.emptyList()) .build(); disabled = noticeRuleDao.saveAndFlush(disabled); diff --git a/manager/src/test/java/org/dromara/hertzbeat/manager/service/MailServiceTest.java b/manager/src/test/java/org/dromara/hertzbeat/manager/service/MailServiceTest.java index 149021407d8..64b7cd0c11b 100644 --- a/manager/src/test/java/org/dromara/hertzbeat/manager/service/MailServiceTest.java +++ b/manager/src/test/java/org/dromara/hertzbeat/manager/service/MailServiceTest.java @@ -1,7 +1,10 @@ package org.dromara.hertzbeat.manager.service; +import freemarker.template.TemplateException; import org.dromara.hertzbeat.alert.AlerterProperties; +import org.dromara.hertzbeat.common.constants.CommonConstants; import org.dromara.hertzbeat.common.entity.alerter.Alert; +import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate; import org.dromara.hertzbeat.manager.service.impl.MailServiceImpl; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -10,9 +13,12 @@ import org.mockito.Mock; import org.mockito.Spy; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.ui.freemarker.FreeMarkerTemplateUtils; import org.thymeleaf.TemplateEngine; import org.thymeleaf.context.Context; +import java.io.IOException; +import java.util.Map; import java.util.ResourceBundle; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -40,17 +46,22 @@ class MailServiceTest { @Mock private ResourceBundle bundle; - @Mock - private Alert alert; - - @BeforeEach - void setUp() { - lenient().when(templateEngine.process(eq("mailAlarm"), any(Context.class))).thenReturn("result"); - } @Test - void buildAlertHtmlTemplate() { - assertEquals("result", mailService.buildAlertHtmlTemplate(alert)); - assertNotNull(mailService.buildAlertHtmlTemplate(alert)); + void buildAlertHtmlTemplate() throws TemplateException, IOException { + Alert alert=new Alert(); + NoticeTemplate noticeTemplate=new NoticeTemplate(); + alert.setTarget("Test Target"); + alert.setContent("Test"); + alert.setTriggerTimes(1); + alert.setFirstAlarmTime(System.currentTimeMillis()); + alert.setLastAlarmTime(System.currentTimeMillis()); + alert.setPriority(CommonConstants.ALERT_PRIORITY_CODE_CRITICAL); + noticeTemplate.setId(1L); + noticeTemplate.setName("test"); + noticeTemplate.setTemplateContent("result"); + + assertEquals("result", mailService.buildAlertHtmlTemplate(alert,noticeTemplate)); + assertNotNull(mailService.buildAlertHtmlTemplate(alert,noticeTemplate)); } } \ No newline at end of file diff --git a/manager/src/test/java/org/dromara/hertzbeat/manager/service/NoticeConfigServiceTest.java b/manager/src/test/java/org/dromara/hertzbeat/manager/service/NoticeConfigServiceTest.java index 351663f81ea..38e68e6bc79 100644 --- a/manager/src/test/java/org/dromara/hertzbeat/manager/service/NoticeConfigServiceTest.java +++ b/manager/src/test/java/org/dromara/hertzbeat/manager/service/NoticeConfigServiceTest.java @@ -2,15 +2,17 @@ import com.google.common.collect.Lists; import com.google.common.collect.Sets; +import org.assertj.core.util.Maps; import org.dromara.hertzbeat.common.entity.alerter.Alert; import org.dromara.hertzbeat.common.entity.manager.NoticeReceiver; import org.dromara.hertzbeat.common.entity.manager.NoticeRule; +import org.dromara.hertzbeat.common.entity.manager.NoticeTemplate; import org.dromara.hertzbeat.common.entity.manager.TagItem; import org.dromara.hertzbeat.manager.component.alerter.DispatcherAlarm; import org.dromara.hertzbeat.manager.dao.NoticeReceiverDao; import org.dromara.hertzbeat.manager.dao.NoticeRuleDao; +import org.dromara.hertzbeat.manager.dao.NoticeTemplateDao; import org.dromara.hertzbeat.manager.service.impl.NoticeConfigServiceImpl; -import org.assertj.core.util.Maps; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -25,10 +27,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.lenient; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.*; /** * Test case for {@link NoticeConfigService} @@ -36,17 +35,16 @@ @ExtendWith(MockitoExtension.class) class NoticeConfigServiceTest { - @InjectMocks - private NoticeConfigServiceImpl noticeConfigService; - @Mock NoticeReceiverDao noticeReceiverDao; - + @Mock + NoticeTemplateDao noticeTemplateDao; @Mock NoticeRuleDao noticeRuleDao; - @Mock DispatcherAlarm dispatcherAlarm; + @InjectMocks + private NoticeConfigServiceImpl noticeConfigService; @BeforeEach void setUp() { @@ -59,6 +57,13 @@ void getNoticeReceivers() { verify(noticeReceiverDao, times(1)).findAll(specification); } + @Test + void getNoticeTemplates() { + final Specification specification = mock(Specification.class); + noticeConfigService.getNoticeTemplates(specification); + verify(noticeTemplateDao, times(1)).findAll(specification); + } + @Test void getNoticeRules() { final Specification specification = mock(Specification.class); @@ -87,6 +92,27 @@ void deleteReceiver() { verify(noticeReceiverDao, times(1)).deleteById(receiverId); } + @Test + void addTemplate() { + final NoticeTemplate noticeTemplate = mock(NoticeTemplate.class); + noticeConfigService.addNoticeTemplate(noticeTemplate); + verify(noticeTemplateDao, times(1)).save(noticeTemplate); + } + + @Test + void editTemplate() { + final NoticeTemplate noticeTemplate = mock(NoticeTemplate.class); + noticeConfigService.editNoticeTemplate(noticeTemplate); + verify(noticeTemplateDao, times(1)).save(noticeTemplate); + } + + @Test + void deleteTemplate() { + final Long templateId = 23342525L; + noticeConfigService.deleteNoticeTemplate(templateId); + verify(noticeTemplateDao, times(1)).deleteById(templateId); + } + @Test void addNoticeRule() { final NoticeRule noticeRule = mock(NoticeRule.class); @@ -173,10 +199,18 @@ void getNoticeRulesById() { verify(noticeRuleDao, times(1)).getReferenceById(receiverId); } + @Test + void getNoticeTemplateById() { + final Long templateId = 343432325L; + noticeConfigService.getNoticeTemplatesById(templateId); + verify(noticeTemplateDao, times(1)).findById(templateId); + } + @Test void sendTestMsg() { final NoticeReceiver noticeReceiver = mock(NoticeReceiver.class); + final NoticeTemplate noticeTemplate = null; noticeConfigService.sendTestMsg(noticeReceiver); - verify(dispatcherAlarm, times(1)).sendNoticeMsg(eq(noticeReceiver), any(Alert.class)); + verify(dispatcherAlarm, times(1)).sendNoticeMsg(eq(noticeReceiver), eq(noticeTemplate), any(Alert.class)); } } diff --git a/web-app/src/app/pojo/NoticeRule.ts b/web-app/src/app/pojo/NoticeRule.ts index 361383917c1..3064e6a2faa 100644 --- a/web-app/src/app/pojo/NoticeRule.ts +++ b/web-app/src/app/pojo/NoticeRule.ts @@ -3,6 +3,8 @@ export class NoticeRule { name!: string; receiverId!: number; receiverName!: string; + templateId!: number; + templateName!: string; enable: boolean = true; // 是否转发所有 filterAll: boolean = true; diff --git a/web-app/src/app/pojo/NoticeTemplate.ts b/web-app/src/app/pojo/NoticeTemplate.ts new file mode 100644 index 00000000000..0203ba59be9 --- /dev/null +++ b/web-app/src/app/pojo/NoticeTemplate.ts @@ -0,0 +1,13 @@ +export class NoticeTemplate { + id!: number; + name!: string; + // 通知信息方式: 0-手机短信 1-邮箱 2-webhook 3-微信公众号 4-企业微信机器人 5-钉钉机器人 6-飞书机器人 + // 7-Telegram机器人 8-SlackWebHook 9-Discord机器人 10-企业微信应用消息 11-华为云SMN + type!: number; + presetTemplate!: boolean; + creator!: string; + modifier!: string; + templateContent!: string; + gmtCreate!: number; + gmtUpdate!: number; +} diff --git a/web-app/src/app/routes/alert/alert-notice/alert-notice.component.html b/web-app/src/app/routes/alert/alert-notice/alert-notice.component.html index 926c64760b2..a1273aa7322 100644 --- a/web-app/src/app/routes/alert/alert-notice/alert-notice.component.html +++ b/web-app/src/app/routes/alert/alert-notice/alert-notice.component.html @@ -1,29 +1,29 @@
- -
@@ -41,55 +41,55 @@ - + {{ 'alert.notice.type.sms' | i18n }} - + {{ 'alert.notice.type.email' | i18n }} - + WebHook - + {{ 'alert.notice.type.wechat' | i18n }} - + {{ 'alert.notice.type.wework' | i18n }} - + {{ 'alert.notice.type.ding' | i18n }} - + {{ 'alert.notice.type.fei-shu' | i18n }} - + {{ 'alert.notice.type.telegram-bot' | i18n }} - + {{ 'alert.notice.type.slack' | i18n }} - + {{ 'alert.notice.type.discord' | i18n }} - + {{ 'alert.notice.type.weChatApp' | i18n }} - + {{ 'alert.notice.type.smn' | i18n }} - + {{ 'alert.notice.type.serverchan' | i18n }} @@ -111,38 +111,193 @@ {{ (data.gmtUpdate ? data.gmtUpdate : data.gmtCreate) | date : 'YYYY-MM-dd HH:mm:ss' }}
+ + +
+ + +
+ + + + {{ 'alert.notice.template.name' | i18n }} + {{ 'alert.notice.template.supplier' | i18n }} + {{ 'common.edit-time' | i18n }} + {{ 'common.edit' | i18n }} + + + + + + {{ data.name }} + + + + + {{ 'alert.applier.type.sms' | i18n }} + + + {{ 'alert.applier.type.email' | i18n }} + + + WebHook + + + {{ 'alert.applier.type.wechat' | i18n }} + + + {{ 'alert.applier.type.wework' | i18n }} + + + {{ 'alert.applier.type.ding' | i18n }} + + + {{ 'alert.applier.type.fei-shu' | i18n }} + + + {{ 'alert.applier.type.telegram' | i18n }} + + + {{ 'alert.applier.type.slack' | i18n }} + + + {{ 'alert.applier.type.discord' | i18n }} + + + {{ 'alert.applier.type.weChatApp' | i18n }} + + + {{ 'alert.applier.type.smn' | i18n }} + + + {{ 'alert.applier.type.serverchan' | i18n }} + + + + + {{ 'alert.applier.type.sms' | i18n }} + + + {{ 'alert.applier.type.email' | i18n }} + + + WebHook + + + {{ 'alert.applier.type.wechat' | i18n }} + + + {{ 'alert.applier.type.wework' | i18n }} + + + {{ 'alert.applier.type.ding' | i18n }} + + + {{ 'alert.applier.type.fei-shu' | i18n }} + + + {{ 'alert.applier.type.telegram' | i18n }} + + + {{ 'alert.applier.type.slack' | i18n }} + + + {{ 'alert.applier.type.discord' | i18n }} + + + {{ 'alert.applier.type.weChatApp' | i18n }} + + + {{ 'alert.applier.type.smn' | i18n }} + + + {{ 'alert.applier.type.serverchan' | i18n }} + + + + {{ (data.gmtUpdate ? data.gmtUpdate : data.gmtCreate) | date : 'YYYY-MM-dd HH:mm:ss' }} + + + + + + + + + + + + +
- -
@@ -150,14 +305,15 @@ {{ 'alert.notice.rule.name' | i18n }} {{ 'alert.notice.receiver.people' | i18n }} + {{ 'alert.notice.template.name' | i18n }} {{ 'alert.notice.rule.all' | i18n }} {{ 'alert.notice.rule.enable' | i18n }} {{ 'common.edit-time' | i18n }} @@ -172,6 +328,9 @@ {{ data.receiverName }} + + {{ data.templateName }} + @@ -181,23 +340,23 @@ {{ (data.gmtUpdate ? data.gmtUpdate : data.gmtCreate) | date : 'YYYY-MM-dd HH:mm:ss' }} @@ -208,65 +367,206 @@ +
+
+ + {{ 'alert.notice.rule.name' | i18n }} + + + + + + {{ 'alert.notice.receiver.people' | i18n }} + + + + + + + {{ 'alert.notice.template' | i18n }} + + + + + + + {{ 'alert.notice.rule.all' | i18n }} + + + + + + {{ 'alert.notice.rule.tag' | i18n }} + + + + + + + {{ 'alert.notice.rule.priority' | i18n }} + + + + + + + + + + + {{ 'alert.notice.rule.period' | i18n }} + + + + + + {{ 'alert.notice.rule.period-chose' | i18n }} + + + + + + {{ 'alert.notice.rule.time' | i18n }} + + + + + + + + {{ 'alert.notice.rule.enable' | i18n }} + + + + +
+
+
+ +
-
+ {{ 'alert.notice.receiver.people.name' | i18n }} - - + + - {{ 'alert.notice.receiver.type' | i18n }} - - - - + {{ 'alert.notice.receiver.type' | i18n }} + + + + - - - - - - - - - + + + + + + + + + - {{ 'alert.notice.type.phone' | i18n }} - - + {{ 'alert.notice.type.phone' | i18n }} + + - {{ 'alert.notice.type.email' | i18n }} - - + {{ 'alert.notice.type.email' | i18n }} + + - {{ 'alert.notice.type.url' | i18n }} - - + {{ 'alert.notice.type.url' | i18n }} + + - {{ + {{ 'alert.notice.type.wechat-id' | i18n }} - - + + @@ -314,122 +614,115 @@ /> + - {{ - 'alert.notice.type.telegram-bot-token' | i18n - }} - - - - - - {{ + {{ 'alert.notice.type.telegram-bot-user-id' | i18n }} - - + + - {{ + {{ 'alert.notice.type.slack-webHook-url' | i18n }} - - + + - {{ + {{ 'alert.notice.type.discord-bot-token' | i18n }} - - + + - {{ + {{ 'alert.notice.type.discord-channel-id' | i18n }} - - + + - + {{ 'alert.notice.type.weChatApp-corpId' | i18n }} - - + + - + {{ 'alert.notice.type.weChatApp-agentId' | i18n }} - - + + - + {{ 'alert.notice.type.weChatApp-appSecret' | i18n }} - - + + - + {{ 'alert.notice.type.smn-ak' | i18n }} - - + + - + {{ 'alert.notice.type.smn-sk' | i18n }} - - + + - + {{ 'alert.notice.type.smn-projectId' | i18n }} - - + + - + {{ 'alert.notice.type.smn-region' | i18n }} - - + + - + {{ 'alert.notice.type.smn-topicUrn' | i18n }} - - + + - {{ + {{ 'alert.notice.type.serverchan-token' | i18n }} - - + + - @@ -437,123 +730,135 @@
-
-
+ - {{ 'alert.notice.rule.name' | i18n }} - - + {{ 'alert.notice.template.name' | i18n }} + + + - {{ 'alert.notice.receiver.people' | i18n }} - - + {{ 'alert.notice.receiver.type' | i18n }} + + + + + + + + + + + + + + + - {{ 'alert.notice.rule.all' | i18n }} - - - - - - {{ 'alert.notice.rule.tag' | i18n }} - - - - - - - {{ 'alert.notice.rule.priority' | i18n }} - - {{ 'alert.notice.template.content' | i18n }} + + +
+
+
+ + +
+
- {{ 'alert.notice.rule.period' | i18n }} - - - - - - {{ 'alert.notice.rule.period-chose' | i18n }} - - + {{ 'alert.notice.template.name' | i18n }} + + + - {{ 'alert.notice.rule.time' | i18n }} - - - - + {{ 'alert.notice.receiver.type' | i18n }} + + + + + + + + + + + + + + + + - {{ 'alert.notice.rule.enable' | i18n }} - - + {{ 'alert.notice.template.content' | i18n }} + +
+ + + +
+ +
+
diff --git a/web-app/src/app/routes/alert/alert-notice/alert-notice.component.ts b/web-app/src/app/routes/alert/alert-notice/alert-notice.component.ts index 82ac540e23f..ee2f0df4eff 100644 --- a/web-app/src/app/routes/alert/alert-notice/alert-notice.component.ts +++ b/web-app/src/app/routes/alert/alert-notice/alert-notice.component.ts @@ -7,8 +7,10 @@ import { finalize } from 'rxjs/operators'; import { NoticeReceiver } from '../../../pojo/NoticeReceiver'; import { NoticeRule, TagItem } from '../../../pojo/NoticeRule'; +import { NoticeTemplate } from '../../../pojo/NoticeTemplate'; import { NoticeReceiverService } from '../../../service/notice-receiver.service'; import { NoticeRuleService } from '../../../service/notice-rule.service'; +import { NoticeTemplateService } from '../../../service/notice-template.service'; import { TagService } from '../../../service/tag.service'; @Component({ @@ -17,28 +19,71 @@ import { TagService } from '../../../service/tag.service'; styles: [] }) export class AlertNoticeComponent implements OnInit { + receivers!: NoticeReceiver[]; + receiverTableLoading: boolean = true; + templates: NoticeTemplate[] = []; + defaultTemplates: NoticeTemplate[] = []; + templateTableLoading: boolean = true; + rules!: NoticeRule[]; + ruleTableLoading: boolean = true; + loading = false; + code: string = ''; + originalCode: string = ''; + // start 新增或修改通知接收人弹出框 + isManageReceiverModalVisible: boolean = false; + isManageReceiverModalAdd: boolean = true; + isManageReceiverModalOkLoading: boolean = false; + isSendTestButtonLoading: boolean = false; + receiver!: NoticeReceiver; + isManageTemplateModalVisible: boolean = false; + isManageTemplateModalAdd: boolean = true; + isManageTemplateModalOkLoading: boolean = false; + isShowTemplateModalVisible: boolean = false; + template: NoticeTemplate = new NoticeTemplate(); + templatesOption: any[] = []; + isManageRuleModalVisible = false; + isManageRuleModalAdd: boolean = true; + isManageRuleModalOkLoading: boolean = false; + rule: NoticeRule = new NoticeRule(); + receiversOption: any[] = []; + searchTag!: string; + tagsOption: any[] = []; + filterTags: string[] = []; + isLimit: boolean = false; + dayCheckOptions = [ + { label: this.i18nSvc.fanyi('common.week.7'), value: 7, checked: true }, + { label: this.i18nSvc.fanyi('common.week.1'), value: 1, checked: true }, + { label: this.i18nSvc.fanyi('common.week.2'), value: 2, checked: true }, + { label: this.i18nSvc.fanyi('common.week.3'), value: 3, checked: true }, + { label: this.i18nSvc.fanyi('common.week.4'), value: 4, checked: true }, + { label: this.i18nSvc.fanyi('common.week.5'), value: 5, checked: true }, + { label: this.i18nSvc.fanyi('common.week.6'), value: 6, checked: true } + ]; + constructor( private notifySvc: NzNotificationService, private noticeReceiverSvc: NoticeReceiverService, private modal: NzModalService, + private noticeTemplateSvc: NoticeTemplateService, private noticeRuleSvc: NoticeRuleService, private tagService: TagService, - @Inject(ALAIN_I18N_TOKEN) private i18nSvc: I18NService ) {} - receivers!: NoticeReceiver[]; - receiverTableLoading: boolean = true; - rules!: NoticeRule[]; - ruleTableLoading: boolean = true; - ngOnInit(): void { this.loadReceiversTable(); this.loadRulesTable(); + this.loadTemplatesTable(); } + syncReceiver() { this.loadReceiversTable(); } + + syncTemplate() { + this.loadTemplatesTable(); + } + syncRule() { this.loadRulesTable(); } @@ -63,6 +108,43 @@ export class AlertNoticeComponent implements OnInit { ); } + loadTemplatesTable() { + this.templateTableLoading = true; + let templatesInit$ = this.noticeTemplateSvc.getNoticeTemplates().subscribe( + message => { + this.templateTableLoading = false; + if (message.code === 0) { + this.templates = message.data; + // this.templates=this.templates.concat(this.defaultTemplates); + } else { + console.warn(message.msg); + } + templatesInit$.unsubscribe(); + }, + error => { + console.error(error.msg); + this.templateTableLoading = false; + templatesInit$.unsubscribe(); + } + ); + let defalutTemplatesInit$ = this.noticeTemplateSvc.getDefaultNoticeTemplates().subscribe( + message => { + this.templateTableLoading = false; + if (message.code === 0) { + this.defaultTemplates = message.data; + } else { + console.warn(message.msg); + } + defalutTemplatesInit$.unsubscribe(); + }, + error => { + console.error(error.msg); + this.templateTableLoading = false; + defalutTemplatesInit$.unsubscribe(); + } + ); + } + loadRulesTable() { this.ruleTableLoading = true; let rulesInit$ = this.noticeRuleSvc.getNoticeRules().subscribe( @@ -130,6 +212,43 @@ export class AlertNoticeComponent implements OnInit { }); } + onDeleteOneNoticeTemplate(templateId: number) { + this.modal.confirm({ + nzTitle: this.i18nSvc.fanyi('common.confirm.delete'), + nzOkText: this.i18nSvc.fanyi('common.button.ok'), + nzCancelText: this.i18nSvc.fanyi('common.button.cancel'), + nzOkDanger: true, + nzOkType: 'primary', + nzClosable: false, + nzOnOk: () => this.deleteOneNoticeTemplate(templateId) + }); + } + + // start 新增或修改通知策略弹出框 + + deleteOneNoticeTemplate(templateId: number) { + const deleteTemplate$ = this.noticeTemplateSvc + .deleteNoticeTemplate(templateId) + .pipe( + finalize(() => { + deleteTemplate$.unsubscribe(); + }) + ) + .subscribe( + message => { + if (message.code === 0) { + this.notifySvc.success(this.i18nSvc.fanyi('common.notify.delete-success'), ''); + this.loadTemplatesTable(); + } else { + this.notifySvc.error(this.i18nSvc.fanyi('common.notify.delete-fail'), message.msg); + } + }, + error => { + this.notifySvc.error(this.i18nSvc.fanyi('common.notify.delete-fail'), error.msg); + } + ); + } + deleteOneNoticeRule(ruleId: number) { const deleteRule$ = this.noticeRuleSvc .deleteNoticeRule(ruleId) @@ -153,13 +272,6 @@ export class AlertNoticeComponent implements OnInit { ); } - // start 新增或修改通知接收人弹出框 - isManageReceiverModalVisible: boolean = false; - isManageReceiverModalAdd: boolean = true; - isManageReceiverModalOkLoading: boolean = false; - isSendTestButtonLoading: boolean = false; - receiver!: NoticeReceiver; - onSplitTokenStr(type: number) { let index = -1; switch (this.receiver?.type) { @@ -195,6 +307,7 @@ export class AlertNoticeComponent implements OnInit { this.isManageReceiverModalVisible = true; this.isManageReceiverModalAdd = true; } + onEditOneNoticeReceiver(receiver: NoticeReceiver) { this.receiver = receiver; this.isManageReceiverModalVisible = true; @@ -230,6 +343,7 @@ export class AlertNoticeComponent implements OnInit { onManageReceiverModalCancel() { this.isManageReceiverModalVisible = false; } + onManageReceiverModalOk() { this.isManageReceiverModalOkLoading = true; if (this.isManageReceiverModalAdd) { @@ -287,25 +401,22 @@ export class AlertNoticeComponent implements OnInit { } } - // start 新增或修改通知策略弹出框 - isManageRuleModalVisible: boolean = false; - isManageRuleModalAdd: boolean = true; - isManageRuleModalOkLoading: boolean = false; - rule!: NoticeRule; - receiversOption: any[] = []; - searchTag!: string; - tagsOption: any[] = []; - filterTags: string[] = []; - isLimit: boolean = false; - dayCheckOptions = [ - { label: this.i18nSvc.fanyi('common.week.7'), value: 7, checked: true }, - { label: this.i18nSvc.fanyi('common.week.1'), value: 1, checked: true }, - { label: this.i18nSvc.fanyi('common.week.2'), value: 2, checked: true }, - { label: this.i18nSvc.fanyi('common.week.3'), value: 3, checked: true }, - { label: this.i18nSvc.fanyi('common.week.4'), value: 4, checked: true }, - { label: this.i18nSvc.fanyi('common.week.5'), value: 5, checked: true }, - { label: this.i18nSvc.fanyi('common.week.6'), value: 6, checked: true } - ]; + onNewNoticeTemplate() { + this.template = new NoticeTemplate(); + this.isManageTemplateModalVisible = true; + this.isManageTemplateModalAdd = true; + } + + onEditOneNoticeTemplate(template: NoticeTemplate) { + this.template = template; + this.isManageTemplateModalVisible = true; + this.isManageTemplateModalAdd = false; + } + + onShowOneNoticeTemplate(template: NoticeTemplate) { + this.template = template; + this.isShowTemplateModalVisible = true; + } onNewNoticeRule() { this.rule = new NoticeRule(); @@ -321,9 +432,6 @@ export class AlertNoticeComponent implements OnInit { } else { this.isLimit = true; } - this.dayCheckOptions.forEach(item => { - item.checked = this.rule.days != undefined && this.rule.days.indexOf(item.value) >= 0; - }); this.isManageRuleModalVisible = true; this.isManageRuleModalAdd = false; this.receiversOption.push({ @@ -346,17 +454,28 @@ export class AlertNoticeComponent implements OnInit { } } + onNoticeRuleDaysChange(value: any[]) { + this.rule.days = value + .filter(item => item.checked == true) + .map(item => item.value) + .concat(); + } + onNoticeRuleLimitChange(limit: boolean) { if (!limit) { this.rule.days = this.dayCheckOptions.map(item => item.value).concat(); } else { this.rule.days = this.dayCheckOptions - .filter(item => item.checked) + .filter(item => item.checked == true) .map(item => item.value) .concat(); } } + loadReciverType(reciverId: number) { + return 5; + } + loadReceiversOption() { let receiverOption$ = this.noticeReceiverSvc.getReceivers().subscribe( message => { @@ -425,6 +544,74 @@ export class AlertNoticeComponent implements OnInit { ); } + loadTemplatesOption() { + let templateOption$ = this.noticeTemplateSvc.getNoticeTemplates().subscribe( + message => { + if (message.code === 0) { + let data = message.data; + this.templatesOption = []; + if (data != undefined) { + data.forEach(item => { + let label = `${item.name}-`; + switch (item.type) { + case 0: + label = `${label}Phone`; + break; + case 1: + label = `${label}Email`; + break; + case 2: + label = `${label}WebHook`; + break; + case 3: + label = `${label}WeChat`; + break; + case 4: + label = `${label}WeWork`; + break; + case 5: + label = `${label}DingDing`; + break; + case 6: + label = `${label}FeiShu`; + break; + case 7: + label = `${label}TelegramBot`; + break; + case 8: + label = `${label}SlackWebHook`; + break; + case 9: + label = `${label}Discord Bot`; + break; + case 10: + label = `${label}weChatApp`; + break; + case 11: + label = `${label}smn`; + break; + case 12: + label = `${label}ServerChan`; + break; + } + this.templatesOption.push({ + value: item.id, + label: label + }); + }); + } + } else { + console.warn(message.msg); + } + templateOption$.unsubscribe(); + }, + error => { + console.error(error.msg); + templateOption$.unsubscribe(); + } + ); + } + loadTagsOption() { let tagsInit$ = this.tagService.loadTags(this.searchTag, undefined, 0, 1000).subscribe( message => { @@ -473,6 +660,11 @@ export class AlertNoticeComponent implements OnInit { this.isManageRuleModalVisible = false; } + onManageTemplateModalCancel() { + this.isManageTemplateModalVisible = false; + this.isShowTemplateModalVisible = false; + } + updateNoticeRule(noticeRule: NoticeRule) { this.ruleTableLoading = true; const updateNoticeRule$ = this.noticeRuleSvc @@ -506,6 +698,12 @@ export class AlertNoticeComponent implements OnInit { this.rule.receiverName = option.label; } }); + // 加上templatemodel + this.templatesOption.forEach(option => { + if (option.value == this.rule.templateId) { + this.rule.templateName = option.label; + } + }); this.rule.tags = []; this.filterTags.forEach(tag => { let tmp: string[] = tag.split(':'); @@ -522,14 +720,6 @@ export class AlertNoticeComponent implements OnInit { if (this.rule.priorities != undefined) { this.rule.priorities = this.rule.priorities.filter(item => item != null && item != 9); } - if (this.isLimit) { - this.rule.days = this.dayCheckOptions - .filter(item => item.checked) - .map(item => item.value) - .concat(); - } else { - this.rule.days = this.dayCheckOptions.map(item => item.value).concat(); - } this.isManageRuleModalOkLoading = true; if (this.isManageRuleModalAdd) { const modalOk$ = this.noticeRuleSvc @@ -579,4 +769,56 @@ export class AlertNoticeComponent implements OnInit { ); } } + + onManageTemplateModalOk() { + this.isManageTemplateModalOkLoading = true; + if (this.isManageTemplateModalAdd) { + this.template.presetTemplate = false; + const modalOk$ = this.noticeTemplateSvc + .newNoticeTemplate(this.template) + .pipe( + finalize(() => { + modalOk$.unsubscribe(); + this.isManageTemplateModalOkLoading = false; + }) + ) + .subscribe( + message => { + if (message.code === 0) { + this.isManageTemplateModalVisible = false; + this.notifySvc.success(this.i18nSvc.fanyi('common.notify.new-success'), ''); + this.loadTemplatesTable(); + } else { + this.notifySvc.error(this.i18nSvc.fanyi('common.notify.new-fail'), message.msg); + } + }, + error => { + this.notifySvc.error(this.i18nSvc.fanyi('common.notify.new-fail'), error.msg); + } + ); + } else { + const modalOk$ = this.noticeTemplateSvc + .editNoticeTemplate(this.template) + .pipe( + finalize(() => { + modalOk$.unsubscribe(); + this.isManageTemplateModalOkLoading = false; + }) + ) + .subscribe( + message => { + if (message.code === 0) { + this.isManageTemplateModalVisible = false; + this.notifySvc.success(this.i18nSvc.fanyi('common.notify.edit-success'), ''); + this.loadTemplatesTable(); + } else { + this.notifySvc.error(this.i18nSvc.fanyi('common.notify.edit-fail'), message.msg); + } + }, + error => { + this.notifySvc.error(this.i18nSvc.fanyi('common.notify.edit-fail'), error.msg); + } + ); + } + } } diff --git a/web-app/src/app/service/notice-template.service.spec.ts b/web-app/src/app/service/notice-template.service.spec.ts new file mode 100644 index 00000000000..ca5fc74ca7b --- /dev/null +++ b/web-app/src/app/service/notice-template.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { NoticeTemplateService } from './notice-template.service'; + +describe('NoticeTemplateService', () => { + let service: NoticeTemplateService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(NoticeTemplateService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/web-app/src/app/service/notice-template.service.ts b/web-app/src/app/service/notice-template.service.ts new file mode 100644 index 00000000000..0365b050b8a --- /dev/null +++ b/web-app/src/app/service/notice-template.service.ts @@ -0,0 +1,37 @@ +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { List } from 'echarts'; +import { Observable } from 'rxjs'; + +import { Message } from '../pojo/Message'; +import { NoticeRule } from '../pojo/NoticeRule'; +import { NoticeTemplate } from '../pojo/NoticeTemplate'; + +const notice_template_uri = '/notice/template'; +const notice_templates_uri = '/notice/templates'; +const default_notice_templates_uri = '/notice/default_templates'; +@Injectable({ + providedIn: 'root' +}) +export class NoticeTemplateService { + constructor(private http: HttpClient) {} + + public newNoticeTemplate(body: NoticeTemplate): Observable> { + return this.http.post>(notice_template_uri, body); + } + + public editNoticeTemplate(body: NoticeTemplate): Observable> { + return this.http.put>(notice_template_uri, body); + } + + public deleteNoticeTemplate(templateId: number): Observable> { + return this.http.delete>(`${notice_template_uri}/${templateId}`); + } + + public getNoticeTemplates(): Observable> { + return this.http.get>(notice_templates_uri); + } + public getDefaultNoticeTemplates(): Observable> { + return this.http.get>(default_notice_templates_uri); + } +} diff --git a/web-app/src/assets/i18n/en-US.json b/web-app/src/assets/i18n/en-US.json index 922c9b8b380..2cb90be301c 100644 --- a/web-app/src/assets/i18n/en-US.json +++ b/web-app/src/assets/i18n/en-US.json @@ -222,6 +222,15 @@ "alert.help.setting.link":"https://hertzbeat.com/docs/help/alert_threshold", "alert.help.silence": "Alarm Silence management is used when you don’t want to be disturbed during system maintenance or on weekend nights.
Click \"New Silence Strategy\" and configure the time period to block messages so you would not get disturbed during weekends and breaks.", "alert.help.silence.link":"https://hertzbeat.com/docs", + "alert.notice.template": "Notice Template", + "alert.notice.template.new": "New Template", + "alert.notice.template.edit": "Edit Template", + "alert.notice.template.showExample": "View a template example", + "alert.notice.template.delete": "Delete Template", + "alert.notice.template.name": "Template Name", + "alert.notice.template.example": "Template Example", + "alert.notice.template.supplier": "Supplier Name", + "alert.notice.template.content": "Template Content", "alert.notice.receiver": "Message Receiver", "alert.notice.receiver.new": "New Receiver", "alert.notice.receiver.edit": "Edit Receiver", @@ -263,6 +272,18 @@ "alert.notice.type.smn-topicUrn": "TopicUrn", "alert.notice.type.serverchan": "ServerChan", "alert.notice.type.serverchan-token": "ServerChanToken", + "alert.applier.type.sms": "SMS", + "alert.applier.type.email": "Email", + "alert.applier.type.wechat": "WeChat", + "alert.applier.type.wework": "WeWork", + "alert.applier.type.ding": "DingDing", + "alert.applier.type.fei-shu": "FeiShu", + "alert.applier.type.telegram": "Telegram", + "alert.applier.type.slack": "Slack WebHook", + "alert.applier.type.discord": "Discord", + "alert.applier.type.weChatApp": "WeChatApp", + "alert.applier.type.smn": "HuaWei Cloud SMN", + "alert.applier.type.serverchan": "ServerChan", "alert.notice.rule": "Alert Notice Policy", "alert.notice.rule.new": "New Notice Policy", "alert.notice.rule.edit": "Edit Notice Policy", diff --git a/web-app/src/assets/i18n/zh-CN.json b/web-app/src/assets/i18n/zh-CN.json index 00b89f870bb..e65473ccefd 100644 --- a/web-app/src/assets/i18n/zh-CN.json +++ b/web-app/src/assets/i18n/zh-CN.json @@ -221,7 +221,16 @@ "alert.help.setting": "阈值规则用于监控指标告警阈值规则管理,点击“新增阈值”对监控指标进行告警阈值配置,系统将根据配置和采集指标数据计算触发告警。您也可以根据需要修改已有配置,如需进行阈值关联监控,请先关闭全局默认。
注意⚠\uFE0F: 配置完毕后,已经被成功触发的告警信息可以在【告警中心】中查看,您也可以在【消息通知】中设置告警信息的通知方式以及通知人员。", "alert.help.setting.link": "https://hertzbeat.com/zh-cn/docs/help/alert_threshold", "alert.help.silence": "告警静默管理用于您不想在系统维护期间或周末晚上受到打扰时,可以点击”新增静默策略“,设置指定时间段内屏蔽所有的告警通知。
告警静默规则支持一次性时间段或周期性时间段,支持标签匹配和告警级别匹配", - "alert.help.silence.link": "https://hertzbeat.com/zh-cn/docs/#%E5%91%8A%E8%AD%A6%E9%9D%99%E9%BB%98", + "alert.help.silence.link":"https://hertzbeat.com/zh-cn/docs/#%E5%91%8A%E8%AD%A6%E9%9D%99%E9%BB%98", + "alert.notice.template": "通知模板", + "alert.notice.template.new": "新增通知模板", + "alert.notice.template.edit": "编辑通知模板", + "alert.notice.template.showExample": "查看模板示例", + "alert.notice.template.delete": "删除通知模板", + "alert.notice.template.name": "模板名称", + "alert.notice.template.example": "模板示例", + "alert.notice.template.supplier": "供应商名称", + "alert.notice.template.content": "通知模板内容", "alert.notice.receiver": "消息接收人", "alert.notice.receiver.new": "新增接收人", "alert.notice.receiver.edit": "编辑接收人", @@ -258,6 +267,18 @@ "alert.notice.type.smn": "华为云SMN", "alert.notice.type.smn-ak": "AK", "alert.notice.type.smn-sk": "SK", + "alert.applier.type.sms": "短信", + "alert.applier.type.email": "邮箱", + "alert.applier.type.wechat": "微信公众号", + "alert.applier.type.wework": "企业微信", + "alert.applier.type.ding": "钉钉", + "alert.applier.type.fei-shu": "飞书", + "alert.applier.type.telegram": "Telegram", + "alert.applier.type.slack": "Slack WebHook", + "alert.applier.type.discord": "Discord", + "alert.applier.type.weChatApp": "企业微信应用", + "alert.applier.type.smn": "华为云SMN", + "alert.applier.type.serverchan": "Server酱(ServerChan)", "alert.notice.type.smn-projectId": "项目ID", "alert.notice.type.smn-region": "地域", "alert.notice.type.smn-topicUrn": "TopicUrn", diff --git a/web-app/src/assets/i18n/zh-TW.json b/web-app/src/assets/i18n/zh-TW.json index 59898f689b6..5b4ab4c6379 100644 --- a/web-app/src/assets/i18n/zh-TW.json +++ b/web-app/src/assets/i18n/zh-TW.json @@ -221,6 +221,15 @@ "alert.help.setting.link":"https://hertzbeat.com/zh-cn/docs/help/alert_threshold", "alert.help.silence": "告警靜默管理用於您不想在系統維護期間或週末晚上受到打擾時,可以點擊”新增靜默策略“,設定指定時間段內遮罩所有的告警通知,避免在週末或者晚上受到打擾。
告警靜默規則支持一次性時間段或週期性時間段,支持標籤匹配和告警級別匹配", "alert.help.silence.link":"https://hertzbeat.com/zh-cn/docs/#%E5%91%8A%E8%AD%A6%E9%9D%99%E9%BB%98", + "alert.notice.template": "通知模板", + "alert.notice.template.new": "新增通知模板", + "alert.notice.template.edit": "編輯通知模板", + "alert.notice.template.showExample": "查看模板實例", + "alert.notice.template.delete": "刪除通知模板", + "alert.notice.template.name": "模板名稱", + "alert.notice.template.example": "模板實例", + "alert.notice.template.supplier": "供應商名稱", + "alert.notice.template.content": "通知模板内容", "alert.notice.receiver": "消息接收人", "alert.notice.receiver.new": "新增接收人", "alert.notice.receiver.edit": "編輯接收人", @@ -262,6 +271,18 @@ "alert.notice.type.smn-topicUrn": "TopicUrn", "alert.notice.type.serverchan": "ServerChan", "alert.notice.type.serverchan-token": "ServerChanToken", + "alert.applier.type.sms": "短信", + "alert.applier.type.email": "郵箱", + "alert.applier.type.wechat": "微信公衆號", + "alert.applier.type.wework": "企業微信", + "alert.applier.type.ding": "釘釘", + "alert.applier.type.fei-shu": "飛書", + "alert.applier.type.telegram": "Telegram", + "alert.applier.type.slack": "Slack WebHook", + "alert.applier.type.discord": "Discord", + "alert.applier.type.weChatApp": "企業微信應用", + "alert.applier.type.smn": "華為雲SMN", + "alert.applier.type.serverchan": "ServerChan", "alert.notice.rule": "告警通知策略", "alert.notice.rule.new": "新增通知策略", "alert.notice.rule.edit": "編輯通知策略",