diff --git a/manager/src/main/java/com/usthe/manager/component/alerter/DispatcherAlarm.java b/manager/src/main/java/com/usthe/manager/component/alerter/DispatcherAlarm.java index 9067cf4a818..30df98a0f3f 100644 --- a/manager/src/main/java/com/usthe/manager/component/alerter/DispatcherAlarm.java +++ b/manager/src/main/java/com/usthe/manager/component/alerter/DispatcherAlarm.java @@ -53,6 +53,25 @@ public void afterPropertiesSet() throws Exception { } } + /** + * send alert msg to receiver + * @param receiver receiver + * @param alert alert msg + * @return send success or failed + */ + public boolean sendNoticeMsg(NoticeReceiver receiver, 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); + return true; + } + return false; + } + private List matchReceiverByNoticeRules(Alert alert) { // todo use cache 使用缓存 return noticeConfigService.getReceiverFilterRule(alert); @@ -82,13 +101,9 @@ private void sendNotify(Alert alert) { List receivers = matchReceiverByNoticeRules(alert); // todo Send notification here temporarily single thread 发送通知这里暂时单线程 for (NoticeReceiver receiver : receivers) { - byte type = receiver.getType(); - if (alertNotifyHandlerMap.containsKey(type)) { - alertNotifyHandlerMap.get(type).send(receiver, alert); - } - // 暂未支持的通知类型 + sendNoticeMsg(receiver, alert); } } - } + } diff --git a/manager/src/main/java/com/usthe/manager/component/alerter/impl/EmailAlertNotifyHandlerImpl.java b/manager/src/main/java/com/usthe/manager/component/alerter/impl/EmailAlertNotifyHandlerImpl.java index d68eef1a9b6..89e40cf1ba8 100644 --- a/manager/src/main/java/com/usthe/manager/component/alerter/impl/EmailAlertNotifyHandlerImpl.java +++ b/manager/src/main/java/com/usthe/manager/component/alerter/impl/EmailAlertNotifyHandlerImpl.java @@ -4,6 +4,7 @@ import com.usthe.common.entity.manager.NoticeReceiver; import com.usthe.manager.component.alerter.AlertNotifyHandler; import com.usthe.manager.service.MailService; +import com.usthe.manager.support.exception.AlertNoticeException; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; @@ -46,6 +47,7 @@ public void send(NoticeReceiver receiver, Alert alert) { javaMailSender.send(mimeMessage); } catch (Exception e) { log.error("[Email Alert] Exception,Exception information={}", e.getMessage()); + throw new AlertNoticeException("[Email Alert] failed: " + e.getMessage()); } } diff --git a/manager/src/main/java/com/usthe/manager/controller/NoticeConfigController.java b/manager/src/main/java/com/usthe/manager/controller/NoticeConfigController.java index 0d067494f6a..c3689066df2 100644 --- a/manager/src/main/java/com/usthe/manager/controller/NoticeConfigController.java +++ b/manager/src/main/java/com/usthe/manager/controller/NoticeConfigController.java @@ -136,4 +136,12 @@ public ResponseEntity>> getRules( return ResponseEntity.ok(message); } + + @PostMapping(path = "/receiver/send-test-msg") + @ApiOperation(value = "Send test msg to receiver", notes = "给指定接收人发送测试消息") + public ResponseEntity> sendTestMsg(@Valid @RequestBody NoticeReceiver noticeReceiver) { + boolean sendFlag = noticeConfigService.sendTestMsg(noticeReceiver); + return ResponseEntity.ok(new Message<>(sendFlag)); + } + } diff --git a/manager/src/main/java/com/usthe/manager/service/NoticeConfigService.java b/manager/src/main/java/com/usthe/manager/service/NoticeConfigService.java index 99db2c65a4b..2f3e9002005 100644 --- a/manager/src/main/java/com/usthe/manager/service/NoticeConfigService.java +++ b/manager/src/main/java/com/usthe/manager/service/NoticeConfigService.java @@ -108,4 +108,12 @@ public interface NoticeConfigService { * @return Notification Rule Entity 通知规则实体 */ NoticeRule getNoticeRulesById(Long ruleId); + + /** + * 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/com/usthe/manager/service/impl/MailServiceImpl.java b/manager/src/main/java/com/usthe/manager/service/impl/MailServiceImpl.java index 5cbaad5a5e8..c101de51ef6 100644 --- a/manager/src/main/java/com/usthe/manager/service/impl/MailServiceImpl.java +++ b/manager/src/main/java/com/usthe/manager/service/impl/MailServiceImpl.java @@ -31,8 +31,12 @@ public class MailServiceImpl implements MailService { @Override public String buildAlertHtmlTemplate(final Alert alert) { - String monitorId = alert.getTags().get(CommonConstants.TAG_MONITOR_ID); - String monitorName = alert.getTags().get(CommonConstants.TAG_MONITOR_NAME); + String monitorId = null; + String monitorName = null; + if (alert.getTags() != null) { + monitorId = alert.getTags().get(CommonConstants.TAG_MONITOR_ID); + monitorName = alert.getTags().get(CommonConstants.TAG_MONITOR_NAME); + } monitorId = monitorId == null? "External alarm, no ID" : monitorId; monitorName = monitorName == null? "External alarm, no Name" : monitorName; // Introduce thymeleaf context parameters to render pages diff --git a/manager/src/main/java/com/usthe/manager/service/impl/NoticeConfigServiceImpl.java b/manager/src/main/java/com/usthe/manager/service/impl/NoticeConfigServiceImpl.java index 604f15ea877..491fca8082d 100644 --- a/manager/src/main/java/com/usthe/manager/service/impl/NoticeConfigServiceImpl.java +++ b/manager/src/main/java/com/usthe/manager/service/impl/NoticeConfigServiceImpl.java @@ -3,6 +3,8 @@ import com.google.common.collect.MapDifference; import com.google.common.collect.Maps; import com.usthe.common.entity.alerter.Alert; +import com.usthe.common.util.CommonConstants; +import com.usthe.manager.component.alerter.DispatcherAlarm; import com.usthe.manager.dao.NoticeReceiverDao; import com.usthe.manager.dao.NoticeRuleDao; import com.usthe.common.entity.manager.NoticeReceiver; @@ -10,6 +12,7 @@ import com.usthe.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.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -30,12 +33,20 @@ @Slf4j public class NoticeConfigServiceImpl implements NoticeConfigService { + private static final String ALERT_TEST_TARGET = "Test Target"; + + private static final String ALERT_TEST_CONTENT = "test send msg! \n This is the test data. It is proved that it can be received successfully"; + @Autowired private NoticeReceiverDao noticeReceiverDao; @Autowired private NoticeRuleDao noticeRuleDao; + @Autowired + @Lazy + private DispatcherAlarm dispatcherAlarm; + @Override public List getNoticeReceivers(Specification specification) { return noticeReceiverDao.findAll(specification); @@ -50,6 +61,14 @@ public List getNoticeRules(Specification specification) public void addReceiver(NoticeReceiver noticeReceiver) { noticeReceiverDao.save(noticeReceiver); } + @Override + public boolean sendTestMsg(NoticeReceiver noticeReceiver) { + Alert alert = new Alert(); + alert.setContent(CommonConstants.TEST_SEND_MSG); + alert.setId(0L); + return dispatcherAlarm.sendNoticeMsg(noticeReceiver, alert); + } + @Override public void editReceiver(NoticeReceiver noticeReceiver) { @@ -115,4 +134,13 @@ public NoticeReceiver getReceiverById(Long receiverId) { public NoticeRule getNoticeRulesById(Long ruleId) { return noticeRuleDao.getOne(ruleId); } + + @Override + public boolean sendTestMsg(NoticeReceiver noticeReceiver) { + Alert alert = new Alert(); + alert.setTarget(ALERT_TEST_TARGET); + alert.setContent(ALERT_TEST_CONTENT); + alert.setPriority(CommonConstants.ALERT_PRIORITY_CODE_CRITICAL); + return dispatcherAlarm.sendNoticeMsg(noticeReceiver, alert); + } } diff --git a/manager/src/main/java/com/usthe/manager/support/GlobalExceptionHandler.java b/manager/src/main/java/com/usthe/manager/support/GlobalExceptionHandler.java index db23f1bb727..1442c8950f5 100644 --- a/manager/src/main/java/com/usthe/manager/support/GlobalExceptionHandler.java +++ b/manager/src/main/java/com/usthe/manager/support/GlobalExceptionHandler.java @@ -1,6 +1,7 @@ package com.usthe.manager.support; import com.usthe.common.entity.dto.Message; +import com.usthe.manager.support.exception.AlertNoticeException; import com.usthe.manager.support.exception.MonitorDatabaseException; import com.usthe.manager.support.exception.MonitorDetectException; import lombok.extern.slf4j.Slf4j; @@ -18,9 +19,7 @@ import java.lang.reflect.Field; -import static com.usthe.common.util.CommonConstants.DETECT_FAILED_CODE; -import static com.usthe.common.util.CommonConstants.MONITOR_CONFLICT_CODE; -import static com.usthe.common.util.CommonConstants.PARAM_INVALID_CODE; +import static com.usthe.common.util.CommonConstants.*; /** * controller exception handler @@ -82,6 +81,13 @@ ResponseEntity> handleIllegalArgumentException(IllegalArgumentExce return ResponseEntity.ok(message); } + @ExceptionHandler(AlertNoticeException.class) + @ResponseBody + ResponseEntity> handleAlertNoticeException(AlertNoticeException noticeException) { + Message message = Message.builder().msg(noticeException.getMessage()).code(FAIL_CODE).build(); + return ResponseEntity.ok(message); + } + /** * 处理请求参数错误的失败, 请求参数json映射body时出错 * @param exception 参数映射body异常 diff --git a/manager/src/main/java/com/usthe/manager/support/exception/AlertNoticeException.java b/manager/src/main/java/com/usthe/manager/support/exception/AlertNoticeException.java new file mode 100644 index 00000000000..b083fee31bd --- /dev/null +++ b/manager/src/main/java/com/usthe/manager/support/exception/AlertNoticeException.java @@ -0,0 +1,13 @@ +package com.usthe.manager.support.exception; + +/** + * alert notice send failed + * 告警通知发送异常 + * @author tom + * @date 2022/5/8 17:59 + */ +public class AlertNoticeException extends RuntimeException { + public AlertNoticeException(String message) { + super(message); + } +} 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 20580b8c8c8..c8d0568cd1a 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 @@ -285,6 +285,14 @@ + + + + + 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 cf6d6c5c6d7..5448695e47c 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 @@ -10,7 +10,6 @@ import { NoticeRule } from '../../../pojo/NoticeRule'; import { NoticeReceiverService } from '../../../service/notice-receiver.service'; import { NoticeRuleService } from '../../../service/notice-rule.service'; import { TagService } from '../../../service/tag.service'; -import { Tag } from '../../../pojo/Tag'; @Component({ selector: 'app-alert-notice', @@ -154,6 +153,7 @@ export class AlertNoticeComponent implements OnInit { isManageReceiverModalVisible: boolean = false; isManageReceiverModalAdd: boolean = true; isManageReceiverModalOkLoading: boolean = false; + isSendTestButtonLoading: boolean = false; receiver!: NoticeReceiver; onNewNoticeReceiver() { @@ -167,6 +167,32 @@ export class AlertNoticeComponent implements OnInit { this.isManageReceiverModalAdd = false; } + onSendAlertTestMsg() { + this.isSendTestButtonLoading = true; + const sendReq$ = this.noticeReceiverSvc + .sendAlertMsgToReceiver(this.receiver) + .pipe( + finalize(() => { + sendReq$.unsubscribe(); + this.isSendTestButtonLoading = false; + }) + ) + .subscribe( + message => { + if (message.code === 0) { + this.isSendTestButtonLoading = false; + this.notifySvc.success(this.i18nSvc.fanyi('alert.notice.send-test.notify.success'), ''); + } else { + this.notifySvc.error(this.i18nSvc.fanyi('alert.notice.send-test.notify.failed'), message.msg); + } + }, + error => { + this.isSendTestButtonLoading = false; + this.notifySvc.error(this.i18nSvc.fanyi('alert.notice.send-test.notify.failed'), error.msg); + } + ); + } + onManageReceiverModalCancel() { this.isManageReceiverModalVisible = false; } @@ -192,6 +218,7 @@ export class AlertNoticeComponent implements OnInit { } }, error => { + this.isManageReceiverModalVisible = false; this.notifySvc.error(this.i18nSvc.fanyi('common.notify.new-fail'), error.msg); } ); @@ -215,6 +242,7 @@ export class AlertNoticeComponent implements OnInit { } }, error => { + this.isManageReceiverModalVisible = false; this.notifySvc.error(this.i18nSvc.fanyi('common.notify.edit-fail'), error.msg); } ); diff --git a/web-app/src/app/service/notice-receiver.service.ts b/web-app/src/app/service/notice-receiver.service.ts index be928997499..9dbb8d353e6 100644 --- a/web-app/src/app/service/notice-receiver.service.ts +++ b/web-app/src/app/service/notice-receiver.service.ts @@ -7,6 +7,7 @@ import { NoticeReceiver } from '../pojo/NoticeReceiver'; const notice_receiver_uri = '/notice/receiver'; const notice_receivers_uri = '/notice/receivers'; +const notice_receiver_send_test_msg_uri = '/notice/receiver/send-test-msg'; @Injectable({ providedIn: 'root' @@ -21,6 +22,7 @@ export class NoticeReceiverService { public editReceiver(body: NoticeReceiver): Observable> { return this.http.put>(notice_receiver_uri, body); } + public deleteReceiver(receiverId: number): Observable> { return this.http.delete>(`${notice_receiver_uri}/${receiverId}`); } @@ -28,4 +30,8 @@ export class NoticeReceiverService { public getReceivers(): Observable> { return this.http.get>(notice_receivers_uri); } + + public sendAlertMsgToReceiver(body: NoticeReceiver): Observable> { + return this.http.post>(notice_receiver_send_test_msg_uri, body); + } } diff --git a/web-app/src/assets/i18n/en-US.json b/web-app/src/assets/i18n/en-US.json index b3ae69fb433..303e98c92bc 100644 --- a/web-app/src/assets/i18n/en-US.json +++ b/web-app/src/assets/i18n/en-US.json @@ -176,6 +176,9 @@ "alert.notice.rule.enable": "Enable", "alert.notice.rule.tag": "Tag Filter", "alert.notice.rule.priority": "Priority Filter", + "alert.notice.send-test": "Send Alert Test Msg", + "alert.notice.send-test.notify.success": "Send Alert Test Success!", + "alert.notice.send-test.notify.failed": "Send Alert Test Failed!", "dashboard.alerts.title": "Recently Alerts List", "dashboard.alerts.title-no": "Recently Pending Alerts", "dashboard.alerts.no": "No Pending Alerts", diff --git a/web-app/src/assets/i18n/zh-CN.json b/web-app/src/assets/i18n/zh-CN.json index 52c797abfcc..e5ede63bdac 100644 --- a/web-app/src/assets/i18n/zh-CN.json +++ b/web-app/src/assets/i18n/zh-CN.json @@ -176,6 +176,9 @@ "alert.notice.rule.enable": "是否启用", "alert.notice.rule.tag": "标签过滤", "alert.notice.rule.priority": "级别过滤", + "alert.notice.send-test": "发送告警测试", + "alert.notice.send-test.notify.success": "触发告警测试成功!", + "alert.notice.send-test.notify.failed": "触发告警测试失败!", "dashboard.alerts.title": "最近告警列表", "dashboard.alerts.title-no": "最近未处理告警", "dashboard.alerts.no": "暂无未处理告警", diff --git a/web-app/src/assets/i18n/zh-TW.json b/web-app/src/assets/i18n/zh-TW.json index 80a627aa03e..3eccf5eb0e2 100644 --- a/web-app/src/assets/i18n/zh-TW.json +++ b/web-app/src/assets/i18n/zh-TW.json @@ -176,6 +176,9 @@ "alert.notice.rule.enable": "是否啓用", "alert.notice.rule.tag": "標簽過濾", "alert.notice.rule.priority": "級別過濾", + "alert.notice.send-test": "發送告警測試", + "alert.notice.send-test.notify.success": "觸發告警測試成功!", + "alert.notice.send-test.notify.failed": "觸發告警測試失敗!", "dashboard.alerts.title": "最近告警列表", "dashboard.alerts.title-no": "最近未處理告警", "dashboard.alerts.no": "暫無未處理告警",