This is an automated email from the ASF dual-hosted git repository.
dahn pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/main by this push:
new e962f0f Unify SMTP mail sending (#4954)
e962f0f is described below
commit e962f0f27181a367eb8c9f54f64b995f935a5085
Author: Daniel Augusto Veronezi Salvador
<[email protected]>
AuthorDate: Tue Jun 15 18:18:26 2021 -0300
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 <[email protected]>
* Remove copyright line in license header
Co-authored-by: Gabriel Beims Bräscher <[email protected]>
* Remove copyright line in license header
Co-authored-by: Gabriel Beims Bräscher <[email protected]>
* Remove copyright line in license header
Co-authored-by: Gabriel Beims Bräscher <[email protected]>
* Remove copyright line in license header
Co-authored-by: Gabriel Beims Bräscher <[email protected]>
Co-authored-by: Daniel Augusto Veronezi Salvador <[email protected]>
Co-authored-by: Gabriel Beims Bräscher <[email protected]>
---
.../cloudstack/quota/QuotaAlertManagerImpl.java | 149 +----
.../quota/QuotaAlertManagerImplTest.java | 14 +-
.../java/com/cloud/alert/AlertManagerImpl.java | 275 +++------
.../com/cloud/projects/ProjectManagerImpl.java | 152 ++---
.../com/cloud/usage/UsageAlertManagerImpl.java | 228 ++------
utils/pom.xml | 9 +
.../cloudstack/utils/mailing/MailAddress.java | 63 +++
.../utils/mailing/SMTPMailProperties.java | 89 +++
.../cloudstack/utils/mailing/SMTPMailSender.java | 231 ++++++++
.../utils/mailing/SMTPSessionProperties.java | 113 ++++
.../utils/mailing/SMTPMailSenderTest.java | 617 +++++++++++++++++++++
11 files changed, 1336 insertions(+), 604 deletions(-)
diff --git
a/framework/quota/src/main/java/org/apache/cloudstack/quota/QuotaAlertManagerImpl.java
b/framework/quota/src/main/java/org/apache/cloudstack/quota/QuotaAlertManagerImpl.java
index 019420c..924d9c4 100644
---
a/framework/quota/src/main/java/org/apache/cloudstack/quota/QuotaAlertManagerImpl.java
+++
b/framework/quota/src/main/java/org/apache/cloudstack/quota/QuotaAlertManagerImpl.java
@@ -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;
-
- 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;
-
- 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);
- }
+ protected void sendQuotaAlert(List<String> emails, String subject, String
body) {
+ SMTPMailProperties mailProperties = new SMTPMailProperties();
- if (smtpUseAuth) {
- smtpProps.put("mail.smtp.starttls.enable",
smtpUseStartTLS);
- }
+ mailProperties.setSender(new MailAddress(senderAddress));
+ mailProperties.setSubject(subject);
+ mailProperties.setContent(body);
+ mailProperties.setContentType("text/html; charset=utf-8");
- 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));
-
- 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);
- }
- }
- }
+ mailProperties.setRecipients(addresses);
- 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);
}
+
}
diff --git
a/framework/quota/src/test/java/org/apache/cloudstack/quota/QuotaAlertManagerImplTest.java
b/framework/quota/src/test/java/org/apache/cloudstack/quota/QuotaAlertManagerImplTest.java
index 88485b9..95033cc 100644
---
a/framework/quota/src/test/java/org/apache/cloudstack/quota/QuotaAlertManagerImplTest.java
+++
b/framework/quota/src/test/java/org/apache/cloudstack/quota/QuotaAlertManagerImplTest.java
@@ -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
diff --git a/server/src/main/java/com/cloud/alert/AlertManagerImpl.java
b/server/src/main/java/com/cloud/alert/AlertManagerImpl.java
index d48f2a3..99200f41c 100644
--- a/server/src/main/java/com/cloud/alert/AlertManagerImpl.java
+++ b/server/src/main/java/com/cloud/alert/AlertManagerImpl.java
@@ -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");
+
+ 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));
- _emailAlert = new EmailAlert(emailAddresses, smtpHost, smtpPort,
smtpConnectionTimeout, smtpTimeout, useAuth, smtpUsername, smtpPassword,
emailSender, smtpDebug);
+ 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) {
diff --git a/server/src/main/java/com/cloud/projects/ProjectManagerImpl.java
b/server/src/main/java/com/cloud/projects/ProjectManagerImpl.java
index 88ad0c2..7cb4674 100644
--- a/server/src/main/java/com/cloud/projects/ProjectManagerImpl.java
+++ b/server/src/main/java/com/cloud/projects/ProjectManagerImpl.java
@@ -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
diff --git a/usage/src/main/java/com/cloud/usage/UsageAlertManagerImpl.java
b/usage/src/main/java/com/cloud/usage/UsageAlertManagerImpl.java
index fd8c7c0..3ee64e6 100644
--- a/usage/src/main/java/com/cloud/usage/UsageAlertManagerImpl.java
+++ b/usage/src/main/java/com/cloud/usage/UsageAlertManagerImpl.java
@@ -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);
}
- }
-
- 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;
- }
+ 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;
}
- // 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);
- }
+ SMTPMailProperties mailProps = new SMTPMailProperties();
+ mailProps.setSender(new MailAddress(senderAddress));
+ mailProps.setSubject(subject);
+ mailProps.setContent(content);
+ mailProps.setContentType("text/plain");
- 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();
- }
+ 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);
- if (alert != null) {
- AlertVO updatedAlert = _alertDao.createForUpdate();
- updatedAlert.setResolved(new Date());
- _alertDao.update(alert.getId(), updatedAlert);
- }
+ mailProps.setRecipients(addresses);
+ mailSender.sendMail(mailProps);
+ }
+
+ 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;
}
}
diff --git a/utils/pom.xml b/utils/pom.xml
index 8f42567..347ba5b 100755
--- a/utils/pom.xml
+++ b/utils/pom.xml
@@ -185,6 +185,15 @@
<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>
</dependency>
diff --git
a/utils/src/main/java/org/apache/cloudstack/utils/mailing/MailAddress.java
b/utils/src/main/java/org/apache/cloudstack/utils/mailing/MailAddress.java
new file mode 100644
index 0000000..aab51fe
--- /dev/null
+++ b/utils/src/main/java/org/apache/cloudstack/utils/mailing/MailAddress.java
@@ -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();
+ }
+
+}
diff --git
a/utils/src/main/java/org/apache/cloudstack/utils/mailing/SMTPMailProperties.java
b/utils/src/main/java/org/apache/cloudstack/utils/mailing/SMTPMailProperties.java
new file mode 100644
index 0000000..ef5d895
--- /dev/null
+++
b/utils/src/main/java/org/apache/cloudstack/utils/mailing/SMTPMailProperties.java
@@ -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;
+ }
+
+}
diff --git
a/utils/src/main/java/org/apache/cloudstack/utils/mailing/SMTPMailSender.java
b/utils/src/main/java/org/apache/cloudstack/utils/mailing/SMTPMailSender.java
new file mode 100644
index 0000000..42497eb
--- /dev/null
+++
b/utils/src/main/java/org/apache/cloudstack/utils/mailing/SMTPMailSender.java
@@ -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;
+ }
+
+}
diff --git
a/utils/src/main/java/org/apache/cloudstack/utils/mailing/SMTPSessionProperties.java
b/utils/src/main/java/org/apache/cloudstack/utils/mailing/SMTPSessionProperties.java
new file mode 100644
index 0000000..cc7023d
--- /dev/null
+++
b/utils/src/main/java/org/apache/cloudstack/utils/mailing/SMTPSessionProperties.java
@@ -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;
+ }
+
+}
diff --git
a/utils/src/test/java/org/apache/cloudstack/utils/mailing/SMTPMailSenderTest.java
b/utils/src/test/java/org/apache/cloudstack/utils/mailing/SMTPMailSenderTest.java
new file mode 100644
index 0000000..bb2290b
--- /dev/null
+++
b/utils/src/test/java/org/apache/cloudstack/utils/mailing/SMTPMailSenderTest.java
@@ -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 = "[email protected]";
+ 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("[email protected]"));
+ 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("\"[email protected]\" <[email protected]>",
message.getFrom()[0].toString());
+ }
+
+ @Test
+ public void validateSMTPMailSenderCreateMessageFromDefined() throws
MessagingException, UnsupportedEncodingException {
+ smtpMailSender = smtpMailSender = Mockito.spy(smtpMailSender);
+
+ SMTPMailProperties mailProps = new SMTPMailProperties();
+
+ mailProps.setSender(new MailAddress("[email protected]"));
+ mailProps.setFrom(new MailAddress("[email protected]", "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 <[email protected]>",
message.getFrom()[0].toString());
+ }
+
+ @Test
+ public void validateSMTPMailSenderCreateMessageSentDateDefined() throws
MessagingException, UnsupportedEncodingException {
+ smtpMailSender = smtpMailSender = Mockito.spy(smtpMailSender);
+
+ SMTPMailProperties mailProps = new SMTPMailProperties();
+
+ mailProps.setSender(new MailAddress("[email protected]"));
+ 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("[email protected]"));
+ 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);
+ }
+}