Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -55,15 +46,14 @@
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 {
Expand All @@ -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;

Expand All @@ -109,19 +100,16 @@ public boolean configure(String name, Map<String, Object> params) throws Configu
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;
}

Expand Down Expand Up @@ -234,7 +222,7 @@ public void sendQuotaAlert(DeferredQuotaEmail emailToBeSent) {
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(),
Expand Down Expand Up @@ -337,99 +325,22 @@ public void sentSuccessfully(final QuotaAccountDao quotaAccountDao) {
}
};

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);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@
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 {
Expand All @@ -68,16 +70,13 @@ public class QuotaAlertManagerImplTest extends TestCase {
private QuotaEmailTemplatesDao quotaEmailTemplateDao;
@Mock
private ConfigurationDao configDao;
@Mock
private QuotaAlertManagerImpl.EmailQuotaAlert emailQuotaAlert;

@Spy
@InjectMocks
private QuotaAlertManagerImpl quotaAlertManager = new QuotaAlertManagerImpl();

@Before
public void setup() throws IllegalAccessException, NoSuchFieldException, ConfigurationException {
// Dummy transaction stack setup
TransactionLegacy.open("QuotaAlertManagerImplTest");
}

Expand Down Expand Up @@ -135,7 +134,8 @@ public void testSendQuotaAlert() throws UnsupportedEncodingException, MessagingE
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");
Expand All @@ -156,9 +156,13 @@ public void testSendQuotaAlert() throws UnsupportedEncodingException, MessagingE
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
Expand Down
Loading
Morty Proxy This is a proxified and sanitized view of the page, visit original site.