You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
375 lines
13 KiB
375 lines
13 KiB
/* |
|
* 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.apache.dolphinscheduler.alert.utils; |
|
|
|
import org.apache.dolphinscheduler.alert.template.AlertTemplate; |
|
import org.apache.dolphinscheduler.alert.template.AlertTemplateFactory; |
|
import org.apache.dolphinscheduler.common.enums.ShowType; |
|
import org.apache.dolphinscheduler.common.utils.CollectionUtils; |
|
import org.apache.dolphinscheduler.common.utils.StringUtils; |
|
|
|
import org.apache.commons.mail.EmailException; |
|
import org.apache.commons.mail.HtmlEmail; |
|
|
|
import java.io.File; |
|
import java.io.IOException; |
|
import java.util.Collection; |
|
import java.util.HashMap; |
|
import java.util.Map; |
|
import java.util.Properties; |
|
|
|
import javax.mail.Authenticator; |
|
import javax.mail.Message; |
|
import javax.mail.MessagingException; |
|
import javax.mail.PasswordAuthentication; |
|
import javax.mail.Session; |
|
import javax.mail.Transport; |
|
import javax.mail.internet.InternetAddress; |
|
import javax.mail.internet.MimeBodyPart; |
|
import javax.mail.internet.MimeMessage; |
|
import javax.mail.internet.MimeMultipart; |
|
import javax.mail.internet.MimeUtility; |
|
|
|
import org.slf4j.Logger; |
|
import org.slf4j.LoggerFactory; |
|
|
|
/** |
|
* mail utils |
|
*/ |
|
public class MailUtils { |
|
|
|
public static final Logger logger = LoggerFactory.getLogger(MailUtils.class); |
|
|
|
public static final String MAIL_PROTOCOL = PropertyUtils.getString(Constants.MAIL_PROTOCOL); |
|
|
|
public static final String MAIL_SERVER_HOST = PropertyUtils.getString(Constants.MAIL_SERVER_HOST); |
|
|
|
public static final Integer MAIL_SERVER_PORT = PropertyUtils.getInt(Constants.MAIL_SERVER_PORT); |
|
|
|
public static final String MAIL_SENDER = PropertyUtils.getString(Constants.MAIL_SENDER); |
|
|
|
public static final String MAIL_USER = PropertyUtils.getString(Constants.MAIL_USER); |
|
|
|
public static final String MAIL_PASSWD = PropertyUtils.getString(Constants.MAIL_PASSWD); |
|
|
|
public static final Boolean MAIL_USE_START_TLS = PropertyUtils.getBoolean(Constants.MAIL_SMTP_STARTTLS_ENABLE); |
|
|
|
public static final Boolean MAIL_USE_SSL = PropertyUtils.getBoolean(Constants.MAIL_SMTP_SSL_ENABLE); |
|
|
|
public static final String XLS_FILE_PATH = PropertyUtils.getString(Constants.XLS_FILE_PATH, "/tmp/xls"); |
|
|
|
public static final String STARTTLS_ENABLE = PropertyUtils.getString(Constants.MAIL_SMTP_STARTTLS_ENABLE); |
|
|
|
public static final Boolean SSL_ENABLE = PropertyUtils.getBoolean(Constants.MAIL_SMTP_SSL_ENABLE); |
|
|
|
public static final String SSL_TRUST = PropertyUtils.getString(Constants.MAIL_SMTP_SSL_TRUST); |
|
|
|
public static final AlertTemplate alertTemplate = AlertTemplateFactory.getMessageTemplate(); |
|
|
|
//Solve the problem of messy Chinese name in excel attachment |
|
static { |
|
System.setProperty("mail.mime.splitlongparameters", "false"); |
|
} |
|
|
|
private MailUtils() { |
|
throw new IllegalStateException(MailUtils.class.getName()); |
|
} |
|
|
|
/** |
|
* send mail to receivers |
|
* |
|
* @param receivers the receiver list |
|
* @param title the title |
|
* @param content the content |
|
* @param showType the show type |
|
* @return the result map |
|
*/ |
|
public static Map<String, Object> sendMails(Collection<String> receivers, String title, String content, String showType) { |
|
return sendMails(receivers, null, title, content, showType); |
|
} |
|
|
|
/** |
|
* send mail |
|
* |
|
* @param receivers the receiver list |
|
* @param receiversCc cc list |
|
* @param title the title |
|
* @param content the content |
|
* @param showType the show type |
|
* @return the send result |
|
*/ |
|
public static Map<String, Object> sendMails(Collection<String> receivers, Collection<String> receiversCc, String title, String content, String showType) { |
|
Map<String, Object> retMap = new HashMap<>(); |
|
retMap.put(Constants.STATUS, false); |
|
|
|
// if there is no receivers && no receiversCc, no need to process |
|
if (CollectionUtils.isEmpty(receivers) && CollectionUtils.isEmpty(receiversCc)) { |
|
return retMap; |
|
} |
|
|
|
receivers.removeIf(StringUtils::isEmpty); |
|
|
|
if (showType.equals(ShowType.TABLE.getDescp()) || showType.equals(ShowType.TEXT.getDescp())) { |
|
// send email |
|
HtmlEmail email = new HtmlEmail(); |
|
|
|
try { |
|
Session session = getSession(); |
|
email.setMailSession(session); |
|
email.setFrom(MAIL_SENDER); |
|
email.setCharset(Constants.UTF_8); |
|
if (CollectionUtils.isNotEmpty(receivers)) { |
|
// receivers mail |
|
for (String receiver : receivers) { |
|
email.addTo(receiver); |
|
} |
|
} |
|
|
|
if (CollectionUtils.isNotEmpty(receiversCc)) { |
|
//cc |
|
for (String receiverCc : receiversCc) { |
|
email.addCc(receiverCc); |
|
} |
|
} |
|
// sender mail |
|
return getStringObjectMap(title, content, showType, retMap, email); |
|
} catch (Exception e) { |
|
handleException(receivers, retMap, e); |
|
} |
|
} else if (showType.equals(ShowType.ATTACHMENT.getDescp()) || showType.equals(ShowType.TABLEATTACHMENT.getDescp())) { |
|
try { |
|
|
|
String partContent = (showType.equals(ShowType.ATTACHMENT.getDescp()) ? "Please see the attachment " + title + Constants.EXCEL_SUFFIX_XLS : htmlTable(content, false)); |
|
|
|
attachment(receivers, receiversCc, title, content, partContent); |
|
|
|
retMap.put(Constants.STATUS, true); |
|
return retMap; |
|
} catch (Exception e) { |
|
handleException(receivers, retMap, e); |
|
return retMap; |
|
} |
|
} |
|
return retMap; |
|
|
|
} |
|
|
|
/** |
|
* html table content |
|
* |
|
* @param content the content |
|
* @param showAll if show the whole content |
|
* @return the html table form |
|
*/ |
|
private static String htmlTable(String content, boolean showAll) { |
|
return alertTemplate.getMessageFromTemplate(content, ShowType.TABLE, showAll); |
|
} |
|
|
|
/** |
|
* html table content |
|
* |
|
* @param content the content |
|
* @return the html table form |
|
*/ |
|
private static String htmlTable(String content) { |
|
return htmlTable(content, true); |
|
} |
|
|
|
/** |
|
* html text content |
|
* |
|
* @param content the content |
|
* @return text in html form |
|
*/ |
|
private static String htmlText(String content) { |
|
return alertTemplate.getMessageFromTemplate(content, ShowType.TEXT); |
|
} |
|
|
|
/** |
|
* send mail as Excel attachment |
|
* |
|
* @param receivers the receiver list |
|
* @param title the title |
|
*/ |
|
private static void attachment(Collection<String> receivers, Collection<String> receiversCc, String title, String content, String partContent) throws Exception { |
|
MimeMessage msg = getMimeMessage(receivers); |
|
|
|
attachContent(receiversCc, title, content, partContent, msg); |
|
} |
|
|
|
/** |
|
* get MimeMessage |
|
* |
|
* @param receivers receivers |
|
* @return the MimeMessage |
|
*/ |
|
private static MimeMessage getMimeMessage(Collection<String> receivers) throws MessagingException { |
|
|
|
// 1. The first step in creating mail: creating session |
|
Session session = getSession(); |
|
// Setting debug mode, can be turned off |
|
session.setDebug(false); |
|
|
|
// 2. creating mail: Creating a MimeMessage |
|
MimeMessage msg = new MimeMessage(session); |
|
// 3. set sender |
|
msg.setFrom(new InternetAddress(MAIL_SENDER)); |
|
// 4. set receivers |
|
for (String receiver : receivers) { |
|
msg.addRecipients(Message.RecipientType.TO, InternetAddress.parse(receiver)); |
|
} |
|
return msg; |
|
} |
|
|
|
/** |
|
* get session |
|
* |
|
* @return the new Session |
|
*/ |
|
private static Session getSession() { |
|
Properties props = new Properties(); |
|
props.setProperty(Constants.MAIL_HOST, MAIL_SERVER_HOST); |
|
props.setProperty(Constants.MAIL_PORT, String.valueOf(MAIL_SERVER_PORT)); |
|
props.setProperty(Constants.MAIL_SMTP_AUTH, Constants.STRING_TRUE); |
|
props.setProperty(Constants.MAIL_TRANSPORT_PROTOCOL, MAIL_PROTOCOL); |
|
props.setProperty(Constants.MAIL_SMTP_STARTTLS_ENABLE, STARTTLS_ENABLE); |
|
if (Boolean.TRUE.equals(SSL_ENABLE)) { |
|
props.setProperty(Constants.MAIL_SMTP_SSL_ENABLE, "true"); |
|
props.setProperty(Constants.MAIL_SMTP_SSL_TRUST, SSL_TRUST); |
|
} |
|
|
|
Authenticator auth = new Authenticator() { |
|
@Override |
|
protected PasswordAuthentication getPasswordAuthentication() { |
|
// mail username and password |
|
return new PasswordAuthentication(MAIL_USER, MAIL_PASSWD); |
|
} |
|
}; |
|
|
|
return Session.getInstance(props, auth); |
|
} |
|
|
|
/** |
|
* attach content |
|
* |
|
* @param receiversCc the cc list |
|
* @param title the title |
|
* @param content the content |
|
* @param partContent the partContent |
|
* @param msg the message |
|
*/ |
|
private static void attachContent(Collection<String> receiversCc, String title, String content, String partContent, MimeMessage msg) throws MessagingException, IOException { |
|
/* |
|
* set receiverCc |
|
*/ |
|
if (CollectionUtils.isNotEmpty(receiversCc)) { |
|
for (String receiverCc : receiversCc) { |
|
msg.addRecipients(Message.RecipientType.CC, InternetAddress.parse(receiverCc)); |
|
} |
|
} |
|
|
|
// set subject |
|
msg.setSubject(title); |
|
MimeMultipart partList = new MimeMultipart(); |
|
// set signature |
|
MimeBodyPart part1 = new MimeBodyPart(); |
|
part1.setContent(partContent, Constants.TEXT_HTML_CHARSET_UTF_8); |
|
// set attach file |
|
MimeBodyPart part2 = new MimeBodyPart(); |
|
File file = new File(XLS_FILE_PATH + Constants.SINGLE_SLASH + title + Constants.EXCEL_SUFFIX_XLS); |
|
if (!file.getParentFile().exists()) { |
|
file.getParentFile().mkdirs(); |
|
} |
|
// make excel file |
|
|
|
ExcelUtils.genExcelFile(content, title, XLS_FILE_PATH); |
|
|
|
part2.attachFile(file); |
|
part2.setFileName(MimeUtility.encodeText(title + Constants.EXCEL_SUFFIX_XLS, Constants.UTF_8, "B")); |
|
// add components to collection |
|
partList.addBodyPart(part1); |
|
partList.addBodyPart(part2); |
|
msg.setContent(partList); |
|
// 5. send Transport |
|
Transport.send(msg); |
|
// 6. delete saved file |
|
deleteFile(file); |
|
} |
|
|
|
/** |
|
* the string object map |
|
* |
|
* @param title the title |
|
* @param content the content |
|
* @param showType the showType |
|
* @param retMap the result map |
|
* @param email the email |
|
* @return the result map |
|
*/ |
|
private static Map<String, Object> getStringObjectMap(String title, String content, String showType, Map<String, Object> retMap, HtmlEmail email) throws EmailException { |
|
|
|
/* |
|
* the subject of the message to be sent |
|
*/ |
|
email.setSubject(title); |
|
/* |
|
* to send information, you can use HTML tags in mail content because of the use of HtmlEmail |
|
*/ |
|
if (showType.equals(ShowType.TABLE.getDescp())) { |
|
email.setMsg(htmlTable(content)); |
|
} else if (showType.equals(ShowType.TEXT.getDescp())) { |
|
email.setMsg(htmlText(content)); |
|
} |
|
|
|
// send |
|
email.send(); |
|
|
|
retMap.put(Constants.STATUS, true); |
|
|
|
return retMap; |
|
} |
|
|
|
/** |
|
* file delete |
|
* |
|
* @param file the file to delete |
|
*/ |
|
public static void deleteFile(File file) { |
|
if (file.exists()) { |
|
if (file.delete()) { |
|
logger.info("delete success: {}", file.getAbsolutePath() + file.getName()); |
|
} else { |
|
logger.info("delete fail: {}", file.getAbsolutePath() + file.getName()); |
|
} |
|
} else { |
|
logger.info("file not exists: {}", file.getAbsolutePath() + file.getName()); |
|
} |
|
} |
|
|
|
/** |
|
* handle exception |
|
* |
|
* @param receivers the receiver list |
|
* @param retMap the result map |
|
* @param e the exception |
|
*/ |
|
private static void handleException(Collection<String> receivers, Map<String, Object> retMap, Exception e) { |
|
logger.error("Send email to {} failed", receivers, e); |
|
retMap.put(Constants.MESSAGE, "Send email to {" + String.join(",", receivers) + "} failed," + e.toString()); |
|
} |
|
}
|
|
|