From 309b122bbfc6d08d72ba5e3c3410b649d5e3955e Mon Sep 17 00:00:00 2001 From: baymax55 Date: Thu, 3 Nov 2022 16:00:57 +0800 Subject: [PATCH 1/4] feat: add email support for send msg when TP' CONFIG or ALARM are triggered --- hippo4j-message/pom.xml | 4 + .../message/config/MessageConfiguration.java | 6 + .../message/enums/NotifyPlatformEnum.java | 7 +- .../platform/EmailSendMessageHandler.java | 174 ++++++++++++++++++ .../constant/EmailAlarmConstants.java | 34 ++++ .../robot/dynamic-thread-pool/email-alarm.txt | 20 ++ .../dynamic-thread-pool/email-config.txt | 17 ++ pom.xml | 6 + 8 files changed, 267 insertions(+), 1 deletion(-) create mode 100644 hippo4j-message/src/main/java/cn/hippo4j/message/platform/EmailSendMessageHandler.java create mode 100644 hippo4j-message/src/main/java/cn/hippo4j/message/platform/constant/EmailAlarmConstants.java create mode 100644 hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/email-alarm.txt create mode 100644 hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/email-config.txt diff --git a/hippo4j-message/pom.xml b/hippo4j-message/pom.xml index 09fed8e6..3ee8b786 100644 --- a/hippo4j-message/pom.xml +++ b/hippo4j-message/pom.xml @@ -36,6 +36,10 @@ spring-boot-starter-test test + + com.sun.mail + javax.mail + diff --git a/hippo4j-message/src/main/java/cn/hippo4j/message/config/MessageConfiguration.java b/hippo4j-message/src/main/java/cn/hippo4j/message/config/MessageConfiguration.java index e495cfe4..63899819 100644 --- a/hippo4j-message/src/main/java/cn/hippo4j/message/config/MessageConfiguration.java +++ b/hippo4j-message/src/main/java/cn/hippo4j/message/config/MessageConfiguration.java @@ -19,6 +19,7 @@ package cn.hippo4j.message.config; import cn.hippo4j.message.api.NotifyConfigBuilder; import cn.hippo4j.message.platform.DingSendMessageHandler; +import cn.hippo4j.message.platform.EmailSendMessageHandler; import cn.hippo4j.message.platform.LarkSendMessageHandler; import cn.hippo4j.message.platform.WeChatSendMessageHandler; import cn.hippo4j.message.service.AlarmControlHandler; @@ -57,4 +58,9 @@ public class MessageConfiguration { public SendMessageHandler weChatSendMessageHandler() { return new WeChatSendMessageHandler(); } + + @Bean + public EmailSendMessageHandler emailSendMessageHandler() { + return new EmailSendMessageHandler(); + } } diff --git a/hippo4j-message/src/main/java/cn/hippo4j/message/enums/NotifyPlatformEnum.java b/hippo4j-message/src/main/java/cn/hippo4j/message/enums/NotifyPlatformEnum.java index 5ffbad3b..6faa4819 100644 --- a/hippo4j-message/src/main/java/cn/hippo4j/message/enums/NotifyPlatformEnum.java +++ b/hippo4j-message/src/main/java/cn/hippo4j/message/enums/NotifyPlatformEnum.java @@ -35,5 +35,10 @@ public enum NotifyPlatformEnum { /** * WECHAT */ - WECHAT + WECHAT, + + /** + * Email + */ + Email } diff --git a/hippo4j-message/src/main/java/cn/hippo4j/message/platform/EmailSendMessageHandler.java b/hippo4j-message/src/main/java/cn/hippo4j/message/platform/EmailSendMessageHandler.java new file mode 100644 index 00000000..89ea0861 --- /dev/null +++ b/hippo4j-message/src/main/java/cn/hippo4j/message/platform/EmailSendMessageHandler.java @@ -0,0 +1,174 @@ +/* + * 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 cn.hippo4j.message.platform; + +import cn.hippo4j.common.toolkit.Assert; +import cn.hippo4j.common.toolkit.FileUtil; +import cn.hippo4j.common.toolkit.JSONUtil; +import cn.hippo4j.common.toolkit.Singleton; +import cn.hippo4j.message.dto.NotifyConfigDTO; +import cn.hippo4j.message.enums.NotifyPlatformEnum; +import cn.hippo4j.message.platform.base.AbstractRobotSendMessageHandler; +import cn.hippo4j.message.platform.base.RobotMessageActualContent; +import cn.hippo4j.message.platform.base.RobotMessageExecuteDTO; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +import javax.mail.*; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeBodyPart; +import javax.mail.internet.MimeMessage; +import javax.mail.internet.MimeMultipart; +import java.nio.charset.Charset; +import java.util.*; + +import static cn.hippo4j.message.platform.constant.EmailAlarmConstants.Email_ALARM_TITLE; +import static cn.hippo4j.message.platform.constant.EmailAlarmConstants.Email_NOTICE_TITLE; + +/** + * Send Email notification message. + */ +@Slf4j +public class EmailSendMessageHandler extends AbstractRobotSendMessageHandler { + + @Override + public String getType() { + return NotifyPlatformEnum.Email.name(); + } + + @Override + protected RobotMessageActualContent buildMessageActualContent() { + String emailAlarmTxtKey = "message/robot/dynamic-thread-pool/email-alarm.txt"; + String emailConfigTxtKey = "message/robot/dynamic-thread-pool/email-config.txt"; + return RobotMessageActualContent.builder() + .receiveSeparator(", @") + .changeSeparator(" -> ") + .alarmMessageContent(Singleton.get(emailAlarmTxtKey, () -> FileUtil.readUtf8String(emailAlarmTxtKey))) + .configMessageContent(Singleton.get(emailConfigTxtKey, () -> FileUtil.readUtf8String(emailConfigTxtKey))) + .build(); + } + + @Override + protected void execute(RobotMessageExecuteDTO robotMessageExecuteDTO) { + + NotifyConfigDTO notifyConfig = robotMessageExecuteDTO.getNotifyConfig(); + String content = robotMessageExecuteDTO.getText(); + String receives = notifyConfig.getReceives(); + String secretKey = notifyConfig.getSecretKey(); + String[] recipients = receives.split(","); + + MailAccount mailAccount = JSONUtil.parseObject(secretKey, MailAccount.class); + Assert.isTrue(mailAccount != null, "mailAccount is null"); + mailAccount.setUser(mailAccount.getFrom()); + String subject = Objects.equals(notifyConfig.getType(), "CONFIG") ? Email_NOTICE_TITLE : Email_ALARM_TITLE; + try { + MimeMessage mimeMessage = buildMsg(mailAccount, recipients, subject, content); + Transport.send(mimeMessage); + } catch (Exception ex) { + log.error("Email failed to send message", ex); + } + } + + private MimeMessage buildMsg(MailAccount mailAccount, String[] recipients, String subject, String content) throws MessagingException { + + UserPassAuthenticator authenticator = new UserPassAuthenticator(mailAccount.getUser(), mailAccount.getPass()); + Properties properties = new Properties(); + properties.put("mail.transport.protocol", "smtp"); + properties.put("mail.smtp.host", mailAccount.getHost()); + properties.put("mail.smtp.port", mailAccount.getPort()); + properties.put("mail.smtp.auth", "true"); + Session session = Session.getInstance(properties, authenticator); + + MimeMessage msg = new MimeMessage(session); + // 发件人 + String from = mailAccount.getFrom(); + msg.setFrom(from); + // 标题 + msg.setSubject(subject); + // 发送时间 + msg.setSentDate(new Date()); + // 内容和附件 + MimeMultipart mimeMultipart = new MimeMultipart(); + MimeBodyPart body = new MimeBodyPart(); + body.setContent(content, "text/html; charset=" + Charset.defaultCharset()); + mimeMultipart.addBodyPart(body); + msg.setContent(mimeMultipart); + + // 收件人 + List
addressList = new ArrayList<>(recipients.length); + for (String recipient : recipients) { + Address to = new InternetAddress(recipient); + addressList.add(to); + } + Address[] addresses = addressList.toArray(new Address[0]); + msg.setRecipients(MimeMessage.RecipientType.TO, addresses); + return msg; + } + + @Data + private static class MailAccount { + + /** + * SMTP服务器域名 + */ + private String host; + /** + * SMTP服务端口 + */ + private Integer port; + /** + * 是否需要用户名密码验证 + */ + private Boolean auth; + /** + * 用户名 + */ + private String user; + /** + * 密码 + */ + private String pass; + + /** + * 发送方 + */ + private String from; + } + + private static class UserPassAuthenticator extends Authenticator { + + private final String user; + private final String pass; + + /** + * 构造 + * + * @param user 用户名 + * @param pass 密码 + */ + public UserPassAuthenticator(String user, String pass) { + this.user = user; + this.pass = pass; + } + + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(this.user, this.pass); + } + } +} \ No newline at end of file diff --git a/hippo4j-message/src/main/java/cn/hippo4j/message/platform/constant/EmailAlarmConstants.java b/hippo4j-message/src/main/java/cn/hippo4j/message/platform/constant/EmailAlarmConstants.java new file mode 100644 index 00000000..3daa24ac --- /dev/null +++ b/hippo4j-message/src/main/java/cn/hippo4j/message/platform/constant/EmailAlarmConstants.java @@ -0,0 +1,34 @@ +/* + * 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 cn.hippo4j.message.platform.constant; + +/** + * Email alarm constants. + */ +public class EmailAlarmConstants { + + /** + * Thread Pool Alert Notification Title + */ + public static final String Email_ALARM_TITLE = "动态线程池告警"; + + /** + * Thread pool parameter change notification title + */ + public static final String Email_NOTICE_TITLE = "动态线程池通知"; +} \ No newline at end of file diff --git a/hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/email-alarm.txt b/hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/email-alarm.txt new file mode 100644 index 00000000..9e1d4a7b --- /dev/null +++ b/hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/email-alarm.txt @@ -0,0 +1,20 @@ +[警报] %s - 动态线程池运行告警(%s)
+ 线程池ID:%s
+ 应用名称:%s
+ 应用实例:%s
+ 核心线程数:%s
+ 最大线程数:%s
+ 当前线程数:%s
+ 活跃线程数:%s
+ 同存最大线程数:%s
+ 线程池任务总量:%s
+ 队列类型:%s
+ 队列容量:%s
+ 队列元素个数:%s
+ 队列剩余个数:%s
+ 拒绝策略:%s
+ 拒绝策略执行次数:%s ${timout-content}
+ OWNER:<@%s>
+ 提示:%d 分钟内此线程池不会重复告警(可配置)
+ + 播报时间:%s \ No newline at end of file diff --git a/hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/email-config.txt b/hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/email-config.txt new file mode 100644 index 00000000..492a76e6 --- /dev/null +++ b/hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/email-config.txt @@ -0,0 +1,17 @@ +[通知] %s - 动态线程池参数变更
+ 线程池ID:%s
+ 应用名称:%s
+ 应用实例:%s
+ 核心线程数:%s
+ 最大线程数:%s
+ 核心线程超时:%s
+ 线程存活时间:%s
+ 执行超时时间:%s
+ 队列类型:%s
+ 队列容量:%s
+ AGO 拒绝策略:%s
+ NOW 拒绝策略:%s
+ OWNER:<@%s>
+ 提示:动态线程池配置变更实时通知(无限制)
+ + 播报时间:%s \ No newline at end of file diff --git a/pom.xml b/pom.xml index da53d543..cb9fff67 100644 --- a/pom.xml +++ b/pom.xml @@ -95,6 +95,7 @@ 3.0 2.22.1 3.1.0 + 1.6.2 @@ -126,6 +127,11 @@ netty-all ${netty.version} + + com.sun.mail + javax.mail + ${javax.mail.version} + From 0ecf204b9d5a3977d53951b22f63682333f1b7fc Mon Sep 17 00:00:00 2001 From: baymax55 Date: Thu, 3 Nov 2022 16:21:52 +0800 Subject: [PATCH 2/4] fix:use mail.transport.protocol form host --- .../cn/hippo4j/message/platform/EmailSendMessageHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hippo4j-message/src/main/java/cn/hippo4j/message/platform/EmailSendMessageHandler.java b/hippo4j-message/src/main/java/cn/hippo4j/message/platform/EmailSendMessageHandler.java index 89ea0861..a40e83b4 100644 --- a/hippo4j-message/src/main/java/cn/hippo4j/message/platform/EmailSendMessageHandler.java +++ b/hippo4j-message/src/main/java/cn/hippo4j/message/platform/EmailSendMessageHandler.java @@ -88,7 +88,7 @@ public class EmailSendMessageHandler extends AbstractRobotSendMessageHandler { UserPassAuthenticator authenticator = new UserPassAuthenticator(mailAccount.getUser(), mailAccount.getPass()); Properties properties = new Properties(); - properties.put("mail.transport.protocol", "smtp"); + properties.put("mail.transport.protocol", mailAccount.getHost().split("\\.")[0]); properties.put("mail.smtp.host", mailAccount.getHost()); properties.put("mail.smtp.port", mailAccount.getPort()); properties.put("mail.smtp.auth", "true"); From 3ef45f2b518c6024a789684220ec54b141b770ba Mon Sep 17 00:00:00 2001 From: baymax55 Date: Mon, 7 Nov 2022 16:47:05 +0800 Subject: [PATCH 3/4] fix:use spring-boot-starter-mail to send msg --- .../src/main/resources/application.properties | 17 ++ hippo4j-message/pom.xml | 9 +- .../message/enums/NotifyPlatformEnum.java | 4 +- .../platform/EmailSendMessageHandler.java | 197 +++++++----------- .../robot/dynamic-thread-pool/email-alarm.ftl | 27 +++ .../robot/dynamic-thread-pool/email-alarm.txt | 20 -- .../dynamic-thread-pool/email-config.ftl | 21 ++ .../dynamic-thread-pool/email-config.txt | 17 -- pom.xml | 8 +- 9 files changed, 152 insertions(+), 168 deletions(-) create mode 100644 hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/email-alarm.ftl delete mode 100644 hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/email-alarm.txt create mode 100644 hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/email-config.ftl delete mode 100644 hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/email-config.txt diff --git a/hippo4j-example/hippo4j-spring-boot-starter-example/src/main/resources/application.properties b/hippo4j-example/hippo4j-spring-boot-starter-example/src/main/resources/application.properties index 3d283f86..8d3ade56 100644 --- a/hippo4j-example/hippo4j-spring-boot-starter-example/src/main/resources/application.properties +++ b/hippo4j-example/hippo4j-spring-boot-starter-example/src/main/resources/application.properties @@ -24,3 +24,20 @@ spring.dynamic.thread-pool.monitor.collect-types=server,micrometer spring.dynamic.thread-pool.monitor.thread-pool-types=dynamic,web spring.dynamic.thread-pool.monitor.initial-delay=10000 spring.dynamic.thread-pool.monitor.collect-interval=5000 + +# for email notify +## simple example +spring.mail.host=smtp.qq.com +spring.mail.username=xxx@qq.com +spring.mail.password=xxx + +## for gmail need ssl +#spring.mail.host=smtp.gmail.com +#spring.mail.username=xxx@gmail.com +#spring.mail.password=xxx +#spring.mail.protocol=smtp +#spring.mail.properties.mail.smtp.auth=true +#spring.mail.properties.mail.smtp.port=465 +#spring.mail.properties.mail.smtp.starttls.enable=true +#spring.mail.properties.mail.smtp.starttls.required=true +#spring.mail.properties.mail.smtp.ssl.enable=true diff --git a/hippo4j-message/pom.xml b/hippo4j-message/pom.xml index 3ee8b786..f4e52c77 100644 --- a/hippo4j-message/pom.xml +++ b/hippo4j-message/pom.xml @@ -37,8 +37,12 @@ test - com.sun.mail - javax.mail + org.springframework.boot + spring-boot-starter-mail + + + org.freemarker + freemarker @@ -49,6 +53,7 @@ **/*.txt **/*.json + **/*.ftl diff --git a/hippo4j-message/src/main/java/cn/hippo4j/message/enums/NotifyPlatformEnum.java b/hippo4j-message/src/main/java/cn/hippo4j/message/enums/NotifyPlatformEnum.java index 6faa4819..0d5aa7c3 100644 --- a/hippo4j-message/src/main/java/cn/hippo4j/message/enums/NotifyPlatformEnum.java +++ b/hippo4j-message/src/main/java/cn/hippo4j/message/enums/NotifyPlatformEnum.java @@ -38,7 +38,7 @@ public enum NotifyPlatformEnum { WECHAT, /** - * Email + * EMAIL */ - Email + EMAIL } diff --git a/hippo4j-message/src/main/java/cn/hippo4j/message/platform/EmailSendMessageHandler.java b/hippo4j-message/src/main/java/cn/hippo4j/message/platform/EmailSendMessageHandler.java index a40e83b4..a7d3e003 100644 --- a/hippo4j-message/src/main/java/cn/hippo4j/message/platform/EmailSendMessageHandler.java +++ b/hippo4j-message/src/main/java/cn/hippo4j/message/platform/EmailSendMessageHandler.java @@ -17,158 +17,109 @@ package cn.hippo4j.message.platform; -import cn.hippo4j.common.toolkit.Assert; import cn.hippo4j.common.toolkit.FileUtil; -import cn.hippo4j.common.toolkit.JSONUtil; import cn.hippo4j.common.toolkit.Singleton; import cn.hippo4j.message.dto.NotifyConfigDTO; import cn.hippo4j.message.enums.NotifyPlatformEnum; -import cn.hippo4j.message.platform.base.AbstractRobotSendMessageHandler; -import cn.hippo4j.message.platform.base.RobotMessageActualContent; -import cn.hippo4j.message.platform.base.RobotMessageExecuteDTO; -import lombok.Data; +import cn.hippo4j.message.platform.constant.EmailAlarmConstants; +import cn.hippo4j.message.request.AlarmNotifyRequest; +import cn.hippo4j.message.request.ChangeParameterNotifyRequest; +import cn.hippo4j.message.service.SendMessageHandler; +import freemarker.cache.StringTemplateLoader; +import freemarker.template.Configuration; +import freemarker.template.Template; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.beanutils.BeanUtils; +import org.springframework.boot.autoconfigure.mail.MailProperties; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.MimeMessageHelper; -import javax.mail.*; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeBodyPart; +import javax.annotation.Resource; +import javax.mail.MessagingException; import javax.mail.internet.MimeMessage; -import javax.mail.internet.MimeMultipart; -import java.nio.charset.Charset; -import java.util.*; - -import static cn.hippo4j.message.platform.constant.EmailAlarmConstants.Email_ALARM_TITLE; -import static cn.hippo4j.message.platform.constant.EmailAlarmConstants.Email_NOTICE_TITLE; +import java.io.StringWriter; +import java.io.Writer; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Map; /** * Send Email notification message. */ @Slf4j -public class EmailSendMessageHandler extends AbstractRobotSendMessageHandler { +public class EmailSendMessageHandler implements SendMessageHandler { + + @Resource + private JavaMailSender emailSender; + + @Resource + MailProperties mailProperties; @Override public String getType() { - return NotifyPlatformEnum.Email.name(); + return NotifyPlatformEnum.EMAIL.name(); } @Override - protected RobotMessageActualContent buildMessageActualContent() { - String emailAlarmTxtKey = "message/robot/dynamic-thread-pool/email-alarm.txt"; - String emailConfigTxtKey = "message/robot/dynamic-thread-pool/email-config.txt"; - return RobotMessageActualContent.builder() - .receiveSeparator(", @") - .changeSeparator(" -> ") - .alarmMessageContent(Singleton.get(emailAlarmTxtKey, () -> FileUtil.readUtf8String(emailAlarmTxtKey))) - .configMessageContent(Singleton.get(emailConfigTxtKey, () -> FileUtil.readUtf8String(emailConfigTxtKey))) - .build(); + public void sendAlarmMessage(NotifyConfigDTO notifyConfig, AlarmNotifyRequest alarmNotifyRequest) { + try { + String emailAlarmTxtKey = "message/robot/dynamic-thread-pool/email-alarm.ftl"; + Map dataModel = getDataModel(alarmNotifyRequest); + dataModel.put("interval", notifyConfig.getInterval().toString()); + String emailAlarmTxt = Singleton.get(emailAlarmTxtKey, () -> FileUtil.readUtf8String(emailAlarmTxtKey)); + String renderedEmailAlarmTxt = render(dataModel, emailAlarmTxt); + String[] recipients = notifyConfig.getReceives().split(","); + execute(recipients, EmailAlarmConstants.Email_ALARM_TITLE, renderedEmailAlarmTxt); + } catch (Exception e) { + log.error("Email failed to send message", e); + } } @Override - protected void execute(RobotMessageExecuteDTO robotMessageExecuteDTO) { - - NotifyConfigDTO notifyConfig = robotMessageExecuteDTO.getNotifyConfig(); - String content = robotMessageExecuteDTO.getText(); - String receives = notifyConfig.getReceives(); - String secretKey = notifyConfig.getSecretKey(); - String[] recipients = receives.split(","); - - MailAccount mailAccount = JSONUtil.parseObject(secretKey, MailAccount.class); - Assert.isTrue(mailAccount != null, "mailAccount is null"); - mailAccount.setUser(mailAccount.getFrom()); - String subject = Objects.equals(notifyConfig.getType(), "CONFIG") ? Email_NOTICE_TITLE : Email_ALARM_TITLE; + public void sendChangeMessage(NotifyConfigDTO notifyConfig, ChangeParameterNotifyRequest changeParameterNotifyRequest) { try { - MimeMessage mimeMessage = buildMsg(mailAccount, recipients, subject, content); - Transport.send(mimeMessage); - } catch (Exception ex) { - log.error("Email failed to send message", ex); + String emailConfigTxtKey = "message/robot/dynamic-thread-pool/email-config.ftl"; + Map dataModel = getDataModel(changeParameterNotifyRequest); + String emailAlarmTxt = Singleton.get(emailConfigTxtKey, () -> FileUtil.readUtf8String(emailConfigTxtKey)); + String renderedEmailAlarmTxt = render(dataModel, emailAlarmTxt); + String[] recipients = notifyConfig.getReceives().split(","); + execute(recipients, EmailAlarmConstants.Email_NOTICE_TITLE, renderedEmailAlarmTxt); + } catch (Exception e) { + log.error("Email failed to send message", e); } } - private MimeMessage buildMsg(MailAccount mailAccount, String[] recipients, String subject, String content) throws MessagingException { - - UserPassAuthenticator authenticator = new UserPassAuthenticator(mailAccount.getUser(), mailAccount.getPass()); - Properties properties = new Properties(); - properties.put("mail.transport.protocol", mailAccount.getHost().split("\\.")[0]); - properties.put("mail.smtp.host", mailAccount.getHost()); - properties.put("mail.smtp.port", mailAccount.getPort()); - properties.put("mail.smtp.auth", "true"); - Session session = Session.getInstance(properties, authenticator); - - MimeMessage msg = new MimeMessage(session); - // 发件人 - String from = mailAccount.getFrom(); - msg.setFrom(from); - // 标题 - msg.setSubject(subject); - // 发送时间 - msg.setSentDate(new Date()); - // 内容和附件 - MimeMultipart mimeMultipart = new MimeMultipart(); - MimeBodyPart body = new MimeBodyPart(); - body.setContent(content, "text/html; charset=" + Charset.defaultCharset()); - mimeMultipart.addBodyPart(body); - msg.setContent(mimeMultipart); - - // 收件人 - List
addressList = new ArrayList<>(recipients.length); - for (String recipient : recipients) { - Address to = new InternetAddress(recipient); - addressList.add(to); + private String render(Map dataModel, String stringTemplate) { + Configuration cfg = new Configuration(Configuration.VERSION_2_3_31); + StringTemplateLoader stringLoader = new StringTemplateLoader(); + stringLoader.putTemplate("renderTemplate", stringTemplate); + cfg.setTemplateLoader(stringLoader); + Writer out = new StringWriter(2048); + try { + Template tpl = cfg.getTemplate("renderTemplate", "UTF-8"); + tpl.process(dataModel, out); + } catch (Exception e) { + log.error("failed to render template,dataModel:{},stringTemplate:{}", dataModel, stringTemplate); } - Address[] addresses = addressList.toArray(new Address[0]); - msg.setRecipients(MimeMessage.RecipientType.TO, addresses); - return msg; + return out.toString(); } - @Data - private static class MailAccount { - - /** - * SMTP服务器域名 - */ - private String host; - /** - * SMTP服务端口 - */ - private Integer port; - /** - * 是否需要用户名密码验证 - */ - private Boolean auth; - /** - * 用户名 - */ - private String user; - /** - * 密码 - */ - private String pass; - - /** - * 发送方 - */ - private String from; + @SneakyThrows + private Map getDataModel(Object bean) { + Map dataModel = BeanUtils.describe(bean); + dataModel.put("from", mailProperties.getUsername()); + dataModel.put("date", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + return dataModel; } - private static class UserPassAuthenticator extends Authenticator { - - private final String user; - private final String pass; - - /** - * 构造 - * - * @param user 用户名 - * @param pass 密码 - */ - public UserPassAuthenticator(String user, String pass) { - this.user = user; - this.pass = pass; - } - - @Override - protected PasswordAuthentication getPasswordAuthentication() { - return new PasswordAuthentication(this.user, this.pass); - } + private void execute(String[] to, String subject, String htmlBody) throws MessagingException { + MimeMessage message = emailSender.createMimeMessage(); + MimeMessageHelper helper = new MimeMessageHelper(message, "UTF-8"); + helper.setFrom(mailProperties.getUsername()); + helper.setTo(to); + helper.setSubject(subject); + helper.setText(htmlBody, true); + emailSender.send(message); } } \ No newline at end of file diff --git a/hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/email-alarm.ftl b/hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/email-alarm.ftl new file mode 100644 index 00000000..42a0c04d --- /dev/null +++ b/hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/email-alarm.ftl @@ -0,0 +1,27 @@ + +[警报] ${active} - 动态线程池运行告警(${notifyTypeEnum}) +
    +
  • 线程池ID:${threadPoolId}
  • +
  • 应用名称:${appName}
  • +
  • 应用实例:${identify}
  • +
  • 核心线程数:${corePoolSize}
  • +
  • 最大线程数:${maximumPoolSize}
  • +
  • 当前线程数:${poolSize}
  • +
  • 活跃线程数:${activeCount}
  • +
  • 同存最大线程数:${largestPoolSize}
  • +
  • 线程池任务总量:${completedTaskCount}
  • +
  • 队列类型:${queueName}
  • +
  • 队列容量:${capacity}
  • +
  • 队列元素个数:${queueSize}
  • +
  • 队列剩余个数:${remainingCapacity}
  • +
  • 拒绝策略:${rejectedExecutionHandlerName}
  • +
  • 拒绝策略执行次数:${rejectCountNum}
  • +
  • OWNER:${from}
  • +
  • 提示:${interval} 分钟内此线程池不会重复告警(可配置)
  • +
+ + 播报时间:${date} \ No newline at end of file diff --git a/hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/email-alarm.txt b/hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/email-alarm.txt deleted file mode 100644 index 9e1d4a7b..00000000 --- a/hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/email-alarm.txt +++ /dev/null @@ -1,20 +0,0 @@ -[警报] %s - 动态线程池运行告警(%s)
- 线程池ID:%s
- 应用名称:%s
- 应用实例:%s
- 核心线程数:%s
- 最大线程数:%s
- 当前线程数:%s
- 活跃线程数:%s
- 同存最大线程数:%s
- 线程池任务总量:%s
- 队列类型:%s
- 队列容量:%s
- 队列元素个数:%s
- 队列剩余个数:%s
- 拒绝策略:%s
- 拒绝策略执行次数:%s ${timout-content}
- OWNER:<@%s>
- 提示:%d 分钟内此线程池不会重复告警(可配置)
- - 播报时间:%s \ No newline at end of file diff --git a/hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/email-config.ftl b/hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/email-config.ftl new file mode 100644 index 00000000..3f6ad711 --- /dev/null +++ b/hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/email-config.ftl @@ -0,0 +1,21 @@ + +[通知] ${active} - 动态线程池参数变更 +
    +
  • 线程池ID:${threadPoolId}
  • +
  • 应用名称:${appName}
  • +
  • 应用实例:${identify}
  • +
  • 核心线程数:${beforeCorePoolSize} -> ${nowCorePoolSize}
  • +
  • 核心线程超时:${beforeMaximumPoolSize} -> ${nowMaximumPoolSize}
  • +
  • 线程存活时间:${beforeAllowsCoreThreadTimeOut} -> ${nowAllowsCoreThreadTimeOut}
  • +
  • 执行超时时间:${beforeKeepAliveTime} -> ${nowKeepAliveTime}
  • +
  • 队列类型:${blockingQueueName}
  • +
  • 队列容量:${beforeQueueCapacity} -> ${nowQueueCapacity}
  • +
  • AGO 拒绝策略:${beforeRejectedName}
  • +
  • NOW 拒绝策略:${nowRejectedName}
  • +
  • OWNER: ${from}
  • +
  • 提示:动态线程池配置变更实时通知(无限制)
  • +
+ + 播报时间:${date} diff --git a/hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/email-config.txt b/hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/email-config.txt deleted file mode 100644 index 492a76e6..00000000 --- a/hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/email-config.txt +++ /dev/null @@ -1,17 +0,0 @@ -[通知] %s - 动态线程池参数变更
- 线程池ID:%s
- 应用名称:%s
- 应用实例:%s
- 核心线程数:%s
- 最大线程数:%s
- 核心线程超时:%s
- 线程存活时间:%s
- 执行超时时间:%s
- 队列类型:%s
- 队列容量:%s
- AGO 拒绝策略:%s
- NOW 拒绝策略:%s
- OWNER:<@%s>
- 提示:动态线程池配置变更实时通知(无限制)
- - 播报时间:%s \ No newline at end of file diff --git a/pom.xml b/pom.xml index cb9fff67..7b1bca48 100644 --- a/pom.xml +++ b/pom.xml @@ -95,7 +95,7 @@ 3.0 2.22.1 3.1.0 - 1.6.2 + 2.3.31 @@ -128,9 +128,9 @@ ${netty.version} - com.sun.mail - javax.mail - ${javax.mail.version} + org.freemarker + freemarker + ${freemarker.version} From 8d069c941f00b056cfdb2da2fc3dbdc4a17de8be Mon Sep 17 00:00:00 2001 From: baymax55 Date: Mon, 14 Nov 2022 10:12:32 +0800 Subject: [PATCH 4/4] rename email msg subject --- .../message/platform/EmailSendMessageHandler.java | 10 ++++++---- .../platform/constant/EmailAlarmConstants.java | 4 ++-- .../robot/dynamic-thread-pool/email-alarm.ftl | 13 +++++++------ .../robot/dynamic-thread-pool/email-config.ftl | 9 ++++++--- 4 files changed, 21 insertions(+), 15 deletions(-) diff --git a/hippo4j-message/src/main/java/cn/hippo4j/message/platform/EmailSendMessageHandler.java b/hippo4j-message/src/main/java/cn/hippo4j/message/platform/EmailSendMessageHandler.java index a7d3e003..9edd3646 100644 --- a/hippo4j-message/src/main/java/cn/hippo4j/message/platform/EmailSendMessageHandler.java +++ b/hippo4j-message/src/main/java/cn/hippo4j/message/platform/EmailSendMessageHandler.java @@ -69,8 +69,9 @@ public class EmailSendMessageHandler implements SendMessageHandler FileUtil.readUtf8String(emailAlarmTxtKey)); String renderedEmailAlarmTxt = render(dataModel, emailAlarmTxt); + String alarmSubject = render(dataModel, EmailAlarmConstants.Email_ALARM_TITLE); String[] recipients = notifyConfig.getReceives().split(","); - execute(recipients, EmailAlarmConstants.Email_ALARM_TITLE, renderedEmailAlarmTxt); + execute(recipients, alarmSubject, renderedEmailAlarmTxt); } catch (Exception e) { log.error("Email failed to send message", e); } @@ -81,10 +82,11 @@ public class EmailSendMessageHandler implements SendMessageHandler dataModel = getDataModel(changeParameterNotifyRequest); - String emailAlarmTxt = Singleton.get(emailConfigTxtKey, () -> FileUtil.readUtf8String(emailConfigTxtKey)); - String renderedEmailAlarmTxt = render(dataModel, emailAlarmTxt); + String emailConfigTxt = Singleton.get(emailConfigTxtKey, () -> FileUtil.readUtf8String(emailConfigTxtKey)); + String renderedEmailConfigTxt = render(dataModel, emailConfigTxt); + String configSubject = render(dataModel, EmailAlarmConstants.Email_NOTICE_TITLE); String[] recipients = notifyConfig.getReceives().split(","); - execute(recipients, EmailAlarmConstants.Email_NOTICE_TITLE, renderedEmailAlarmTxt); + execute(recipients, configSubject, renderedEmailConfigTxt); } catch (Exception e) { log.error("Email failed to send message", e); } diff --git a/hippo4j-message/src/main/java/cn/hippo4j/message/platform/constant/EmailAlarmConstants.java b/hippo4j-message/src/main/java/cn/hippo4j/message/platform/constant/EmailAlarmConstants.java index 3daa24ac..b20c45dc 100644 --- a/hippo4j-message/src/main/java/cn/hippo4j/message/platform/constant/EmailAlarmConstants.java +++ b/hippo4j-message/src/main/java/cn/hippo4j/message/platform/constant/EmailAlarmConstants.java @@ -25,10 +25,10 @@ public class EmailAlarmConstants { /** * Thread Pool Alert Notification Title */ - public static final String Email_ALARM_TITLE = "动态线程池告警"; + public static String Email_ALARM_TITLE = "【Hippo4J】${active}-${threadPoolId} 线程池 ${notifyTypeEnum} 预警"; /** * Thread pool parameter change notification title */ - public static final String Email_NOTICE_TITLE = "动态线程池通知"; + public static String Email_NOTICE_TITLE = "【Hippo4J】${active}-${threadPoolId} 线程池参数变更通知"; } \ No newline at end of file diff --git a/hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/email-alarm.ftl b/hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/email-alarm.ftl index 42a0c04d..ef1fd737 100644 --- a/hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/email-alarm.ftl +++ b/hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/email-alarm.ftl @@ -1,8 +1,3 @@ - [警报] ${active} - 动态线程池运行告警(${notifyTypeEnum})
  • 线程池ID:${threadPoolId}
  • @@ -24,4 +19,10 @@
  • 提示:${interval} 分钟内此线程池不会重复告警(可配置)
- 播报时间:${date} \ No newline at end of file + 播报时间:${date} + + \ No newline at end of file diff --git a/hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/email-config.ftl b/hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/email-config.ftl index 3f6ad711..620b3305 100644 --- a/hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/email-config.ftl +++ b/hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/email-config.ftl @@ -1,6 +1,3 @@ - [通知] ${active} - 动态线程池参数变更
  • 线程池ID:${threadPoolId}
  • @@ -19,3 +16,9 @@
播报时间:${date} + +