fix:use spring-boot-starter-mail to send msg

pull/923/head
baymax55 3 years ago
parent 0ecf204b9d
commit 3ef45f2b51

@ -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

@ -37,8 +37,12 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
</dependency>
</dependencies>
@ -49,6 +53,7 @@
<includes>
<include>**/*.txt</include>
<include>**/*.json</include>
<include>**/*.ftl</include>
</includes>
</resource>
</resources>

@ -38,7 +38,7 @@ public enum NotifyPlatformEnum {
WECHAT,
/**
* Email
* EMAIL
*/
Email
EMAIL
}

@ -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<AlarmNotifyRequest, ChangeParameterNotifyRequest> {
@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<String, String> 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<String, String> 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<Address> addressList = new ArrayList<>(recipients.length);
for (String recipient : recipients) {
Address to = new InternetAddress(recipient);
addressList.add(to);
private String render(Map<String, String> 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<String, String> getDataModel(Object bean) {
Map<String, String> 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);
}
}

@ -0,0 +1,27 @@
<style>
li {
list-style-type: none;
}
</style>
<span style="color: rgb(255, 0, 0);">[警报] </span>${active} - 动态线程池运行告警(${notifyTypeEnum}
<ul>
<li>线程池ID<span style="color: rgb(160, 0, 0);">${threadPoolId}</span></li>
<li>应用名称:<span style="color: rgb(160, 0, 0);">${appName}</span></li>
<li>应用实例:${identify}</li>
<li>核心线程数:${corePoolSize}</li>
<li>最大线程数:${maximumPoolSize}</li>
<li>当前线程数:${poolSize}</li>
<li>活跃线程数:${activeCount}</li>
<li>同存最大线程数:${largestPoolSize}</li>
<li>线程池任务总量:${completedTaskCount}</li>
<li>队列类型:${queueName}</li>
<li>队列容量:${capacity}</li>
<li>队列元素个数:${queueSize}</li>
<li>队列剩余个数:${remainingCapacity}</li>
<li>拒绝策略:${rejectedExecutionHandlerName}</li>
<li>拒绝策略执行次数:<span style="color: #FF0000; ">${rejectCountNum}</li>
<li>OWNER${from}</li>
<li>提示:${interval} 分钟内此线程池不会重复告警(可配置)</li>
</ul>
<b> 播报时间:${date} </b>

@ -1,20 +0,0 @@
<font color='#FF0000'>[警报] </font>%s - 动态线程池运行告警(%s <br/>
线程池ID<font color='warning'>%s</font> <br/>
应用名称:<font color='warning'>%s</font> <br/>
应用实例:%s <br/>
核心线程数:%s <br/>
最大线程数:%s <br/>
当前线程数:%s <br/>
活跃线程数:%s <br/>
同存最大线程数:%s <br/>
线程池任务总量:%s <br/>
队列类型:%s <br/>
队列容量:%s <br/>
队列元素个数:%s <br/>
队列剩余个数:%s <br/>
拒绝策略:%s <br/>
拒绝策略执行次数:<font color='#FF0000'>%s</font> ${timout-content} <br/>
OWNER<@%s> <br/>
提示:%d 分钟内此线程池不会重复告警(可配置)<br/>
<b> 播报时间:%s </b>

@ -0,0 +1,21 @@
<style>
li{list-style-type:none;}
</style>
<span style="color: rgb(0, 240, 0); ">[通知] </span>${active} - 动态线程池参数变更
<ul>
<li>线程池ID<span style="color: rgb(160, 0, 0);">${threadPoolId}</span></li>
<li>应用名称:<span style="color: rgb(160, 0, 0);">${appName}</span></li>
<li>应用实例:${identify}</li>
<li>核心线程数:${beforeCorePoolSize} -> ${nowCorePoolSize}</li>
<li>核心线程超时:${beforeMaximumPoolSize} -> ${nowMaximumPoolSize}</li>
<li>线程存活时间:${beforeAllowsCoreThreadTimeOut} -> ${nowAllowsCoreThreadTimeOut}</li>
<li>执行超时时间:${beforeKeepAliveTime} -> ${nowKeepAliveTime}</li>
<li>队列类型:${blockingQueueName}</li>
<li>队列容量:${beforeQueueCapacity} -> ${nowQueueCapacity}</li>
<li>AGO 拒绝策略:${beforeRejectedName}</li>
<li>NOW 拒绝策略:${nowRejectedName}</li>
<li>OWNER ${from}</li>
<li>提示:动态线程池配置变更实时通知(无限制)</li>
</ul>
<b> 播报时间:${date} </b>

@ -1,17 +0,0 @@
<font color='info'>[通知] </font>%s - 动态线程池参数变更 <br/>
线程池ID<font color='warning'>%s</font> <br/>
应用名称:<font color='warning'>%s</font> <br/>
应用实例:%s <br/>
核心线程数:%s <br/>
最大线程数:%s <br/>
核心线程超时:%s <br/>
线程存活时间:%s <br/>
执行超时时间:%s <br/>
队列类型:%s <br/>
队列容量:%s <br/>
AGO 拒绝策略:%s <br/>
NOW 拒绝策略:%s <br/>
OWNER<@%s> <br/>
提示:动态线程池配置变更实时通知(无限制) <br/>
<b> 播报时间:%s </b>

@ -95,7 +95,7 @@
<license-maven-plugin.version>3.0</license-maven-plugin.version>
<spotless-maven-plugin.version>2.22.1</spotless-maven-plugin.version>
<maven-checkstyle-plugin.version>3.1.0</maven-checkstyle-plugin.version>
<javax.mail.version>1.6.2</javax.mail.version>
<freemarker.version>2.3.31</freemarker.version>
</properties>
<dependencyManagement>
@ -128,9 +128,9 @@
<version>${netty.version}</version>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>${javax.mail.version}</version>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>${freemarker.version}</version>
</dependency>
</dependencies>
</dependencyManagement>

Loading…
Cancel
Save