| /* |
| * |
| * Licensed 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.cloudstack.utils.mailing; |
| |
| import com.sun.mail.smtp.SMTPMessage; |
| import com.sun.mail.smtp.SMTPSSLTransport; |
| import com.sun.mail.smtp.SMTPTransport; |
| |
| import java.io.UnsupportedEncodingException; |
| |
| import java.util.Date; |
| import java.util.Map; |
| import java.util.Properties; |
| import java.util.Set; |
| import javax.mail.Authenticator; |
| import javax.mail.Message; |
| import javax.mail.MessagingException; |
| import javax.mail.PasswordAuthentication; |
| import javax.mail.Session; |
| import javax.mail.URLName; |
| import javax.mail.internet.InternetAddress; |
| |
| import org.apache.commons.collections.CollectionUtils; |
| import org.apache.commons.lang3.ArrayUtils; |
| import org.apache.commons.lang3.BooleanUtils; |
| import org.apache.commons.lang3.StringUtils; |
| import org.apache.commons.lang3.math.NumberUtils; |
| import org.apache.commons.mail.EmailConstants; |
| import org.apache.logging.log4j.Logger; |
| import org.apache.logging.log4j.LogManager; |
| |
| public class SMTPMailSender { |
| |
| protected Logger logger = LogManager.getLogger(SMTPMailSender.class); |
| |
| protected Session session = null; |
| protected SMTPSessionProperties sessionProps; |
| |
| protected static final String CONFIG_HOST = "host"; |
| protected static final String CONFIG_PORT = "port"; |
| protected static final String CONFIG_USE_AUTH = "useAuth"; |
| protected static final String CONFIG_USERNAME = "username"; |
| protected static final String CONFIG_PASSWORD = "password"; |
| protected static final String CONFIG_DEBUG_MODE = "debug"; |
| protected static final String CONFIG_USE_STARTTLS = "useStartTLS"; |
| protected static final String CONFIG_ENABLED_SECURITY_PROTOCOLS = "enabledSecurityProtocols"; |
| protected static final String CONFIG_TIMEOUT = "timeout"; |
| protected static final String CONFIG_CONNECTION_TIMEOUT = "connectiontimeout"; |
| |
| protected Map<String, String> configs; |
| protected String namespace; |
| |
| public SMTPMailSender(Map<String, String> configs, String namespace) { |
| |
| if (namespace == null) { |
| logger.error("Unable to configure SMTP session due to null namespace."); |
| return; |
| } |
| |
| this.configs = configs; |
| this.namespace = namespace; |
| this.sessionProps = configureSessionProperties(); |
| |
| if (StringUtils.isNotBlank(sessionProps.getHost())) { |
| Properties props = new Properties(); |
| |
| props.put(EmailConstants.MAIL_HOST, sessionProps.getHost()); |
| props.put(EmailConstants.MAIL_PORT, sessionProps.getPort()); |
| props.put(EmailConstants.MAIL_SMTP_AUTH, sessionProps.getUseAuth()); |
| |
| String username = sessionProps.getUsername(); |
| |
| if (username != null) { |
| props.put(EmailConstants.MAIL_SMTP_USER, username); |
| } |
| |
| String protocols = sessionProps.getEnabledSecurityProtocols(); |
| if (StringUtils.isNotBlank(protocols)) { |
| props.put("mail.smtp.ssl.protocols", protocols); |
| } |
| |
| if (sessionProps.getUseAuth()) { |
| props.put(EmailConstants.MAIL_TRANSPORT_STARTTLS_ENABLE, sessionProps.getUseStartTLS()); |
| } |
| |
| if (sessionProps.getTimeout() != null) { |
| props.put(EmailConstants.MAIL_SMTP_TIMEOUT, sessionProps.getTimeout()); |
| } |
| |
| if (sessionProps.getConnectionTimeout() != null) { |
| props.put(EmailConstants.MAIL_SMTP_CONNECTIONTIMEOUT, sessionProps.getConnectionTimeout()); |
| } |
| |
| String password = sessionProps.getPassword(); |
| if (StringUtils.isNotBlank(username) && StringUtils.isNotBlank(password)) { |
| session = Session.getInstance(props, new Authenticator() { |
| @Override |
| protected PasswordAuthentication getPasswordAuthentication() { |
| return new PasswordAuthentication(username, password); |
| } |
| }); |
| } else { |
| session = Session.getInstance(props); |
| } |
| |
| session.setDebug(sessionProps.getDebugMode()); |
| |
| } else { |
| logger.debug("Unable to instantiate SMTP mail session due to empty or null host."); |
| } |
| } |
| |
| protected String getConfig(String config) { |
| return this.configs.get(String.format("%s.%s", namespace, config)); |
| } |
| |
| protected SMTPSessionProperties configureSessionProperties() { |
| String host = getConfig(CONFIG_HOST); |
| String port = getConfig(CONFIG_PORT); |
| String useAuth = getConfig(CONFIG_USE_AUTH); |
| String username = getConfig(CONFIG_USERNAME); |
| String password = getConfig(CONFIG_PASSWORD); |
| String debugMode = getConfig(CONFIG_DEBUG_MODE); |
| String useStartTLS = getConfig(CONFIG_USE_STARTTLS); |
| String enabledSecurityProtocols = getConfig(CONFIG_ENABLED_SECURITY_PROTOCOLS); |
| String timeout = getConfig(CONFIG_TIMEOUT); |
| String connectionTimeout = getConfig(CONFIG_CONNECTION_TIMEOUT); |
| |
| SMTPSessionProperties sessionProps = new SMTPSessionProperties(); |
| |
| sessionProps.setHost(host); |
| sessionProps.setPort(NumberUtils.toInt(port, 25)); |
| sessionProps.setUseAuth(BooleanUtils.toBoolean(useAuth)); |
| sessionProps.setUsername(username); |
| sessionProps.setPassword(password); |
| sessionProps.setUseStartTLS(BooleanUtils.toBoolean(useStartTLS)); |
| sessionProps.setEnabledSecurityProtocols(enabledSecurityProtocols); |
| sessionProps.setDebugMode(BooleanUtils.toBoolean(debugMode)); |
| |
| sessionProps.setTimeout(timeout == null ? null : NumberUtils.toInt(timeout)); |
| sessionProps.setConnectionTimeout(connectionTimeout == null ? null : NumberUtils.toInt(connectionTimeout)); |
| |
| return sessionProps; |
| } |
| |
| public void sendMail(SMTPMailProperties mailProps) { |
| if (session == null) { |
| logger.error("Unable to send mail due to null session."); |
| return; |
| } |
| |
| try { |
| SMTPMessage message = createMessage(mailProps); |
| |
| if (ArrayUtils.isEmpty(message.getAllRecipients())) { |
| logger.error(String.format("Unable to send mail [%s] due to the recipient list of the message being empty.", |
| mailProps.getSubject())); |
| return; |
| } |
| |
| SMTPTransport smtpTrans = createSmtpTransport(); |
| |
| smtpTrans.connect(); |
| smtpTrans.sendMessage(message, message.getAllRecipients()); |
| smtpTrans.close(); |
| |
| } catch (MessagingException | UnsupportedEncodingException ex) { |
| logger.error(String.format("Unable to send mail [%s] to the recipcients [%s].", mailProps.getSubject(), mailProps.getRecipients().toString()), ex); |
| } |
| } |
| |
| protected SMTPMessage createMessage(SMTPMailProperties mailProps) throws MessagingException, UnsupportedEncodingException { |
| SMTPMessage message = new SMTPMessage(session); |
| |
| MailAddress sender = mailProps.getSender(); |
| MailAddress from = mailProps.getFrom(); |
| |
| if (from == null) { |
| from = sender; |
| } |
| |
| message.setSender(new InternetAddress(sender.getAddress(), sender.getPersonal())); |
| message.setFrom(new InternetAddress(from.getAddress(), from.getPersonal())); |
| |
| setMailRecipients(message, mailProps.getRecipients(), mailProps.getSubject()); |
| |
| message.setSubject(mailProps.getSubject()); |
| message.setSentDate(mailProps.getSentDate() != null ? mailProps.getSentDate() : new Date()); |
| message.setContent(mailProps.getContent(), mailProps.getContentType()); |
| message.saveChanges(); |
| return message; |
| } |
| |
| protected SMTPTransport createSmtpTransport() { |
| URLName urlName = new URLName("smtp", sessionProps.getHost(), sessionProps.getPort(), null, sessionProps.getUsername(), sessionProps.getPassword()); |
| |
| if (sessionProps.getUseAuth() && !sessionProps.getUseStartTLS()) { |
| return new SMTPSSLTransport(session, urlName); |
| } |
| |
| return new SMTPTransport(session, urlName); |
| } |
| |
| protected void setMailRecipients(SMTPMessage message, Set<MailAddress> recipients, String subject) throws UnsupportedEncodingException, MessagingException { |
| if (CollectionUtils.isEmpty(recipients)) { |
| logger.error("Unable to set recipients due to the recipient list being empty."); |
| return; |
| } |
| |
| for (MailAddress recipient : recipients) { |
| if (StringUtils.isNotBlank(recipient.getAddress())) { |
| try { |
| InternetAddress address = new InternetAddress(recipient.getAddress(), recipient.getPersonal()); |
| message.addRecipient(Message.RecipientType.TO, address); |
| } catch (MessagingException ex) { |
| logger.error(String.format("Unable to create InternetAddres for address [%s].", recipient), ex); |
| } |
| } |
| } |
| } |
| |
| } |