mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Unify SMTP mail sending (#4954)
* Add mail dependencies * Create util to send SMTP mail * Add unit tests to SMTP mail sender * Use SMTP mail util on quota alert * Use SMTP mail util on alert * Use SMTP mail util on project * Use SMTP mail util on usage alert * Remove copyright line in license header Co-authored-by: Gabriel Beims Bräscher <gabrascher@gmail.com> * Remove copyright line in license header Co-authored-by: Gabriel Beims Bräscher <gabrascher@gmail.com> * Remove copyright line in license header Co-authored-by: Gabriel Beims Bräscher <gabrascher@gmail.com> * Remove copyright line in license header Co-authored-by: Gabriel Beims Bräscher <gabrascher@gmail.com> * Remove copyright line in license header Co-authored-by: Gabriel Beims Bräscher <gabrascher@gmail.com> Co-authored-by: Daniel Augusto Veronezi Salvador <daniel@scclouds.com.br> Co-authored-by: Gabriel Beims Bräscher <gabrascher@gmail.com>
This commit is contained in:
parent
bf6266188c
commit
e962f0f271
@ -16,24 +16,15 @@
|
||||
//under the License.
|
||||
package org.apache.cloudstack.quota;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.inject.Inject;
|
||||
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 javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
@ -55,15 +46,14 @@ import com.cloud.user.AccountVO;
|
||||
import com.cloud.user.UserVO;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.user.dao.UserDao;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
import com.cloud.utils.db.TransactionLegacy;
|
||||
import com.google.common.base.Strings;
|
||||
import com.sun.mail.smtp.SMTPMessage;
|
||||
import com.sun.mail.smtp.SMTPSSLTransport;
|
||||
import com.sun.mail.smtp.SMTPTransport;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang.BooleanUtils;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import org.apache.cloudstack.utils.mailing.MailAddress;
|
||||
import org.apache.cloudstack.utils.mailing.SMTPMailProperties;
|
||||
import org.apache.cloudstack.utils.mailing.SMTPMailSender;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
|
||||
@Component
|
||||
public class QuotaAlertManagerImpl extends ManagerBase implements QuotaAlertManager {
|
||||
@ -84,8 +74,9 @@ public class QuotaAlertManagerImpl extends ManagerBase implements QuotaAlertMana
|
||||
@Inject
|
||||
private QuotaManager _quotaManager;
|
||||
|
||||
private EmailQuotaAlert _emailQuotaAlert;
|
||||
private boolean _lockAccountEnforcement = false;
|
||||
private String senderAddress;
|
||||
protected SMTPMailSender mailSender;
|
||||
|
||||
boolean _smtpDebug = false;
|
||||
|
||||
@ -109,19 +100,16 @@ public class QuotaAlertManagerImpl extends ManagerBase implements QuotaAlertMana
|
||||
mergeConfigs(configs, params);
|
||||
}
|
||||
|
||||
final String smtpHost = configs.get(QuotaConfig.QuotaSmtpHost.key());
|
||||
int smtpPort = NumbersUtil.parseInt(configs.get(QuotaConfig.QuotaSmtpPort.key()), 25);
|
||||
String useAuthStr = configs.get(QuotaConfig.QuotaSmtpAuthType.key());
|
||||
boolean useAuth = ((useAuthStr != null) && Boolean.parseBoolean(useAuthStr));
|
||||
senderAddress = configs.get(QuotaConfig.QuotaSmtpSender.key());
|
||||
_lockAccountEnforcement = BooleanUtils.toBoolean(configs.get(QuotaConfig.QuotaEnableEnforcement.key()));
|
||||
String smtpUsername = configs.get(QuotaConfig.QuotaSmtpUser.key());
|
||||
String smtpPassword = configs.get(QuotaConfig.QuotaSmtpPassword.key());
|
||||
String emailSender = configs.get(QuotaConfig.QuotaSmtpSender.key());
|
||||
String smtpEnabledSecurityProtocols = configs.get(QuotaConfig.QuotaSmtpEnabledSecurityProtocols.key());
|
||||
String useStartTLSStr = configs.get(QuotaConfig.QuotaSmtpUseStartTLS.key());
|
||||
boolean useStartTLS = BooleanUtils.toBoolean(useStartTLSStr);
|
||||
_lockAccountEnforcement = "true".equalsIgnoreCase(configs.get(QuotaConfig.QuotaEnableEnforcement.key()));
|
||||
|
||||
_emailQuotaAlert = new EmailQuotaAlert(smtpHost, smtpPort, useAuth, smtpUsername, smtpPassword, emailSender, smtpEnabledSecurityProtocols, useStartTLS, _smtpDebug);
|
||||
String namespace = "quota.usage.smtp";
|
||||
configs.put(String.format("%s.debug", namespace), String.valueOf(_smtpDebug));
|
||||
configs.put(String.format("%s.username", namespace), smtpUsername);
|
||||
|
||||
mailSender = new SMTPMailSender(configs, namespace);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -234,7 +222,7 @@ public class QuotaAlertManagerImpl extends ManagerBase implements QuotaAlertMana
|
||||
final String subject = templateEngine.replace(emailTemplate.getTemplateSubject());
|
||||
final String body = templateEngine.replace(emailTemplate.getTemplateBody());
|
||||
try {
|
||||
_emailQuotaAlert.sendQuotaAlert(emailRecipients, subject, body);
|
||||
sendQuotaAlert(emailRecipients, subject, body);
|
||||
emailToBeSent.sentSuccessfully(_quotaAcc);
|
||||
} catch (Exception e) {
|
||||
s_logger.error(String.format("Unable to send quota alert email (subject=%s; body=%s) to account %s (%s) recipients (%s) due to error (%s)", subject, body, account.getAccountName(),
|
||||
@ -337,99 +325,22 @@ public class QuotaAlertManagerImpl extends ManagerBase implements QuotaAlertMana
|
||||
}
|
||||
};
|
||||
|
||||
static class EmailQuotaAlert {
|
||||
private final Session _smtpSession;
|
||||
private final String _smtpHost;
|
||||
private final int _smtpPort;
|
||||
private final boolean _smtpUseAuth;
|
||||
private final String _smtpUsername;
|
||||
private final String _smtpPassword;
|
||||
private final String _emailSender;
|
||||
private final boolean smtpUseStartTLS;
|
||||
protected void sendQuotaAlert(List<String> emails, String subject, String body) {
|
||||
SMTPMailProperties mailProperties = new SMTPMailProperties();
|
||||
|
||||
public EmailQuotaAlert(String smtpHost, int smtpPort, boolean smtpUseAuth, final String smtpUsername, final String smtpPassword, String emailSender, String smtpEnabledSecurityProtocols, boolean smtpUseStartTLS, boolean smtpDebug) {
|
||||
_smtpHost = smtpHost;
|
||||
_smtpPort = smtpPort;
|
||||
_smtpUseAuth = smtpUseAuth;
|
||||
_smtpUsername = smtpUsername;
|
||||
_smtpPassword = smtpPassword;
|
||||
_emailSender = emailSender;
|
||||
this.smtpUseStartTLS = smtpUseStartTLS;
|
||||
mailProperties.setSender(new MailAddress(senderAddress));
|
||||
mailProperties.setSubject(subject);
|
||||
mailProperties.setContent(body);
|
||||
mailProperties.setContentType("text/html; charset=utf-8");
|
||||
|
||||
if (!Strings.isNullOrEmpty(_smtpHost)) {
|
||||
Properties smtpProps = new Properties();
|
||||
smtpProps.put("mail.smtp.host", smtpHost);
|
||||
smtpProps.put("mail.smtp.port", smtpPort);
|
||||
smtpProps.put("mail.smtp.auth", "" + smtpUseAuth);
|
||||
if (smtpUsername != null) {
|
||||
smtpProps.put("mail.smtp.user", smtpUsername);
|
||||
}
|
||||
|
||||
smtpProps.put("mail.smtps.host", smtpHost);
|
||||
smtpProps.put("mail.smtps.port", smtpPort);
|
||||
smtpProps.put("mail.smtps.auth", "" + smtpUseAuth);
|
||||
if (!Strings.isNullOrEmpty(smtpUsername)) {
|
||||
smtpProps.put("mail.smtps.user", smtpUsername);
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(smtpEnabledSecurityProtocols)) {
|
||||
smtpProps.put("mail.smtp.ssl.protocols", smtpEnabledSecurityProtocols);
|
||||
}
|
||||
|
||||
if (smtpUseAuth) {
|
||||
smtpProps.put("mail.smtp.starttls.enable", smtpUseStartTLS);
|
||||
}
|
||||
|
||||
if (!Strings.isNullOrEmpty(smtpUsername) && !Strings.isNullOrEmpty(smtpPassword)) {
|
||||
_smtpSession = Session.getInstance(smtpProps, new Authenticator() {
|
||||
@Override
|
||||
protected PasswordAuthentication getPasswordAuthentication() {
|
||||
return new PasswordAuthentication(smtpUsername, smtpPassword);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
_smtpSession = Session.getInstance(smtpProps);
|
||||
}
|
||||
_smtpSession.setDebug(smtpDebug);
|
||||
} else {
|
||||
_smtpSession = null;
|
||||
}
|
||||
Set<MailAddress> addresses = new HashSet<>();
|
||||
for (String email : emails) {
|
||||
addresses.add(new MailAddress(email));
|
||||
}
|
||||
|
||||
public void sendQuotaAlert(List<String> emails, String subject, String body) throws MessagingException, UnsupportedEncodingException {
|
||||
if (_smtpSession == null) {
|
||||
s_logger.error("Unable to create smtp session.");
|
||||
return;
|
||||
}
|
||||
SMTPMessage msg = new SMTPMessage(_smtpSession);
|
||||
msg.setSender(new InternetAddress(_emailSender, _emailSender));
|
||||
msg.setFrom(new InternetAddress(_emailSender, _emailSender));
|
||||
mailProperties.setRecipients(addresses);
|
||||
|
||||
for (String email : emails) {
|
||||
if (email != null && !email.isEmpty()) {
|
||||
try {
|
||||
InternetAddress address = new InternetAddress(email, email);
|
||||
msg.addRecipient(Message.RecipientType.TO, address);
|
||||
} catch (Exception pokemon) {
|
||||
s_logger.error("Exception in creating address for:" + email, pokemon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
msg.setSubject(subject);
|
||||
msg.setSentDate(new Date());
|
||||
msg.setContent(body, "text/html; charset=utf-8");
|
||||
msg.saveChanges();
|
||||
|
||||
SMTPTransport smtpTrans = null;
|
||||
if (_smtpUseAuth && !this.smtpUseStartTLS) {
|
||||
smtpTrans = new SMTPSSLTransport(_smtpSession, new URLName("smtp", _smtpHost, _smtpPort, null, _smtpUsername, _smtpPassword));
|
||||
} else {
|
||||
smtpTrans = new SMTPTransport(_smtpSession, new URLName("smtp", _smtpHost, _smtpPort, null, _smtpUsername, _smtpPassword));
|
||||
}
|
||||
smtpTrans.connect();
|
||||
smtpTrans.sendMessage(msg, msg.getAllRecipients());
|
||||
smtpTrans.close();
|
||||
}
|
||||
mailSender.sendMail(mailProperties);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -52,6 +52,8 @@ import com.cloud.user.dao.UserDao;
|
||||
import com.cloud.utils.db.TransactionLegacy;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.apache.cloudstack.utils.mailing.SMTPMailProperties;
|
||||
import org.apache.cloudstack.utils.mailing.SMTPMailSender;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class QuotaAlertManagerImplTest extends TestCase {
|
||||
@ -68,8 +70,6 @@ public class QuotaAlertManagerImplTest extends TestCase {
|
||||
private QuotaEmailTemplatesDao quotaEmailTemplateDao;
|
||||
@Mock
|
||||
private ConfigurationDao configDao;
|
||||
@Mock
|
||||
private QuotaAlertManagerImpl.EmailQuotaAlert emailQuotaAlert;
|
||||
|
||||
@Spy
|
||||
@InjectMocks
|
||||
@ -77,7 +77,6 @@ public class QuotaAlertManagerImplTest extends TestCase {
|
||||
|
||||
@Before
|
||||
public void setup() throws IllegalAccessException, NoSuchFieldException, ConfigurationException {
|
||||
// Dummy transaction stack setup
|
||||
TransactionLegacy.open("QuotaAlertManagerImplTest");
|
||||
}
|
||||
|
||||
@ -135,7 +134,8 @@ public class QuotaAlertManagerImplTest extends TestCase {
|
||||
quotaAccount.setQuotaAlertDate(null);
|
||||
quotaAccount.setQuotaEnforce(0);
|
||||
|
||||
QuotaAlertManagerImpl.DeferredQuotaEmail email = new QuotaAlertManagerImpl.DeferredQuotaEmail(account, quotaAccount, new BigDecimal(100), QuotaConfig.QuotaEmailTemplateTypes.QUOTA_LOW);
|
||||
QuotaAlertManagerImpl.DeferredQuotaEmail email = new QuotaAlertManagerImpl.DeferredQuotaEmail(account, quotaAccount, new BigDecimal(100),
|
||||
QuotaConfig.QuotaEmailTemplateTypes.QUOTA_LOW);
|
||||
|
||||
QuotaEmailTemplatesVO quotaEmailTemplatesVO = new QuotaEmailTemplatesVO();
|
||||
quotaEmailTemplatesVO.setTemplateSubject("Low quota");
|
||||
@ -156,9 +156,13 @@ public class QuotaAlertManagerImplTest extends TestCase {
|
||||
users.add(user);
|
||||
Mockito.when(userDao.listByAccount(Mockito.anyLong())).thenReturn(users);
|
||||
|
||||
quotaAlertManager.mailSender = Mockito.mock(SMTPMailSender.class);
|
||||
Mockito.when(quotaAlertManager.mailSender.sendMail(Mockito.anyObject())).thenReturn(Boolean.TRUE);
|
||||
|
||||
quotaAlertManager.sendQuotaAlert(email);
|
||||
assertTrue(email.getSendDate() != null);
|
||||
Mockito.verify(emailQuotaAlert, Mockito.times(1)).sendQuotaAlert(Mockito.anyListOf(String.class), Mockito.anyString(), Mockito.anyString());
|
||||
Mockito.verify(quotaAlertManager, Mockito.times(1)).sendQuotaAlert(Mockito.anyListOf(String.class), Mockito.anyString(), Mockito.anyString());
|
||||
Mockito.verify(quotaAlertManager.mailSender, Mockito.times(1)).sendMail(Mockito.any(SMTPMailProperties.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@ -23,20 +23,12 @@ import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Timer;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.mail.Authenticator;
|
||||
import javax.mail.Message.RecipientType;
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.PasswordAuthentication;
|
||||
import javax.mail.SendFailedException;
|
||||
import javax.mail.Session;
|
||||
import javax.mail.URLName;
|
||||
import javax.mail.internet.InternetAddress;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.cloudstack.framework.config.ConfigDepot;
|
||||
@ -78,13 +70,15 @@ import com.cloud.resource.ResourceManager;
|
||||
import com.cloud.service.ServiceOfferingVO;
|
||||
import com.cloud.service.dao.ServiceOfferingDao;
|
||||
import com.cloud.storage.StorageManager;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
import com.cloud.utils.concurrency.NamedThreadFactory;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.sun.mail.smtp.SMTPMessage;
|
||||
import com.sun.mail.smtp.SMTPSSLTransport;
|
||||
import com.sun.mail.smtp.SMTPTransport;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import org.apache.cloudstack.utils.mailing.MailAddress;
|
||||
import org.apache.cloudstack.utils.mailing.SMTPMailProperties;
|
||||
import org.apache.cloudstack.utils.mailing.SMTPMailSender;
|
||||
import org.apache.commons.lang3.math.NumberUtils;
|
||||
|
||||
public class AlertManagerImpl extends ManagerBase implements AlertManager, Configurable {
|
||||
private static final Logger s_logger = Logger.getLogger(AlertManagerImpl.class.getName());
|
||||
@ -94,7 +88,6 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
|
||||
private static final DecimalFormat DfPct = new DecimalFormat("###.##");
|
||||
private static final DecimalFormat DfWhole = new DecimalFormat("########");
|
||||
|
||||
private EmailAlert _emailAlert;
|
||||
@Inject
|
||||
private AlertDao _alertDao;
|
||||
@Inject
|
||||
@ -138,6 +131,10 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
|
||||
|
||||
private final ExecutorService _executor;
|
||||
|
||||
protected SMTPMailSender mailSender;
|
||||
protected String[] recipients = null;
|
||||
protected String senderAddress = null;
|
||||
|
||||
public AlertManagerImpl() {
|
||||
_executor = Executors.newCachedThreadPool(new NamedThreadFactory("Email-Alerts-Sender"));
|
||||
}
|
||||
@ -148,27 +145,23 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
|
||||
|
||||
// set up the email system for alerts
|
||||
String emailAddressList = configs.get("alert.email.addresses");
|
||||
String[] emailAddresses = null;
|
||||
if (emailAddressList != null) {
|
||||
emailAddresses = emailAddressList.split(",");
|
||||
recipients = emailAddressList.split(",");
|
||||
}
|
||||
|
||||
String smtpHost = configs.get("alert.smtp.host");
|
||||
int smtpPort = NumbersUtil.parseInt(configs.get("alert.smtp.port"), 25);
|
||||
String useAuthStr = configs.get("alert.smtp.useAuth");
|
||||
boolean useAuth = ((useAuthStr == null) ? false : Boolean.parseBoolean(useAuthStr));
|
||||
String smtpUsername = configs.get("alert.smtp.username");
|
||||
String smtpPassword = configs.get("alert.smtp.password");
|
||||
String emailSender = configs.get("alert.email.sender");
|
||||
String smtpDebugStr = configs.get("alert.smtp.debug");
|
||||
int smtpTimeout = NumbersUtil.parseInt(configs.get("alert.smtp.timeout"), 30000);
|
||||
int smtpConnectionTimeout = NumbersUtil.parseInt(configs.get("alert.smtp.connectiontimeout"), 30000);
|
||||
boolean smtpDebug = false;
|
||||
if (smtpDebugStr != null) {
|
||||
smtpDebug = Boolean.parseBoolean(smtpDebugStr);
|
||||
}
|
||||
senderAddress = configs.get("alert.email.sender");
|
||||
|
||||
_emailAlert = new EmailAlert(emailAddresses, smtpHost, smtpPort, smtpConnectionTimeout, smtpTimeout, useAuth, smtpUsername, smtpPassword, emailSender, smtpDebug);
|
||||
String namespace = "alert.smtp";
|
||||
String timeoutConfig = String.format("%s.timeout", namespace);
|
||||
String connectionTimeoutConfig = String.format("%s.connectiontimeout", namespace);
|
||||
|
||||
int smtpTimeout = NumberUtils.toInt(configs.get(timeoutConfig), 30000);
|
||||
int smtpConnectionTimeout = NumberUtils.toInt(configs.get(connectionTimeoutConfig), 30000);
|
||||
|
||||
configs.put(timeoutConfig, String.valueOf(smtpTimeout));
|
||||
configs.put(connectionTimeoutConfig, String.valueOf(smtpConnectionTimeout));
|
||||
|
||||
mailSender = new SMTPMailSender(configs, namespace);
|
||||
|
||||
String publicIPCapacityThreshold = _configDao.getValue(Config.PublicIpCapacityThreshold.key());
|
||||
String privateIPCapacityThreshold = _configDao.getValue(Config.PrivateIpCapacityThreshold.key());
|
||||
@ -231,9 +224,7 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
|
||||
@Override
|
||||
public void clearAlert(AlertType alertType, long dataCenterId, long podId) {
|
||||
try {
|
||||
if (_emailAlert != null) {
|
||||
_emailAlert.clearAlert(alertType.getType(), dataCenterId, podId);
|
||||
}
|
||||
clearAlert(alertType.getType(), dataCenterId, podId);
|
||||
} catch (Exception ex) {
|
||||
s_logger.error("Problem clearing email alert", ex);
|
||||
}
|
||||
@ -248,8 +239,8 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
|
||||
// TODO: queue up these messages and send them as one set of issues once a certain number of issues is reached? If that's the case,
|
||||
// shouldn't we have a type/severity as part of the API so that severe errors get sent right away?
|
||||
try {
|
||||
if (_emailAlert != null) {
|
||||
_emailAlert.sendAlert(alertType, dataCenterId, podId, null, subject, body);
|
||||
if (mailSender != null) {
|
||||
sendAlert(alertType, dataCenterId, podId, null, subject, body);
|
||||
} else {
|
||||
s_logger.warn("AlertType:: " + alertType + " | dataCenterId:: " + dataCenterId + " | podId:: " + podId +
|
||||
" | message:: " + subject + " | body:: " + body);
|
||||
@ -441,8 +432,7 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
|
||||
|
||||
recalculateCapacity();
|
||||
|
||||
// abort if we can't possibly send an alert...
|
||||
if (_emailAlert == null) {
|
||||
if (mailSender == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -642,7 +632,7 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
|
||||
s_logger.debug(msgSubject);
|
||||
s_logger.debug(msgContent);
|
||||
}
|
||||
_emailAlert.sendAlert(alertType, dc.getId(), podId, clusterId, msgSubject, msgContent);
|
||||
sendAlert(alertType, dc.getId(), podId, clusterId, msgSubject, msgContent);
|
||||
} catch (Exception ex) {
|
||||
s_logger.error("Exception in CapacityChecker", ex);
|
||||
}
|
||||
@ -679,170 +669,73 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
|
||||
|
||||
}
|
||||
|
||||
class EmailAlert {
|
||||
private Session _smtpSession;
|
||||
private InternetAddress[] _recipientList;
|
||||
private final String _smtpHost;
|
||||
private int _smtpPort = -1;
|
||||
private boolean _smtpUseAuth = false;
|
||||
private final String _smtpUsername;
|
||||
private final String _smtpPassword;
|
||||
private final String _emailSender;
|
||||
private int _smtpTimeout;
|
||||
private int _smtpConnectionTimeout;
|
||||
|
||||
public EmailAlert(String[] recipientList, String smtpHost, int smtpPort, int smtpConnectionTimeout, int smtpTimeout, boolean smtpUseAuth,
|
||||
final String smtpUsername,
|
||||
final String smtpPassword, String emailSender, boolean smtpDebug) {
|
||||
if (recipientList != null) {
|
||||
_recipientList = new InternetAddress[recipientList.length];
|
||||
for (int i = 0; i < recipientList.length; i++) {
|
||||
try {
|
||||
_recipientList[i] = new InternetAddress(recipientList[i], recipientList[i]);
|
||||
} catch (Exception ex) {
|
||||
s_logger.error("Exception creating address for: " + recipientList[i], ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_smtpHost = smtpHost;
|
||||
_smtpPort = smtpPort;
|
||||
_smtpUseAuth = smtpUseAuth;
|
||||
_smtpUsername = smtpUsername;
|
||||
_smtpPassword = smtpPassword;
|
||||
_emailSender = emailSender;
|
||||
_smtpTimeout = smtpTimeout;
|
||||
_smtpConnectionTimeout = smtpConnectionTimeout;
|
||||
|
||||
if (_smtpHost != null) {
|
||||
Properties smtpProps = new Properties();
|
||||
smtpProps.put("mail.smtp.host", smtpHost);
|
||||
smtpProps.put("mail.smtp.port", smtpPort);
|
||||
smtpProps.put("mail.smtp.auth", "" + smtpUseAuth);
|
||||
smtpProps.put("mail.smtp.timeout", _smtpTimeout);
|
||||
smtpProps.put("mail.smtp.connectiontimeout", _smtpConnectionTimeout);
|
||||
|
||||
if (smtpUsername != null) {
|
||||
smtpProps.put("mail.smtp.user", smtpUsername);
|
||||
}
|
||||
|
||||
smtpProps.put("mail.smtps.host", smtpHost);
|
||||
smtpProps.put("mail.smtps.port", smtpPort);
|
||||
smtpProps.put("mail.smtps.auth", "" + smtpUseAuth);
|
||||
smtpProps.put("mail.smtps.timeout", _smtpTimeout);
|
||||
smtpProps.put("mail.smtps.connectiontimeout", _smtpConnectionTimeout);
|
||||
|
||||
if (smtpUsername != null) {
|
||||
smtpProps.put("mail.smtps.user", smtpUsername);
|
||||
}
|
||||
|
||||
if ((smtpUsername != null) && (smtpPassword != null)) {
|
||||
_smtpSession = Session.getInstance(smtpProps, new Authenticator() {
|
||||
@Override
|
||||
protected PasswordAuthentication getPasswordAuthentication() {
|
||||
return new PasswordAuthentication(smtpUsername, smtpPassword);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
_smtpSession = Session.getInstance(smtpProps);
|
||||
}
|
||||
_smtpSession.setDebug(smtpDebug);
|
||||
} else {
|
||||
_smtpSession = null;
|
||||
public void clearAlert(short alertType, long dataCenterId, Long podId) {
|
||||
if (alertType != -1) {
|
||||
AlertVO alert = _alertDao.getLastAlert(alertType, dataCenterId, podId, null);
|
||||
if (alert != null) {
|
||||
AlertVO updatedAlert = _alertDao.createForUpdate();
|
||||
updatedAlert.setResolved(new Date());
|
||||
_alertDao.update(alert.getId(), updatedAlert);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: make sure this handles SSL transport (useAuth is true) and regular
|
||||
public void sendAlert(AlertType alertType, long dataCenterId, Long podId, Long clusterId, String subject, String content) throws MessagingException,
|
||||
UnsupportedEncodingException {
|
||||
s_logger.warn("AlertType:: " + alertType + " | dataCenterId:: " + dataCenterId + " | podId:: " +
|
||||
podId + " | clusterId:: " + clusterId + " | message:: " + subject);
|
||||
AlertVO alert = null;
|
||||
if ((alertType != AlertManager.AlertType.ALERT_TYPE_HOST) &&
|
||||
(alertType != AlertManager.AlertType.ALERT_TYPE_USERVM) &&
|
||||
(alertType != AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER) &&
|
||||
(alertType != AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY) &&
|
||||
(alertType != AlertManager.AlertType.ALERT_TYPE_SSVM) &&
|
||||
(alertType != AlertManager.AlertType.ALERT_TYPE_STORAGE_MISC) &&
|
||||
(alertType != AlertManager.AlertType.ALERT_TYPE_MANAGMENT_NODE) &&
|
||||
(alertType != AlertManager.AlertType.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED) &&
|
||||
(alertType != AlertManager.AlertType.ALERT_TYPE_UPLOAD_FAILED) &&
|
||||
(alertType != AlertManager.AlertType.ALERT_TYPE_OOBM_AUTH_ERROR) &&
|
||||
(alertType != AlertManager.AlertType.ALERT_TYPE_HA_ACTION) &&
|
||||
(alertType != AlertManager.AlertType.ALERT_TYPE_CA_CERT) &&
|
||||
(alertType != AlertManager.AlertType.ALERT_TYPE_VM_SNAPSHOT)) {
|
||||
alert = _alertDao.getLastAlert(alertType.getType(), dataCenterId, podId, clusterId);
|
||||
}
|
||||
public void sendAlert(AlertType alertType, long dataCenterId, Long podId, Long clusterId, String subject, String content)
|
||||
throws MessagingException, UnsupportedEncodingException {
|
||||
s_logger.warn(String.format("alertType=[%s] dataCenterId=[%s] podId=[%s] clusterId=[%s] message=[%s].", alertType, dataCenterId, podId, clusterId, subject));
|
||||
AlertVO alert = null;
|
||||
if ((alertType != AlertManager.AlertType.ALERT_TYPE_HOST) && (alertType != AlertManager.AlertType.ALERT_TYPE_USERVM)
|
||||
&& (alertType != AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER) && (alertType != AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY)
|
||||
&& (alertType != AlertManager.AlertType.ALERT_TYPE_SSVM) && (alertType != AlertManager.AlertType.ALERT_TYPE_STORAGE_MISC)
|
||||
&& (alertType != AlertManager.AlertType.ALERT_TYPE_MANAGMENT_NODE) && (alertType != AlertManager.AlertType.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED)
|
||||
&& (alertType != AlertManager.AlertType.ALERT_TYPE_UPLOAD_FAILED) && (alertType != AlertManager.AlertType.ALERT_TYPE_OOBM_AUTH_ERROR)
|
||||
&& (alertType != AlertManager.AlertType.ALERT_TYPE_HA_ACTION) && (alertType != AlertManager.AlertType.ALERT_TYPE_CA_CERT)) {
|
||||
alert = _alertDao.getLastAlert(alertType.getType(), dataCenterId, podId, clusterId);
|
||||
}
|
||||
|
||||
if (alert == null) {
|
||||
// set up a new alert
|
||||
AlertVO newAlert = new AlertVO();
|
||||
newAlert.setType(alertType.getType());
|
||||
newAlert.setSubject(subject);
|
||||
newAlert.setContent(content);
|
||||
newAlert.setClusterId(clusterId);
|
||||
newAlert.setPodId(podId);
|
||||
newAlert.setDataCenterId(dataCenterId);
|
||||
newAlert.setSentCount(1); // Initialize sent count to 1 since we are now sending an alert.
|
||||
newAlert.setLastSent(new Date());
|
||||
newAlert.setName(alertType.getName());
|
||||
_alertDao.persist(newAlert);
|
||||
} else {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
if (alert == null) {
|
||||
AlertVO newAlert = new AlertVO();
|
||||
newAlert.setType(alertType.getType());
|
||||
newAlert.setSubject(subject);
|
||||
newAlert.setContent(content);
|
||||
newAlert.setClusterId(clusterId);
|
||||
newAlert.setPodId(podId);
|
||||
newAlert.setDataCenterId(dataCenterId);
|
||||
newAlert.setSentCount(1);
|
||||
newAlert.setLastSent(new Date());
|
||||
newAlert.setName(alertType.getName());
|
||||
_alertDao.persist(newAlert);
|
||||
} else {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Have already sent: " + alert.getSentCount() + " emails for alert type '" + alertType + "' -- skipping send email");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (_smtpSession != null) {
|
||||
SMTPMessage msg = new SMTPMessage(_smtpSession);
|
||||
msg.setSender(new InternetAddress(_emailSender, _emailSender));
|
||||
msg.setFrom(new InternetAddress(_emailSender, _emailSender));
|
||||
for (InternetAddress address : _recipientList) {
|
||||
msg.addRecipient(RecipientType.TO, address);
|
||||
}
|
||||
msg.setSubject(subject);
|
||||
msg.setSentDate(new Date());
|
||||
msg.setContent(content, "text/plain");
|
||||
msg.saveChanges();
|
||||
|
||||
SMTPTransport smtpTrans = null;
|
||||
if (_smtpUseAuth) {
|
||||
smtpTrans = new SMTPSSLTransport(_smtpSession, new URLName("smtp", _smtpHost, _smtpPort, null, _smtpUsername, _smtpPassword));
|
||||
} else {
|
||||
smtpTrans = new SMTPTransport(_smtpSession, new URLName("smtp", _smtpHost, _smtpPort, null, _smtpUsername, _smtpPassword));
|
||||
}
|
||||
sendMessage(smtpTrans, msg);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
private void sendMessage(final SMTPTransport smtpTrans, final SMTPMessage msg) {
|
||||
_executor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
smtpTrans.connect();
|
||||
smtpTrans.sendMessage(msg, msg.getAllRecipients());
|
||||
smtpTrans.close();
|
||||
} catch (SendFailedException e) {
|
||||
s_logger.error(" Failed to send email alert " + e);
|
||||
} catch (MessagingException e) {
|
||||
s_logger.error(" Failed to send email alert " + e);
|
||||
}
|
||||
}
|
||||
});
|
||||
SMTPMailProperties mailProps = new SMTPMailProperties();
|
||||
mailProps.setSender(new MailAddress(senderAddress));
|
||||
mailProps.setSubject(subject);
|
||||
mailProps.setContent(content);
|
||||
mailProps.setContentType("text/plain");
|
||||
|
||||
Set<MailAddress> addresses = new HashSet<>();
|
||||
for (String recipient : recipients) {
|
||||
addresses.add(new MailAddress(recipient));
|
||||
}
|
||||
|
||||
public void clearAlert(short alertType, long dataCenterId, Long podId) {
|
||||
if (alertType != -1) {
|
||||
AlertVO alert = _alertDao.getLastAlert(alertType, dataCenterId, podId, null);
|
||||
if (alert != null) {
|
||||
AlertVO updatedAlert = _alertDao.createForUpdate();
|
||||
updatedAlert.setResolved(new Date());
|
||||
_alertDao.update(alert.getId(), updatedAlert);
|
||||
}
|
||||
mailProps.setRecipients(addresses);
|
||||
|
||||
sendMessage(mailProps);
|
||||
|
||||
}
|
||||
|
||||
private void sendMessage(SMTPMailProperties mailProps) {
|
||||
_executor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mailSender.sendMail(mailProps);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static String formatPercent(double percentage) {
|
||||
|
||||
@ -17,11 +17,9 @@
|
||||
package com.cloud.projects;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
import java.util.Random;
|
||||
import java.util.TimeZone;
|
||||
import java.util.UUID;
|
||||
@ -31,13 +29,7 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.mail.Authenticator;
|
||||
import javax.mail.Message.RecipientType;
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.PasswordAuthentication;
|
||||
import javax.mail.Session;
|
||||
import javax.mail.URLName;
|
||||
import javax.mail.internet.InternetAddress;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.cloudstack.acl.ProjectRole;
|
||||
@ -79,8 +71,6 @@ import com.cloud.user.ResourceLimitService;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.user.dao.UserDao;
|
||||
import com.cloud.utils.DateUtil;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
import com.cloud.utils.concurrency.NamedThreadFactory;
|
||||
import com.cloud.utils.db.DB;
|
||||
@ -90,14 +80,16 @@ import com.cloud.utils.db.TransactionCallbackNoReturn;
|
||||
import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn;
|
||||
import com.cloud.utils.db.TransactionStatus;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.sun.mail.smtp.SMTPMessage;
|
||||
import com.sun.mail.smtp.SMTPSSLTransport;
|
||||
import com.sun.mail.smtp.SMTPTransport;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import org.apache.cloudstack.utils.mailing.MailAddress;
|
||||
import org.apache.cloudstack.utils.mailing.SMTPMailProperties;
|
||||
import org.apache.cloudstack.utils.mailing.SMTPMailSender;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
|
||||
@Component
|
||||
public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
public static final Logger s_logger = Logger.getLogger(ProjectManagerImpl.class);
|
||||
private EmailInvite _emailInvite;
|
||||
|
||||
@Inject
|
||||
private DomainDao _domainDao;
|
||||
@ -137,33 +129,23 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
protected boolean _allowUserToCreateProject = true;
|
||||
protected ScheduledExecutorService _executor;
|
||||
protected int _projectCleanupExpInvInterval = 60; //Interval defining how often project invitation cleanup thread is running
|
||||
private String senderAddress;
|
||||
protected SMTPMailSender mailSender;
|
||||
|
||||
@Override
|
||||
public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
|
||||
|
||||
Map<String, String> configs = _configDao.getConfiguration(params);
|
||||
_invitationRequired = Boolean.valueOf(configs.get(Config.ProjectInviteRequired.key()));
|
||||
_invitationRequired = BooleanUtils.toBoolean(configs.get(Config.ProjectInviteRequired.key()));
|
||||
|
||||
String value = configs.get(Config.ProjectInvitationExpirationTime.key());
|
||||
_invitationTimeOut = Long.parseLong(value != null ? value : "86400") * 1000;
|
||||
_allowUserToCreateProject = Boolean.valueOf(configs.get(Config.AllowUserToCreateProject.key()));
|
||||
_allowUserToCreateProject = BooleanUtils.toBoolean(configs.get(Config.AllowUserToCreateProject.key()));
|
||||
senderAddress = configs.get("project.email.sender");
|
||||
|
||||
// set up the email system for project invitations
|
||||
String namespace = "project.smtp";
|
||||
|
||||
String smtpHost = configs.get("project.smtp.host");
|
||||
int smtpPort = NumbersUtil.parseInt(configs.get("project.smtp.port"), 25);
|
||||
String useAuthStr = configs.get("project.smtp.useAuth");
|
||||
boolean useAuth = ((useAuthStr == null) ? false : Boolean.parseBoolean(useAuthStr));
|
||||
String smtpUsername = configs.get("project.smtp.username");
|
||||
String smtpPassword = configs.get("project.smtp.password");
|
||||
String emailSender = configs.get("project.email.sender");
|
||||
String smtpDebugStr = configs.get("project.smtp.debug");
|
||||
boolean smtpDebug = false;
|
||||
if (smtpDebugStr != null) {
|
||||
smtpDebug = Boolean.parseBoolean(smtpDebugStr);
|
||||
}
|
||||
|
||||
_emailInvite = new EmailInvite(smtpHost, smtpPort, useAuth, smtpUsername, smtpPassword, emailSender, smtpDebug);
|
||||
mailSender = new SMTPMailSender(configs, namespace);
|
||||
_executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Project-ExpireInvitations"));
|
||||
|
||||
return true;
|
||||
@ -1081,7 +1063,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
|
||||
ProjectInvitation projectInvitation = _projectInvitationDao.persist(projectInvitationVO);
|
||||
try {
|
||||
_emailInvite.sendInvite(token, email, project.getId());
|
||||
sendInvite(token, email, project.getId());
|
||||
} catch (Exception ex) {
|
||||
s_logger.warn("Failed to send project id=" + project + " invitation to the email " + email + "; removing the invitation record from the db", ex);
|
||||
_projectInvitationDao.remove(projectInvitation.getId());
|
||||
@ -1091,6 +1073,27 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
return projectInvitation;
|
||||
}
|
||||
|
||||
protected void sendInvite(String token, String email, long projectId) throws MessagingException, UnsupportedEncodingException {
|
||||
String subject = String.format("You are invited to join the cloud stack project id=[%s].", projectId);
|
||||
String content = String.format("You've been invited to join the CloudStack project id=[%s]. Please use token [%s] to complete registration", projectId, token);
|
||||
|
||||
SMTPMailProperties mailProperties = new SMTPMailProperties();
|
||||
|
||||
mailProperties.setSender(new MailAddress(senderAddress));
|
||||
mailProperties.setSubject(subject);
|
||||
mailProperties.setContent(content);
|
||||
mailProperties.setContentType("text/plain");
|
||||
|
||||
Set<MailAddress> addresses = new HashSet<>();
|
||||
|
||||
addresses.add(new MailAddress(email));
|
||||
|
||||
mailProperties.setRecipients(addresses);
|
||||
|
||||
mailSender.sendMail(mailProperties);
|
||||
|
||||
}
|
||||
|
||||
private boolean expireInvitation(ProjectInvitationVO invite) {
|
||||
s_logger.debug("Expiring invitation id=" + invite.getId());
|
||||
invite.setState(ProjectInvitation.State.Expired);
|
||||
@ -1305,91 +1308,6 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
class EmailInvite {
|
||||
private Session _smtpSession;
|
||||
private final String _smtpHost;
|
||||
private int _smtpPort = -1;
|
||||
private boolean _smtpUseAuth = false;
|
||||
private final String _smtpUsername;
|
||||
private final String _smtpPassword;
|
||||
private final String _emailSender;
|
||||
|
||||
public EmailInvite(String smtpHost, int smtpPort, boolean smtpUseAuth, final String smtpUsername, final String smtpPassword, String emailSender, boolean smtpDebug) {
|
||||
_smtpHost = smtpHost;
|
||||
_smtpPort = smtpPort;
|
||||
_smtpUseAuth = smtpUseAuth;
|
||||
_smtpUsername = smtpUsername;
|
||||
_smtpPassword = smtpPassword;
|
||||
_emailSender = emailSender;
|
||||
|
||||
if (_smtpHost != null) {
|
||||
Properties smtpProps = new Properties();
|
||||
smtpProps.put("mail.smtp.host", smtpHost);
|
||||
smtpProps.put("mail.smtp.port", smtpPort);
|
||||
smtpProps.put("mail.smtp.auth", "" + smtpUseAuth);
|
||||
if (smtpUsername != null) {
|
||||
smtpProps.put("mail.smtp.user", smtpUsername);
|
||||
}
|
||||
|
||||
smtpProps.put("mail.smtps.host", smtpHost);
|
||||
smtpProps.put("mail.smtps.port", smtpPort);
|
||||
smtpProps.put("mail.smtps.auth", "" + smtpUseAuth);
|
||||
if (smtpUsername != null) {
|
||||
smtpProps.put("mail.smtps.user", smtpUsername);
|
||||
}
|
||||
|
||||
if ((smtpUsername != null) && (smtpPassword != null)) {
|
||||
_smtpSession = Session.getInstance(smtpProps, new Authenticator() {
|
||||
@Override
|
||||
protected PasswordAuthentication getPasswordAuthentication() {
|
||||
return new PasswordAuthentication(smtpUsername, smtpPassword);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
_smtpSession = Session.getInstance(smtpProps);
|
||||
}
|
||||
_smtpSession.setDebug(smtpDebug);
|
||||
} else {
|
||||
_smtpSession = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void sendInvite(String token, String email, long projectId) throws MessagingException, UnsupportedEncodingException {
|
||||
if (_smtpSession != null) {
|
||||
InternetAddress address = null;
|
||||
if (email != null) {
|
||||
try {
|
||||
address = new InternetAddress(email, email);
|
||||
} catch (Exception ex) {
|
||||
s_logger.error("Exception creating address for: " + email, ex);
|
||||
}
|
||||
}
|
||||
|
||||
String content = "You've been invited to join the CloudStack project id=" + projectId + ". Please use token " + token + " to complete registration";
|
||||
|
||||
SMTPMessage msg = new SMTPMessage(_smtpSession);
|
||||
msg.setSender(new InternetAddress(_emailSender, _emailSender));
|
||||
msg.setFrom(new InternetAddress(_emailSender, _emailSender));
|
||||
msg.addRecipient(RecipientType.TO, address);
|
||||
msg.setSubject("You are invited to join the cloud stack project id=" + projectId);
|
||||
msg.setSentDate(new Date(DateUtil.currentGMTTime().getTime() >> 10));
|
||||
msg.setContent(content, "text/plain");
|
||||
msg.saveChanges();
|
||||
|
||||
SMTPTransport smtpTrans = null;
|
||||
if (_smtpUseAuth) {
|
||||
smtpTrans = new SMTPSSLTransport(_smtpSession, new URLName("smtp", _smtpHost, _smtpPort, null, _smtpUsername, _smtpPassword));
|
||||
} else {
|
||||
smtpTrans = new SMTPTransport(_smtpSession, new URLName("smtp", _smtpHost, _smtpPort, null, _smtpUsername, _smtpPassword));
|
||||
}
|
||||
smtpTrans.connect();
|
||||
smtpTrans.sendMessage(msg, msg.getAllRecipients());
|
||||
smtpTrans.close();
|
||||
} else {
|
||||
throw new CloudRuntimeException("Unable to send email invitation; smtp ses");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@DB
|
||||
|
||||
@ -16,19 +16,10 @@
|
||||
// under the License.
|
||||
package com.cloud.usage;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.mail.Authenticator;
|
||||
import javax.mail.Message.RecipientType;
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.PasswordAuthentication;
|
||||
import javax.mail.Session;
|
||||
import javax.mail.URLName;
|
||||
import javax.mail.internet.InternetAddress;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
@ -38,18 +29,21 @@ import org.springframework.stereotype.Component;
|
||||
import com.cloud.alert.AlertManager;
|
||||
import com.cloud.alert.AlertVO;
|
||||
import com.cloud.alert.dao.AlertDao;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
import com.sun.mail.smtp.SMTPMessage;
|
||||
import com.sun.mail.smtp.SMTPSSLTransport;
|
||||
import com.sun.mail.smtp.SMTPTransport;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import org.apache.cloudstack.utils.mailing.MailAddress;
|
||||
import org.apache.cloudstack.utils.mailing.SMTPMailProperties;
|
||||
import org.apache.cloudstack.utils.mailing.SMTPMailSender;
|
||||
|
||||
@Component
|
||||
public class UsageAlertManagerImpl extends ManagerBase implements AlertManager {
|
||||
private static final Logger s_logger = Logger.getLogger(UsageAlertManagerImpl.class.getName());
|
||||
private static final Logger s_alertsLogger = Logger.getLogger("org.apache.cloudstack.alerts");
|
||||
|
||||
private EmailAlert _emailAlert;
|
||||
private String senderAddress;
|
||||
protected SMTPMailSender mailSender;
|
||||
protected String[] recipients;
|
||||
|
||||
@Inject
|
||||
private AlertDao _alertDao;
|
||||
@Inject
|
||||
@ -59,185 +53,75 @@ public class UsageAlertManagerImpl extends ManagerBase implements AlertManager {
|
||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||
Map<String, String> configs = _configDao.getConfiguration("management-server", params);
|
||||
|
||||
// set up the email system for alerts
|
||||
senderAddress = configs.get("alert.email.sender");
|
||||
String emailAddressList = configs.get("alert.email.addresses");
|
||||
String[] emailAddresses = null;
|
||||
recipients = null;
|
||||
if (emailAddressList != null) {
|
||||
emailAddresses = emailAddressList.split(",");
|
||||
recipients = emailAddressList.split(",");
|
||||
}
|
||||
|
||||
String smtpHost = configs.get("alert.smtp.host");
|
||||
int smtpPort = NumbersUtil.parseInt(configs.get("alert.smtp.port"), 25);
|
||||
String useAuthStr = configs.get("alert.smtp.useAuth");
|
||||
boolean useAuth = ((useAuthStr == null) ? false : Boolean.parseBoolean(useAuthStr));
|
||||
String smtpUsername = configs.get("alert.smtp.username");
|
||||
String smtpPassword = configs.get("alert.smtp.password");
|
||||
String emailSender = configs.get("alert.email.sender");
|
||||
String smtpDebugStr = configs.get("alert.smtp.debug");
|
||||
boolean smtpDebug = false;
|
||||
if (smtpDebugStr != null) {
|
||||
smtpDebug = Boolean.parseBoolean(smtpDebugStr);
|
||||
}
|
||||
String namespace = "alert.smtp";
|
||||
|
||||
mailSender = new SMTPMailSender(configs, namespace);
|
||||
|
||||
_emailAlert = new EmailAlert(emailAddresses, smtpHost, smtpPort, useAuth, smtpUsername, smtpPassword, emailSender, smtpDebug);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearAlert(AlertType alertType, long dataCenterId, long podId) {
|
||||
try {
|
||||
if (_emailAlert != null) {
|
||||
_emailAlert.clearAlert(alertType.getType(), dataCenterId, podId);
|
||||
}
|
||||
clearAlert(alertType.getType(), dataCenterId, podId);
|
||||
} catch (Exception ex) {
|
||||
s_logger.error("Problem clearing email alert", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendAlert(AlertType alertType, long dataCenterId, Long podId, String subject, String body) {
|
||||
// TODO: queue up these messages and send them as one set of issues once a certain number of issues is reached? If that's the case,
|
||||
// shouldn't we have a type/severity as part of the API so that severe errors get sent right away?
|
||||
try {
|
||||
if (_emailAlert != null) {
|
||||
_emailAlert.sendAlert(alertType, dataCenterId, podId, subject, body);
|
||||
} else {
|
||||
s_alertsLogger.warn(" alertType:: " + alertType + " // dataCenterId:: " + dataCenterId + " // podId:: " + podId + " // clusterId:: " + null +
|
||||
" // message:: " + subject + " // body:: " + body);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
s_logger.error("Problem sending email alert", ex);
|
||||
public void sendAlert(AlertType alertType, long dataCenterId, Long podId, String subject, String content) {
|
||||
AlertVO alert = null;
|
||||
if ((alertType != AlertManager.AlertType.ALERT_TYPE_HOST) && (alertType != AlertManager.AlertType.ALERT_TYPE_USERVM)
|
||||
&& (alertType != AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER) && (alertType != AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY)
|
||||
&& (alertType != AlertManager.AlertType.ALERT_TYPE_SSVM) && (alertType != AlertManager.AlertType.ALERT_TYPE_STORAGE_MISC)
|
||||
&& (alertType != AlertManager.AlertType.ALERT_TYPE_MANAGMENT_NODE)) {
|
||||
alert = _alertDao.getLastAlert(alertType.getType(), dataCenterId, podId);
|
||||
}
|
||||
if (alert == null) {
|
||||
AlertVO newAlert = new AlertVO();
|
||||
newAlert.setType(alertType.getType());
|
||||
newAlert.setSubject(subject);
|
||||
newAlert.setPodId(podId);
|
||||
newAlert.setDataCenterId(dataCenterId);
|
||||
newAlert.setSentCount(1);
|
||||
newAlert.setLastSent(new Date());
|
||||
newAlert.setName(alertType.getName());
|
||||
_alertDao.persist(newAlert);
|
||||
} else {
|
||||
s_logger.debug(String.format("Have already sent: [%s] emails for alert type [%s] -- skipping send email.", alert.getSentCount(), alertType));
|
||||
return;
|
||||
}
|
||||
|
||||
SMTPMailProperties mailProps = new SMTPMailProperties();
|
||||
mailProps.setSender(new MailAddress(senderAddress));
|
||||
mailProps.setSubject(subject);
|
||||
mailProps.setContent(content);
|
||||
mailProps.setContentType("text/plain");
|
||||
|
||||
Set<MailAddress> addresses = new HashSet<>();
|
||||
for (String recipient : recipients) {
|
||||
addresses.add(new MailAddress(recipient));
|
||||
}
|
||||
|
||||
mailProps.setRecipients(addresses);
|
||||
mailSender.sendMail(mailProps);
|
||||
}
|
||||
|
||||
class EmailAlert {
|
||||
private Session _smtpSession;
|
||||
private InternetAddress[] _recipientList;
|
||||
private final String _smtpHost;
|
||||
private int _smtpPort = -1;
|
||||
private boolean _smtpUseAuth = false;
|
||||
private final String _smtpUsername;
|
||||
private final String _smtpPassword;
|
||||
private final String _emailSender;
|
||||
|
||||
public EmailAlert(String[] recipientList, String smtpHost, int smtpPort, boolean smtpUseAuth, final String smtpUsername, final String smtpPassword,
|
||||
String emailSender, boolean smtpDebug) {
|
||||
if (recipientList != null) {
|
||||
_recipientList = new InternetAddress[recipientList.length];
|
||||
for (int i = 0; i < recipientList.length; i++) {
|
||||
try {
|
||||
_recipientList[i] = new InternetAddress(recipientList[i], recipientList[i]);
|
||||
} catch (Exception ex) {
|
||||
s_logger.error("Exception creating address for: " + recipientList[i], ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_smtpHost = smtpHost;
|
||||
_smtpPort = smtpPort;
|
||||
_smtpUseAuth = smtpUseAuth;
|
||||
_smtpUsername = smtpUsername;
|
||||
_smtpPassword = smtpPassword;
|
||||
_emailSender = emailSender;
|
||||
|
||||
if (_smtpHost != null) {
|
||||
Properties smtpProps = new Properties();
|
||||
smtpProps.put("mail.smtp.host", smtpHost);
|
||||
smtpProps.put("mail.smtp.port", smtpPort);
|
||||
smtpProps.put("mail.smtp.auth", "" + smtpUseAuth);
|
||||
if (smtpUsername != null) {
|
||||
smtpProps.put("mail.smtp.user", smtpUsername);
|
||||
}
|
||||
|
||||
smtpProps.put("mail.smtps.host", smtpHost);
|
||||
smtpProps.put("mail.smtps.port", smtpPort);
|
||||
smtpProps.put("mail.smtps.auth", "" + smtpUseAuth);
|
||||
if (smtpUsername != null) {
|
||||
smtpProps.put("mail.smtps.user", smtpUsername);
|
||||
}
|
||||
|
||||
if ((smtpUsername != null) && (smtpPassword != null)) {
|
||||
_smtpSession = Session.getInstance(smtpProps, new Authenticator() {
|
||||
@Override
|
||||
protected PasswordAuthentication getPasswordAuthentication() {
|
||||
return new PasswordAuthentication(smtpUsername, smtpPassword);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
_smtpSession = Session.getInstance(smtpProps);
|
||||
}
|
||||
_smtpSession.setDebug(smtpDebug);
|
||||
} else {
|
||||
_smtpSession = null;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: make sure this handles SSL transport (useAuth is true) and regular
|
||||
protected void sendAlert(AlertType alertType, long dataCenterId, Long podId, String subject, String content) throws MessagingException,
|
||||
UnsupportedEncodingException {
|
||||
s_alertsLogger.warn(" alertType:: " + alertType + " // dataCenterId:: " + dataCenterId + " // podId:: " +
|
||||
podId + " // clusterId:: " + null + " // message:: " + subject);
|
||||
AlertVO alert = null;
|
||||
if ((alertType != AlertManager.AlertType.ALERT_TYPE_HOST) &&
|
||||
(alertType != AlertManager.AlertType.ALERT_TYPE_USERVM) &&
|
||||
(alertType != AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER) &&
|
||||
(alertType != AlertManager.AlertType.ALERT_TYPE_CONSOLE_PROXY) &&
|
||||
(alertType != AlertManager.AlertType.ALERT_TYPE_SSVM) &&
|
||||
(alertType != AlertManager.AlertType.ALERT_TYPE_STORAGE_MISC) &&
|
||||
(alertType != AlertManager.AlertType.ALERT_TYPE_MANAGMENT_NODE)) {
|
||||
alert = _alertDao.getLastAlert(alertType.getType(), dataCenterId, podId);
|
||||
}
|
||||
|
||||
if (alert == null) {
|
||||
// set up a new alert
|
||||
AlertVO newAlert = new AlertVO();
|
||||
newAlert.setType(alertType.getType());
|
||||
newAlert.setSubject(subject);
|
||||
newAlert.setPodId(podId);
|
||||
newAlert.setDataCenterId(dataCenterId);
|
||||
newAlert.setSentCount(1); // initialize sent count to 1 since we are now sending an alert
|
||||
newAlert.setLastSent(new Date());
|
||||
newAlert.setName(alertType.getName());
|
||||
_alertDao.persist(newAlert);
|
||||
} else {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Have already sent: " + alert.getSentCount() + " emails for alert type '" + alertType + "' -- skipping send email");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (_smtpSession != null) {
|
||||
SMTPMessage msg = new SMTPMessage(_smtpSession);
|
||||
msg.setSender(new InternetAddress(_emailSender, _emailSender));
|
||||
msg.setFrom(new InternetAddress(_emailSender, _emailSender));
|
||||
for (InternetAddress address : _recipientList) {
|
||||
msg.addRecipient(RecipientType.TO, address);
|
||||
}
|
||||
msg.setSubject(subject);
|
||||
msg.setSentDate(new Date());
|
||||
msg.setContent(content, "text/plain");
|
||||
msg.saveChanges();
|
||||
|
||||
SMTPTransport smtpTrans = null;
|
||||
if (_smtpUseAuth) {
|
||||
smtpTrans = new SMTPSSLTransport(_smtpSession, new URLName("smtp", _smtpHost, _smtpPort, null, _smtpUsername, _smtpPassword));
|
||||
} else {
|
||||
smtpTrans = new SMTPTransport(_smtpSession, new URLName("smtp", _smtpHost, _smtpPort, null, _smtpUsername, _smtpPassword));
|
||||
}
|
||||
smtpTrans.connect();
|
||||
smtpTrans.sendMessage(msg, msg.getAllRecipients());
|
||||
smtpTrans.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void clearAlert(short alertType, long dataCenterId, Long podId) {
|
||||
if (alertType != -1) {
|
||||
AlertVO alert = _alertDao.getLastAlert(alertType, dataCenterId, podId);
|
||||
if (alert != null) {
|
||||
AlertVO updatedAlert = _alertDao.createForUpdate();
|
||||
updatedAlert.setResolved(new Date());
|
||||
_alertDao.update(alert.getId(), updatedAlert);
|
||||
}
|
||||
public void clearAlert(short alertType, long dataCenterId, Long podId) {
|
||||
if (alertType != -1) {
|
||||
AlertVO alert = _alertDao.getLastAlert(alertType, dataCenterId, podId);
|
||||
if (alert != null) {
|
||||
AlertVO updatedAlert = _alertDao.createForUpdate();
|
||||
updatedAlert.setResolved(new Date());
|
||||
_alertDao.update(alert.getId(), updatedAlert);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -254,7 +138,7 @@ public class UsageAlertManagerImpl extends ManagerBase implements AlertManager {
|
||||
sendAlert(alertType, dataCenterId, podId, msg, msg);
|
||||
return true;
|
||||
} catch (Exception ex) {
|
||||
s_logger.warn("Failed to generate an alert of type=" + alertType + "; msg=" + msg);
|
||||
s_logger.warn("Failed to generate an alert of type=" + alertType + "; msg=" + msg, ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -184,6 +184,15 @@
|
||||
<artifactId>commons-compress</artifactId>
|
||||
<version>${cs.commons-compress.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.mail</groupId>
|
||||
<artifactId>mail</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-email</artifactId>
|
||||
<version>1.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
|
||||
@ -0,0 +1,63 @@
|
||||
/*
|
||||
*
|
||||
* 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 org.apache.commons.lang3.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
public class MailAddress {
|
||||
|
||||
private final String address;
|
||||
private final String personal;
|
||||
|
||||
public MailAddress(String address) {
|
||||
this.address = address;
|
||||
this.personal = address;
|
||||
}
|
||||
|
||||
public MailAddress(String address, String personal) {
|
||||
this.address = address;
|
||||
this.personal = personal;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public String getPersonal() {
|
||||
return personal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return HashCodeBuilder.reflectionHashCode(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
String[] excludedFields = {"personal"};
|
||||
return EqualsBuilder.reflectionEquals(this, obj, excludedFields);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
ToStringBuilder tsb = new ToStringBuilder(this, ToStringStyle.JSON_STYLE);
|
||||
tsb.append("mailAddress", address);
|
||||
return tsb.build();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,89 @@
|
||||
/*
|
||||
*
|
||||
* 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 java.util.Date;
|
||||
import java.util.Set;
|
||||
|
||||
public class SMTPMailProperties {
|
||||
|
||||
private MailAddress sender;
|
||||
private MailAddress from;
|
||||
private Set<MailAddress> recipients;
|
||||
private String subject;
|
||||
private Date sentDate;
|
||||
private Object content;
|
||||
private String contentType;
|
||||
|
||||
public SMTPMailProperties() {
|
||||
}
|
||||
|
||||
public MailAddress getSender() {
|
||||
return sender;
|
||||
}
|
||||
|
||||
public void setSender(MailAddress sender) {
|
||||
this.sender = sender;
|
||||
}
|
||||
|
||||
public MailAddress getFrom() {
|
||||
return from;
|
||||
}
|
||||
|
||||
public void setFrom(MailAddress from) {
|
||||
this.from = from;
|
||||
}
|
||||
|
||||
public Set<MailAddress> getRecipients() {
|
||||
return recipients;
|
||||
}
|
||||
|
||||
public void setRecipients(Set<MailAddress> recipients) {
|
||||
this.recipients = recipients;
|
||||
}
|
||||
|
||||
public String getSubject() {
|
||||
return subject;
|
||||
}
|
||||
|
||||
public void setSubject(String subject) {
|
||||
this.subject = subject;
|
||||
}
|
||||
|
||||
public Date getSentDate() {
|
||||
return sentDate;
|
||||
}
|
||||
|
||||
public void setSentDate(Date sentDate) {
|
||||
this.sentDate = sentDate;
|
||||
}
|
||||
|
||||
public Object getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(Object content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
public void setContentType(String contentType) {
|
||||
this.contentType = contentType;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,231 @@
|
||||
/*
|
||||
*
|
||||
* 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.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.math.NumberUtils;
|
||||
import org.apache.commons.mail.EmailConstants;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
public class SMTPMailSender {
|
||||
|
||||
private Logger logger = Logger.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 boolean sendMail(SMTPMailProperties mailProps) {
|
||||
if (session == null) {
|
||||
logger.error("Unable to send mail due to null session.");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
SMTPMessage message = createMessage(mailProps);
|
||||
|
||||
SMTPTransport smtpTrans = createSmtpTransport();
|
||||
|
||||
smtpTrans.connect();
|
||||
smtpTrans.sendMessage(message, message.getAllRecipients());
|
||||
smtpTrans.close();
|
||||
|
||||
return true;
|
||||
} catch (MessagingException | UnsupportedEncodingException ex) {
|
||||
logger.error(String.format("Unable to send mail [%s] to the recipcients [%s].", mailProps.getSubject(), mailProps.getRecipients().toString()), ex);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
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 boolean setMailRecipients(SMTPMessage message, Set<MailAddress> recipients, String subject) throws UnsupportedEncodingException, MessagingException {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (recipients.isEmpty() || message.getAllRecipients().length == 0) {
|
||||
logger.error("Unable to send mail due to empty list of recipients.");
|
||||
logger.debug(String.format("Unable to send message [%s].", subject));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,113 @@
|
||||
/*
|
||||
*
|
||||
* 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;
|
||||
|
||||
public class SMTPSessionProperties {
|
||||
|
||||
private String host;
|
||||
private int port;
|
||||
private Boolean useAuth;
|
||||
private String username;
|
||||
private String password;
|
||||
private Boolean useStartTLS;
|
||||
private String enabledSecurityProtocols;
|
||||
private Boolean debugMode;
|
||||
private Integer timeout;
|
||||
private Integer connectionTimeout;
|
||||
|
||||
public SMTPSessionProperties() {
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public void setHost(String host) {
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public Boolean getUseAuth() {
|
||||
return useAuth;
|
||||
}
|
||||
|
||||
public void setUseAuth(Boolean useAuth) {
|
||||
this.useAuth = useAuth;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public Boolean getUseStartTLS() {
|
||||
return useStartTLS;
|
||||
}
|
||||
|
||||
public void setUseStartTLS(Boolean useStartTLS) {
|
||||
this.useStartTLS = useStartTLS;
|
||||
}
|
||||
|
||||
public String getEnabledSecurityProtocols() {
|
||||
return enabledSecurityProtocols;
|
||||
}
|
||||
|
||||
public void setEnabledSecurityProtocols(String enabledSecurityProtocols) {
|
||||
this.enabledSecurityProtocols = enabledSecurityProtocols;
|
||||
}
|
||||
|
||||
public Boolean getDebugMode() {
|
||||
return debugMode;
|
||||
}
|
||||
|
||||
public void setDebugMode(Boolean debugMode) {
|
||||
this.debugMode = debugMode;
|
||||
}
|
||||
|
||||
public Integer getTimeout() {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
public void setTimeout(Integer timeout) {
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
public Integer getConnectionTimeout() {
|
||||
return connectionTimeout;
|
||||
}
|
||||
|
||||
public void setConnectionTimeout(Integer connectionTimeout) {
|
||||
this.connectionTimeout = connectionTimeout;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,617 @@
|
||||
/*
|
||||
*
|
||||
* 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.SMTPTransport;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import javax.mail.Address;
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.Session;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
import junit.framework.TestCase;
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
import org.apache.commons.mail.EmailConstants;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class SMTPMailSenderTest extends TestCase {
|
||||
|
||||
private SMTPMailSender smtpMailSender;
|
||||
private Map<String, String> configsMock = Mockito.mock(Map.class);
|
||||
private String namespace = "test";
|
||||
private String enabledProtocols = "mail.smtp.ssl.protocols";
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
smtpMailSender = new SMTPMailSender(configsMock, namespace);
|
||||
}
|
||||
|
||||
private String getConfigName(String config) {
|
||||
return String.format("%s.%s", namespace, config);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSetSessionPropertiesUseStartTLSTrue() {
|
||||
Map<String, String> configs = new HashMap<>();
|
||||
configs.put(getConfigName(SMTPMailSender.CONFIG_USE_STARTTLS), "true");
|
||||
|
||||
smtpMailSender.configs = configs;
|
||||
SMTPSessionProperties props = smtpMailSender.configureSessionProperties();
|
||||
|
||||
assertTrue(props.getUseStartTLS());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSetSessionPropertiesUseStartTLSFalse() {
|
||||
Map<String, String> configs = new HashMap<>();
|
||||
configs.put(getConfigName(SMTPMailSender.CONFIG_USE_STARTTLS), "false");
|
||||
|
||||
smtpMailSender.configs = configs;
|
||||
SMTPSessionProperties props = smtpMailSender.configureSessionProperties();
|
||||
|
||||
assertFalse(props.getUseStartTLS());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSetSessionPropertiesUseStartTLSUndefinedUseDefaultFalse() {
|
||||
SMTPMailSender smtpMailSender = new SMTPMailSender(configsMock, namespace);
|
||||
|
||||
SMTPSessionProperties props = smtpMailSender.configureSessionProperties();
|
||||
|
||||
assertFalse(props.getUseStartTLS());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSetSessionPropertiesUseAuthTrue() {
|
||||
Map<String, String> configs = new HashMap<>();
|
||||
configs.put(getConfigName(SMTPMailSender.CONFIG_USE_AUTH), "true");
|
||||
|
||||
smtpMailSender.configs = configs;
|
||||
SMTPSessionProperties props = smtpMailSender.configureSessionProperties();
|
||||
|
||||
assertTrue(props.getUseAuth());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSetSessionPropertiesUseAuthFalse() {
|
||||
Map<String, String> configs = new HashMap<>();
|
||||
configs.put(getConfigName(SMTPMailSender.CONFIG_USE_AUTH), "false");
|
||||
|
||||
smtpMailSender.configs = configs;
|
||||
SMTPSessionProperties props = smtpMailSender.configureSessionProperties();
|
||||
|
||||
assertFalse(props.getUseAuth());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSetSessionPropertiesUseAuthUndefinedUseDefaultFalse() {
|
||||
SMTPMailSender smtpMailSender = new SMTPMailSender(configsMock, namespace);
|
||||
|
||||
SMTPSessionProperties props = smtpMailSender.configureSessionProperties();
|
||||
|
||||
assertFalse(props.getUseAuth());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSetSessionPropertiesDebugModeTrue() {
|
||||
Map<String, String> configs = new HashMap<>();
|
||||
configs.put(getConfigName(SMTPMailSender.CONFIG_DEBUG_MODE), "true");
|
||||
|
||||
smtpMailSender.configs = configs;
|
||||
SMTPSessionProperties props = smtpMailSender.configureSessionProperties();
|
||||
|
||||
assertTrue(props.getDebugMode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSetSessionPropertiesDebugModeFalse() {
|
||||
Map<String, String> configs = new HashMap<>();
|
||||
configs.put(getConfigName(SMTPMailSender.CONFIG_DEBUG_MODE), "false");
|
||||
|
||||
smtpMailSender.configs = configs;
|
||||
SMTPSessionProperties props = smtpMailSender.configureSessionProperties();
|
||||
|
||||
assertFalse(props.getDebugMode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSetSessionPropertiesDebugModeUndefinedUseDefaultFalse() {
|
||||
SMTPMailSender smtpMailSender = new SMTPMailSender(configsMock, namespace);
|
||||
|
||||
SMTPSessionProperties props = smtpMailSender.configureSessionProperties();
|
||||
|
||||
assertFalse(props.getDebugMode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSMTPMailSenderConstructorHostDefinedAsNullNoSessionCreated() {
|
||||
SMTPMailSender smtpMailSender = new SMTPMailSender(new HashMap<>(), namespace);
|
||||
|
||||
assertNull(smtpMailSender.sessionProps.getHost());
|
||||
assertNull(smtpMailSender.session);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSMTPMailSenderConstructorHostDefinedAsEmptyNoSessionCreated() {
|
||||
Map<String, String> configs = new HashMap<>();
|
||||
|
||||
String host = "";
|
||||
|
||||
configs.put(getConfigName(SMTPMailSender.CONFIG_HOST), host);
|
||||
SMTPMailSender smtpMailSender = new SMTPMailSender(configs, namespace);
|
||||
|
||||
assertEquals(host, smtpMailSender.sessionProps.getHost());
|
||||
assertNull(smtpMailSender.session);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSMTPMailSenderConstructorHostDefinedAsBlankNoSessionCreated() {
|
||||
Map<String, String> configs = new HashMap<>();
|
||||
|
||||
String host = " ";
|
||||
|
||||
configs.put(getConfigName(SMTPMailSender.CONFIG_HOST), host);
|
||||
SMTPMailSender smtpMailSender = new SMTPMailSender(configs, namespace);
|
||||
|
||||
assertEquals(host, smtpMailSender.sessionProps.getHost());
|
||||
assertNull(smtpMailSender.session);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSMTPMailSenderConstructorHostDefinedSessionCreated() {
|
||||
Map<String, String> configs = new HashMap<>();
|
||||
|
||||
String host = "smtp.acme.org";
|
||||
|
||||
configs.put(getConfigName(SMTPMailSender.CONFIG_HOST), host);
|
||||
SMTPMailSender smtpMailSender = new SMTPMailSender(configs, namespace);
|
||||
|
||||
assertEquals(host, smtpMailSender.sessionProps.getHost());
|
||||
assertNotNull(smtpMailSender.session);
|
||||
}
|
||||
|
||||
private Map<String, String> getConfigsWithHost() {
|
||||
Map<String, String> configs = new HashMap<>();
|
||||
|
||||
String host = "smtp.acme.org";
|
||||
|
||||
configs.put(getConfigName(SMTPMailSender.CONFIG_HOST), host);
|
||||
|
||||
return configs;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSMTPMailSenderConstructorPortUndefinedUseDefault25() {
|
||||
Map<String, String> configs = getConfigsWithHost();
|
||||
|
||||
SMTPMailSender smtpMailSender = new SMTPMailSender(configs, namespace);
|
||||
|
||||
assertEquals(25, smtpMailSender.sessionProps.getPort());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSMTPMailSenderConstructorPortDefined() {
|
||||
Map<String, String> configs = getConfigsWithHost();
|
||||
|
||||
int port = 465;
|
||||
configs.put(getConfigName(SMTPMailSender.CONFIG_PORT), String.valueOf(port));
|
||||
|
||||
SMTPMailSender smtpMailSender = new SMTPMailSender(configs, namespace);
|
||||
|
||||
assertEquals(port, smtpMailSender.sessionProps.getPort());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSMTPMailSenderConstructorWithTimeoutUndefined() {
|
||||
Map<String, String> configs = getConfigsWithHost();
|
||||
|
||||
SMTPMailSender smtpMailSender = new SMTPMailSender(configs, namespace);
|
||||
|
||||
assertNull(smtpMailSender.sessionProps.getTimeout());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSMTPMailSenderConstructorWithTimeoutDefined() {
|
||||
Map<String, String> configs = getConfigsWithHost();
|
||||
|
||||
Integer timeout = 12345;
|
||||
configs.put(getConfigName(SMTPMailSender.CONFIG_TIMEOUT), String.valueOf(timeout));
|
||||
|
||||
SMTPMailSender smtpMailSender = new SMTPMailSender(configs, namespace);
|
||||
|
||||
assertEquals(timeout, smtpMailSender.sessionProps.getTimeout());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSMTPMailSenderConstructorWithConnectionTimeoutUndefined() {
|
||||
Map<String, String> configs = getConfigsWithHost();
|
||||
|
||||
SMTPMailSender smtpMailSender = new SMTPMailSender(configs, namespace);
|
||||
|
||||
assertNull(smtpMailSender.sessionProps.getConnectionTimeout());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSMTPMailSenderConstructorWithConnectionTimeoutDefined() {
|
||||
Map<String, String> configs = getConfigsWithHost();
|
||||
|
||||
Integer connectionTimeout = 12345;
|
||||
configs.put(getConfigName(SMTPMailSender.CONFIG_CONNECTION_TIMEOUT), String.valueOf(connectionTimeout));
|
||||
|
||||
SMTPMailSender smtpMailSender = new SMTPMailSender(configs, namespace);
|
||||
|
||||
assertEquals(connectionTimeout, smtpMailSender.sessionProps.getConnectionTimeout());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSMTPMailSenderConstructorWithUsernameUndefined() {
|
||||
Map<String, String> configs = getConfigsWithHost();
|
||||
|
||||
SMTPMailSender smtpMailSender = new SMTPMailSender(configs, namespace);
|
||||
|
||||
assertNull(smtpMailSender.sessionProps.getUsername());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSMTPMailSenderConstructorWithUsernameDefinedAsEmpty() {
|
||||
Map<String, String> configs = getConfigsWithHost();
|
||||
|
||||
String username = "";
|
||||
configs.put(getConfigName(SMTPMailSender.CONFIG_USERNAME), username);
|
||||
|
||||
SMTPMailSender smtpMailSender = new SMTPMailSender(configs, namespace);
|
||||
|
||||
assertNotNull(smtpMailSender.sessionProps.getUsername());
|
||||
assertEquals(username, smtpMailSender.session.getProperties().get(EmailConstants.MAIL_SMTP_USER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSMTPMailSenderConstructorWithUsernameDefinedAsBlank() {
|
||||
Map<String, String> configs = getConfigsWithHost();
|
||||
|
||||
String username = " ";
|
||||
configs.put(getConfigName(SMTPMailSender.CONFIG_USERNAME), username);
|
||||
|
||||
SMTPMailSender smtpMailSender = new SMTPMailSender(configs, namespace);
|
||||
|
||||
assertNotNull(smtpMailSender.sessionProps.getUsername());
|
||||
assertEquals(username, smtpMailSender.session.getProperties().get(EmailConstants.MAIL_SMTP_USER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSMTPMailSenderConstructorWithValidUsername() {
|
||||
Map<String, String> configs = getConfigsWithHost();
|
||||
|
||||
String username = "test@test.com";
|
||||
configs.put(getConfigName(SMTPMailSender.CONFIG_USERNAME), username);
|
||||
|
||||
SMTPMailSender smtpMailSender = new SMTPMailSender(configs, namespace);
|
||||
|
||||
assertNotNull(smtpMailSender.sessionProps.getUsername());
|
||||
assertEquals(username, smtpMailSender.session.getProperties().get(EmailConstants.MAIL_SMTP_USER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSMTPMailSenderConstructorWithProtocolsUndefined() {
|
||||
Map<String, String> configs = getConfigsWithHost();
|
||||
|
||||
SMTPMailSender smtpMailSender = new SMTPMailSender(configs, namespace);
|
||||
|
||||
assertNull(smtpMailSender.sessionProps.getEnabledSecurityProtocols());
|
||||
assertNull(smtpMailSender.session.getProperties().get(enabledProtocols));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSMTPMailSenderConstructorWithProtocolsDefinedAsEmpty() {
|
||||
Map<String, String> configs = getConfigsWithHost();
|
||||
|
||||
String protocols = "";
|
||||
configs.put(getConfigName(SMTPMailSender.CONFIG_ENABLED_SECURITY_PROTOCOLS), protocols);
|
||||
|
||||
SMTPMailSender smtpMailSender = new SMTPMailSender(configs, namespace);
|
||||
|
||||
assertEquals(protocols, smtpMailSender.sessionProps.getEnabledSecurityProtocols());
|
||||
assertNull(smtpMailSender.session.getProperties().get(enabledProtocols));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSMTPMailSenderConstructorWithProtocolsDefinedAsBlank() {
|
||||
Map<String, String> configs = getConfigsWithHost();
|
||||
|
||||
String protocols = " ";
|
||||
configs.put(getConfigName(SMTPMailSender.CONFIG_ENABLED_SECURITY_PROTOCOLS), protocols);
|
||||
|
||||
SMTPMailSender smtpMailSender = new SMTPMailSender(configs, namespace);
|
||||
|
||||
assertEquals(protocols, smtpMailSender.sessionProps.getEnabledSecurityProtocols());
|
||||
assertNull(smtpMailSender.session.getProperties().get(enabledProtocols));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSMTPMailSenderConstructorWithValidProtocol() {
|
||||
Map<String, String> configs = getConfigsWithHost();
|
||||
|
||||
String protocols = "TLSv1";
|
||||
configs.put(getConfigName(SMTPMailSender.CONFIG_ENABLED_SECURITY_PROTOCOLS), protocols);
|
||||
|
||||
SMTPMailSender smtpMailSender = new SMTPMailSender(configs, namespace);
|
||||
|
||||
assertEquals(protocols, smtpMailSender.sessionProps.getEnabledSecurityProtocols());
|
||||
assertEquals(protocols, smtpMailSender.session.getProperties().get(enabledProtocols));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSMTPMailSenderConstructorWithMultipleValidsProtocols() {
|
||||
Map<String, String> configs = getConfigsWithHost();
|
||||
|
||||
String protocols = "TLSv1 TLSv1.2";
|
||||
configs.put(getConfigName(SMTPMailSender.CONFIG_ENABLED_SECURITY_PROTOCOLS), protocols);
|
||||
|
||||
SMTPMailSender smtpMailSender = new SMTPMailSender(configs, namespace);
|
||||
|
||||
assertEquals(protocols, smtpMailSender.sessionProps.getEnabledSecurityProtocols());
|
||||
assertEquals(protocols, smtpMailSender.session.getProperties().get(enabledProtocols));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSMTPMailSenderConstructorUseAuthFalseUseStartTLSFalseStartTLSEnabledMustBeNull() {
|
||||
Map<String, String> configs = getConfigsWithHost();
|
||||
|
||||
Boolean useAuth = false;
|
||||
Boolean useStartTLS = false;
|
||||
|
||||
configs.put(getConfigName(SMTPMailSender.CONFIG_USE_AUTH), String.valueOf(useAuth));
|
||||
configs.put(getConfigName(SMTPMailSender.CONFIG_USE_STARTTLS), String.valueOf(useStartTLS));
|
||||
|
||||
SMTPMailSender smtpMailSender = new SMTPMailSender(configs, namespace);
|
||||
|
||||
assertNull(smtpMailSender.session.getProperties().get(EmailConstants.MAIL_TRANSPORT_STARTTLS_ENABLE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSMTPMailSenderConstructorUseAuthFalseUseStartTLSTrueStartTLSEnabledMustBeNull() {
|
||||
Map<String, String> configs = getConfigsWithHost();
|
||||
|
||||
Boolean useAuth = false;
|
||||
Boolean useStartTLS = true;
|
||||
|
||||
configs.put(getConfigName(SMTPMailSender.CONFIG_USE_AUTH), String.valueOf(useAuth));
|
||||
configs.put(getConfigName(SMTPMailSender.CONFIG_USE_STARTTLS), String.valueOf(useStartTLS));
|
||||
|
||||
SMTPMailSender smtpMailSender = new SMTPMailSender(configs, namespace);
|
||||
|
||||
assertNull(smtpMailSender.session.getProperties().get(EmailConstants.MAIL_TRANSPORT_STARTTLS_ENABLE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSMTPMailSenderConstructorUseAuthTrueUseStartTLSFalseStartTLSEnabledMustBeFalse() {
|
||||
Map<String, String> configs = getConfigsWithHost();
|
||||
|
||||
Boolean useAuth = true;
|
||||
Boolean useStartTLS = false;
|
||||
|
||||
configs.put(getConfigName(SMTPMailSender.CONFIG_USE_AUTH), String.valueOf(useAuth));
|
||||
configs.put(getConfigName(SMTPMailSender.CONFIG_USE_STARTTLS), String.valueOf(useStartTLS));
|
||||
|
||||
SMTPMailSender smtpMailSender = new SMTPMailSender(configs, namespace);
|
||||
|
||||
assertFalse((boolean)smtpMailSender.session.getProperties().get(EmailConstants.MAIL_TRANSPORT_STARTTLS_ENABLE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSMTPMailSenderConstructorUseAuthTrueUseStartTLSTrueStartTLSEnabledMustBeFalse() {
|
||||
Map<String, String> configs = getConfigsWithHost();
|
||||
|
||||
Boolean useAuth = true;
|
||||
Boolean useStartTLS = true;
|
||||
|
||||
configs.put(getConfigName(SMTPMailSender.CONFIG_USE_AUTH), String.valueOf(useAuth));
|
||||
configs.put(getConfigName(SMTPMailSender.CONFIG_USE_STARTTLS), String.valueOf(useStartTLS));
|
||||
|
||||
SMTPMailSender smtpMailSender = new SMTPMailSender(configs, namespace);
|
||||
|
||||
assertTrue((boolean)smtpMailSender.session.getProperties().get(EmailConstants.MAIL_TRANSPORT_STARTTLS_ENABLE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSMTPMailSenderCreateMessageFromDefinedAsNull() throws MessagingException, UnsupportedEncodingException {
|
||||
smtpMailSender = smtpMailSender = Mockito.spy(smtpMailSender);
|
||||
|
||||
SMTPMailProperties mailProps = new SMTPMailProperties();
|
||||
|
||||
mailProps.setSender(new MailAddress("test@test.com"));
|
||||
mailProps.setContent("A simple test");
|
||||
mailProps.setContentType("text/plain");
|
||||
|
||||
Mockito.doReturn(true).when(smtpMailSender).setMailRecipients(Mockito.any(SMTPMessage.class), Mockito.any(), Mockito.any());
|
||||
|
||||
SMTPMessage message = smtpMailSender.createMessage(mailProps);
|
||||
|
||||
assertEquals("\"test@test.com\" <test@test.com>", message.getFrom()[0].toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSMTPMailSenderCreateMessageFromDefined() throws MessagingException, UnsupportedEncodingException {
|
||||
smtpMailSender = smtpMailSender = Mockito.spy(smtpMailSender);
|
||||
|
||||
SMTPMailProperties mailProps = new SMTPMailProperties();
|
||||
|
||||
mailProps.setSender(new MailAddress("test@test.com"));
|
||||
mailProps.setFrom(new MailAddress("test2@test2.com", "TEST2"));
|
||||
mailProps.setContent("A simple test");
|
||||
mailProps.setContentType("text/plain");
|
||||
|
||||
Mockito.doReturn(true).when(smtpMailSender).setMailRecipients(Mockito.any(SMTPMessage.class), Mockito.any(), Mockito.any());
|
||||
|
||||
SMTPMessage message = smtpMailSender.createMessage(mailProps);
|
||||
|
||||
assertEquals("TEST2 <test2@test2.com>", message.getFrom()[0].toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSMTPMailSenderCreateMessageSentDateDefined() throws MessagingException, UnsupportedEncodingException {
|
||||
smtpMailSender = smtpMailSender = Mockito.spy(smtpMailSender);
|
||||
|
||||
SMTPMailProperties mailProps = new SMTPMailProperties();
|
||||
|
||||
mailProps.setSender(new MailAddress("test@test.com"));
|
||||
mailProps.setContent("A simple test");
|
||||
mailProps.setContentType("text/plain");
|
||||
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(new Date());
|
||||
cal.set(Calendar.YEAR, 2015);
|
||||
cal.set(Calendar.MONTH, 1);
|
||||
cal.set(Calendar.DAY_OF_MONTH, 1);
|
||||
|
||||
mailProps.setSentDate(cal.getTime());
|
||||
|
||||
Mockito.doReturn(true).when(smtpMailSender).setMailRecipients(Mockito.any(SMTPMessage.class), Mockito.any(), Mockito.any());
|
||||
|
||||
SMTPMessage message = smtpMailSender.createMessage(mailProps);
|
||||
assertTrue(DateUtils.truncatedEquals(cal.getTime(), message.getSentDate(), Calendar.SECOND));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSMTPMailSenderCreateMessageSubjectContentAndContentTypeDefined() throws MessagingException, UnsupportedEncodingException, IOException {
|
||||
smtpMailSender = smtpMailSender = Mockito.spy(smtpMailSender);
|
||||
|
||||
SMTPMailProperties mailProps = new SMTPMailProperties();
|
||||
|
||||
String subject = "A TEST";
|
||||
String content = "A simple test";
|
||||
String contentType = "text/plain;charset=utf8";
|
||||
|
||||
mailProps.setSender(new MailAddress("test@test.com"));
|
||||
mailProps.setSubject(subject);
|
||||
mailProps.setContent(content);
|
||||
mailProps.setContentType(contentType);
|
||||
|
||||
Mockito.doReturn(true).when(smtpMailSender).setMailRecipients(Mockito.any(SMTPMessage.class), Mockito.any(), Mockito.any());
|
||||
|
||||
SMTPMessage message = smtpMailSender.createMessage(mailProps);
|
||||
assertEquals(subject, message.getSubject());
|
||||
assertEquals(content, message.getContent());
|
||||
assertEquals(contentType, message.getContentType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setMailRecipientsTest() throws UnsupportedEncodingException, MessagingException {
|
||||
SMTPMessage messageMock = new SMTPMessage(Mockito.mock(MimeMessage.class));
|
||||
|
||||
Set<MailAddress> recipients = new HashSet<>();
|
||||
recipients.add(new MailAddress(null));
|
||||
recipients.add(new MailAddress(""));
|
||||
recipients.add(new MailAddress(" "));
|
||||
recipients.add(new MailAddress("smtp.acme.org"));
|
||||
recipients.add(new MailAddress("smtp.acme2.org", "Coyote"));
|
||||
|
||||
boolean returnOfSetEmail = smtpMailSender.setMailRecipients(messageMock, recipients, "A simple test");
|
||||
|
||||
Address[] allRecipients = messageMock.getAllRecipients();
|
||||
|
||||
int expectedNumberOfValidRecipientsConfigured = 2;
|
||||
assertEquals(expectedNumberOfValidRecipientsConfigured, allRecipients.length);
|
||||
|
||||
assertEquals("\"smtp.acme.org\" <smtp.acme.org>", allRecipients[0].toString());
|
||||
assertEquals("Coyote <smtp.acme2.org>", allRecipients[1].toString());
|
||||
|
||||
assertTrue(returnOfSetEmail);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setMailRecipientsTestOnlyInvalidEmailSettings() throws UnsupportedEncodingException, MessagingException {
|
||||
SMTPMessage messageMock = new SMTPMessage(Mockito.mock(MimeMessage.class));
|
||||
|
||||
messageMock = messageMock = Mockito.spy(messageMock);
|
||||
Mockito.doReturn(new Address[0]).when(messageMock).getAllRecipients();
|
||||
|
||||
Set<MailAddress> recipients = new HashSet<>();
|
||||
recipients.add(new MailAddress(null));
|
||||
recipients.add(new MailAddress(""));
|
||||
recipients.add(new MailAddress(" "));
|
||||
|
||||
boolean returnOfSetEmail = smtpMailSender.setMailRecipients(messageMock, recipients, "A simple test");
|
||||
|
||||
Address[] allRecipients = messageMock.getAllRecipients();
|
||||
|
||||
int expectedNumberOfValidRecipientsConfigured = 0;
|
||||
assertEquals(expectedNumberOfValidRecipientsConfigured, allRecipients.length);
|
||||
|
||||
assertFalse(returnOfSetEmail);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSMTPMailSenderSendMailWithNullSession() {
|
||||
SMTPMailProperties mailProps = new SMTPMailProperties();
|
||||
|
||||
boolean returnOfSendMail = smtpMailSender.sendMail(mailProps);
|
||||
|
||||
assertFalse(returnOfSendMail);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSMTPMailSenderSendMailWithValidSession() throws MessagingException, UnsupportedEncodingException {
|
||||
smtpMailSender = smtpMailSender = Mockito.spy(smtpMailSender);
|
||||
SMTPMailProperties mailProps = new SMTPMailProperties();
|
||||
|
||||
smtpMailSender.session = Session.getDefaultInstance(Mockito.mock(Properties.class));
|
||||
|
||||
Mockito.doReturn(Mockito.mock(SMTPMessage.class)).when(smtpMailSender).createMessage(Mockito.any(SMTPMailProperties.class));
|
||||
Mockito.doReturn(Mockito.mock(SMTPTransport.class)).when(smtpMailSender).createSmtpTransport();
|
||||
|
||||
boolean returnOfSendMail = smtpMailSender.sendMail(mailProps);
|
||||
|
||||
assertTrue(returnOfSendMail);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSMTPMailSenderGetConfigPropertyUndefinedMustReturnNull() {
|
||||
smtpMailSender = smtpMailSender = Mockito.spy(smtpMailSender);
|
||||
|
||||
String returnOfPropertyThatDoesNotExist = smtpMailSender.getConfig("test");
|
||||
|
||||
assertNull(returnOfPropertyThatDoesNotExist);
|
||||
}
|
||||
|
||||
public void validateSMTPMailSenderGetConfigPropertyDefinedMustReturnIt() {
|
||||
smtpMailSender = smtpMailSender = Mockito.spy(smtpMailSender);
|
||||
|
||||
Map<String, String> configs = new HashMap<>();
|
||||
|
||||
String host = "smtp.acme.org";
|
||||
configs.put(getConfigName(SMTPMailSender.CONFIG_HOST), host);
|
||||
|
||||
smtpMailSender.configs = configs;
|
||||
|
||||
String returnOfPropertyThatExist = smtpMailSender.getConfig(getConfigName(SMTPMailSender.CONFIG_HOST));
|
||||
|
||||
assertNotNull(returnOfPropertyThatExist);
|
||||
assertNotNull(host, returnOfPropertyThatExist);
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user