Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.apache.cloudstack.quota.vo.QuotaEmailTemplatesVO;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.text.StrSubstitutor;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;

Expand Down Expand Up @@ -223,7 +224,7 @@ public void sendQuotaAlert(DeferredQuotaEmail emailToBeSent) {
final String body = bodySubstitutor.replace(emailTemplate.getTemplateBody());

try {
sendQuotaAlert(account.getUuid(), emailRecipients, subject, body);
sendQuotaAlert(account, 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 @@ -354,17 +355,20 @@ public void sentSuccessfully(final QuotaAccountDao quotaAccountDao) {
}
};

protected void sendQuotaAlert(String accountUuid, List<String> emails, String subject, String body) {
protected void sendQuotaAlert(Account account, List<String> emails, String subject, String body) {
SMTPMailProperties mailProperties = new SMTPMailProperties();

mailProperties.setSender(new MailAddress(senderAddress));

body = addHeaderAndFooter(body, QuotaConfig.QuotaEmailHeader.valueIn(account.getDomainId()), QuotaConfig.QuotaEmailFooter.valueIn(account.getDomainId()));

mailProperties.setSubject(subject);
mailProperties.setContent(body);
mailProperties.setContentType("text/html; charset=utf-8");

if (CollectionUtils.isEmpty(emails)) {
s_logger.warn(String.format("Account [%s] does not have users with email registered, "
+ "therefore we are unable to send quota alert email with subject [%s] and content [%s].", accountUuid, subject, body));
+ "therefore we are unable to send quota alert email with subject [%s] and content [%s].", account.getUuid(), subject, body));
return;
}

Expand All @@ -378,4 +382,16 @@ protected void sendQuotaAlert(String accountUuid, List<String> emails, String su
mailSender.sendMail(mailProperties);
}

protected String addHeaderAndFooter(String body, String header, String footer) {

if (StringUtils.isNotEmpty(header)) {
body = String.format("%s%s", header, body);
}
if (StringUtils.isNotEmpty(footer)) {
body = String.format("%s%s", body, footer);
}

return body;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ public interface QuotaConfig {
ConfigKey<Boolean> QuotaAccountEnabled = new ConfigKey<>("Advanced", Boolean.class, "quota.account.enabled", "true", "Indicates whether Quota plugin is enabled or not for " +
"the account.", true, ConfigKey.Scope.Account);

ConfigKey<String> QuotaEmailHeader = new ConfigKey<>("Advanced", String.class, "quota.email.header", "",
"Text to be added as a header for quota emails. Line breaks are not automatically inserted between this section and the body.", true, ConfigKey.Scope.Domain);

ConfigKey<String> QuotaEmailFooter = new ConfigKey<>("Advanced", String.class, "quota.email.footer", "",
"Text to be added as a footer for quota emails. Line breaks are not automatically inserted between this section and the body.", true, ConfigKey.Scope.Domain);

enum QuotaEmailTemplateTypes {
QUOTA_LOW, QUOTA_EMPTY, QUOTA_UNLOCK_ACCOUNT, QUOTA_STATEMENT
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,21 @@ public class QuotaAlertManagerImplTest extends TestCase {
@Mock
private ConfigurationDao configDao;

@Mock
private QuotaAccountVO quotaAccountVOMock;

@Mock
private List<QuotaAlertManagerImpl.DeferredQuotaEmail> deferredQuotaEmailListMock;

@Mock
private QuotaManagerImpl quotaManagerMock;

@Mock
private Date balanceDateMock;

@Mock
private AccountVO accountMock;

@Spy
@InjectMocks
private QuotaAlertManagerImpl quotaAlertManager = new QuotaAlertManagerImpl();
Expand Down Expand Up @@ -162,10 +177,22 @@ public void testSendQuotaAlert() throws UnsupportedEncodingException, MessagingE
quotaAlertManager.sendQuotaAlert(email);
assertTrue(email.getSendDate() != null);

Mockito.verify(quotaAlertManager, Mockito.times(1)).sendQuotaAlert(Mockito.anyString(), Mockito.anyListOf(String.class), Mockito.anyString(), Mockito.anyString());
Mockito.verify(quotaAlertManager, Mockito.times(1)).sendQuotaAlert(Mockito.any(), Mockito.anyListOf(String.class), Mockito.anyString(), Mockito.anyString());
Mockito.verify(quotaAlertManager.mailSender, Mockito.times(1)).sendMail(Mockito.any(SMTPMailProperties.class));
}

@Test
public void addHeaderAndFooterTestIfHeaderAndFootersAreAdded() {
String body = quotaAlertManager.addHeaderAndFooter("body", "Header", "Footer");
assertEquals("HeaderbodyFooter", body);
}

@Test
public void addHeaderAndFooterTestIfHeaderAndFootersAreNotAddedIfEmpty() {
String body = quotaAlertManager.addHeaderAndFooter("body", "", "");
assertEquals("body", body);
}

@Test
public void testGetDifferenceDays() {
Date now = new Date();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ public String getConfigComponentName() {
@Override
public ConfigKey<?>[] getConfigKeys() {
return new ConfigKey<?>[] {QuotaPluginEnabled, QuotaEnableEnforcement, QuotaCurrencySymbol, QuotaStatementPeriod, QuotaSmtpHost, QuotaSmtpPort, QuotaSmtpTimeout,
QuotaSmtpUser, QuotaSmtpPassword, QuotaSmtpAuthType, QuotaSmtpSender, QuotaSmtpEnabledSecurityProtocols, QuotaSmtpUseStartTLS, QuotaActivationRuleTimeout, QuotaAccountEnabled};
QuotaSmtpUser, QuotaSmtpPassword, QuotaSmtpAuthType, QuotaSmtpSender, QuotaSmtpEnabledSecurityProtocols, QuotaSmtpUseStartTLS, QuotaActivationRuleTimeout, QuotaAccountEnabled,
QuotaEmailHeader, QuotaEmailFooter};
}

@Override
Expand Down