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 @@ -53,6 +53,7 @@
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.collections.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;

@Component
Expand Down Expand Up @@ -222,7 +223,7 @@ public void sendQuotaAlert(DeferredQuotaEmail emailToBeSent) {
final String subject = templateEngine.replace(emailTemplate.getTemplateSubject());
final String body = templateEngine.replace(emailTemplate.getTemplateBody());
try {
sendQuotaAlert(emailRecipients, subject, body);
sendQuotaAlert(account.getUuid(), 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 @@ -325,14 +326,20 @@ public void sentSuccessfully(final QuotaAccountDao quotaAccountDao) {
}
};

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

mailProperties.setSender(new MailAddress(senderAddress));
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));
return;
}

Set<MailAddress> addresses = new HashSet<>();
for (String email : emails) {
addresses.add(new MailAddress(email));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,12 @@ public void testSendQuotaAlert() throws UnsupportedEncodingException, MessagingE
Mockito.when(userDao.listByAccount(Mockito.anyLong())).thenReturn(users);

quotaAlertManager.mailSender = Mockito.mock(SMTPMailSender.class);
Mockito.when(quotaAlertManager.mailSender.sendMail(Mockito.anyObject())).thenReturn(Boolean.TRUE);
Mockito.doNothing().when(quotaAlertManager.mailSender).sendMail(Mockito.any());

quotaAlertManager.sendQuotaAlert(email);
assertTrue(email.getSendDate() != null);
Mockito.verify(quotaAlertManager, Mockito.times(1)).sendQuotaAlert(Mockito.anyListOf(String.class), Mockito.anyString(), Mockito.anyString());

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

Expand Down
70 changes: 35 additions & 35 deletions server/src/main/java/com/cloud/alert/AlertManagerImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,11 @@
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.ArrayUtils;
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());
protected Logger logger = Logger.getLogger(AlertManagerImpl.class.getName());

private static final long INITIAL_CAPACITY_CHECK_DELAY = 30L * 1000L; // Thirty seconds expressed in milliseconds.

Expand Down Expand Up @@ -226,7 +227,7 @@ public void clearAlert(AlertType alertType, long dataCenterId, long podId) {
try {
clearAlert(alertType.getType(), dataCenterId, podId);
} catch (Exception ex) {
s_logger.error("Problem clearing email alert", ex);
logger.error("Problem clearing email alert", ex);
}
}

Expand All @@ -242,11 +243,11 @@ public void sendAlert(AlertType alertType, long dataCenterId, Long podId, String
if (mailSender != null) {
sendAlert(alertType, dataCenterId, podId, null, subject, body);
} else {
s_logger.warn("AlertType:: " + alertType + " | dataCenterId:: " + dataCenterId + " | podId:: " + podId +
logger.warn("AlertType:: " + alertType + " | dataCenterId:: " + dataCenterId + " | podId:: " + podId +
" | message:: " + subject + " | body:: " + body);
}
} catch (Exception ex) {
s_logger.error("Problem sending email alert", ex);
logger.error("Problem sending email alert", ex);
}
}

Expand All @@ -261,9 +262,9 @@ public void recalculateCapacity() {

try {

if (s_logger.isDebugEnabled()) {
s_logger.debug("recalculating system capacity");
s_logger.debug("Executing cpu/ram capacity update");
if (logger.isDebugEnabled()) {
logger.debug("recalculating system capacity");
logger.debug("Executing cpu/ram capacity update");
}

// Calculate CPU and RAM capacities
Expand All @@ -280,9 +281,9 @@ public void recalculateCapacity() {
_capacityMgr.updateCapacityForHost(host, offeringsMap);
}
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("Done executing cpu/ram capacity update");
s_logger.debug("Executing storage capacity update");
if (logger.isDebugEnabled()) {
logger.debug("Done executing cpu/ram capacity update");
logger.debug("Executing storage capacity update");
}
// Calculate storage pool capacity
List<StoragePoolVO> storagePools = _storagePoolDao.listAll();
Expand All @@ -295,9 +296,9 @@ public void recalculateCapacity() {
}
}

if (s_logger.isDebugEnabled()) {
s_logger.debug("Done executing storage capacity update");
s_logger.debug("Executing capacity updates for public ip and Vlans");
if (logger.isDebugEnabled()) {
logger.debug("Done executing storage capacity update");
logger.debug("Executing capacity updates for public ip and Vlans");
}

List<DataCenterVO> datacenters = _dcDao.listAll();
Expand All @@ -324,9 +325,9 @@ public void recalculateCapacity() {
}
}

if (s_logger.isDebugEnabled()) {
s_logger.debug("Done capacity updates for public ip and Vlans");
s_logger.debug("Executing capacity updates for private ip");
if (logger.isDebugEnabled()) {
logger.debug("Done capacity updates for public ip and Vlans");
logger.debug("Executing capacity updates for private ip");
}

// Calculate new Private IP capacity
Expand All @@ -338,13 +339,13 @@ public void recalculateCapacity() {
createOrUpdateIpCapacity(dcId, podId, Capacity.CAPACITY_TYPE_PRIVATE_IP, _configMgr.findPodAllocationState(pod));
}

if (s_logger.isDebugEnabled()) {
s_logger.debug("Done executing capacity updates for private ip");
s_logger.debug("Done recalculating system capacity");
if (logger.isDebugEnabled()) {
logger.debug("Done executing capacity updates for private ip");
logger.debug("Done recalculating system capacity");
}

} catch (Throwable t) {
s_logger.error("Caught exception in recalculating capacity", t);
logger.error("Caught exception in recalculating capacity", t);
}
}

Expand Down Expand Up @@ -419,11 +420,11 @@ class CapacityChecker extends ManagedContextTimerTask {
@Override
protected void runInContext() {
try {
s_logger.debug("Running Capacity Checker ... ");
logger.debug("Running Capacity Checker ... ");
checkForAlerts();
s_logger.debug("Done running Capacity Checker ... ");
logger.debug("Done running Capacity Checker ... ");
} catch (Throwable t) {
s_logger.error("Exception in CapacityChecker", t);
logger.error("Exception in CapacityChecker", t);
}
}
}
Expand Down Expand Up @@ -628,13 +629,13 @@ private void generateEmailAlert(DataCenterVO dc, HostPodVO pod, ClusterVO cluste
}

try {
if (s_logger.isDebugEnabled()) {
s_logger.debug(msgSubject);
s_logger.debug(msgContent);
if (logger.isDebugEnabled()) {
logger.debug(msgSubject);
logger.debug(msgContent);
}
sendAlert(alertType, dc.getId(), podId, clusterId, msgSubject, msgContent);
} catch (Exception ex) {
s_logger.error("Exception in CapacityChecker", ex);
logger.error("Exception in CapacityChecker", ex);
}
}

Expand Down Expand Up @@ -682,7 +683,7 @@ public void clearAlert(short alertType, long dataCenterId, Long podId) {

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));
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)
Expand All @@ -706,14 +707,13 @@ public void sendAlert(AlertType alertType, long dataCenterId, Long podId, Long c
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");
}
logger.debug("Have already sent: " + alert.getSentCount() + " emails for alert type '" + alertType + "' -- skipping send email");
Comment thread
joseflauzino marked this conversation as resolved.
return;
}

if (recipients == null) {
s_logger.warn(String.format("No recipients set in 'alert.email.addresses', skipping sending alert with subject: %s and content: %s", subject, content));
if (ArrayUtils.isEmpty(recipients)) {
logger.warn(String.format("No recipients set in global setting 'alert.email.addresses', "
+ "skipping sending alert with subject [%s] and content [%s].", subject, content));
return;
}

Expand All @@ -734,7 +734,7 @@ public void sendAlert(AlertType alertType, long dataCenterId, Long podId, Long c

}

private void sendMessage(SMTPMailProperties mailProps) {
protected void sendMessage(SMTPMailProperties mailProps) {
_executor.execute(new Runnable() {
@Override
public void run() {
Expand Down Expand Up @@ -770,7 +770,7 @@ public boolean generateAlert(AlertType alertType, long dataCenterId, Long podId,
sendAlert(alertType, dataCenterId, podId, msg, msg);
return true;
} catch (Exception ex) {
s_logger.warn("Failed to generate an alert of type=" + alertType + "; msg=" + msg);
logger.warn("Failed to generate an alert of type=" + alertType + "; msg=" + msg);
return false;
}
}
Expand Down
99 changes: 99 additions & 0 deletions server/src/test/java/com/cloud/alert/AlertManagerImplTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// 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 com.cloud.alert;

import java.io.UnsupportedEncodingException;

import javax.mail.MessagingException;

import org.apache.cloudstack.utils.mailing.SMTPMailSender;
import org.apache.log4j.Logger;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnitRunner;

import com.cloud.alert.dao.AlertDao;

@RunWith(MockitoJUnitRunner.class)
public class AlertManagerImplTest {

@Spy
@InjectMocks
AlertManagerImpl alertManagerImplMock;

@Mock
AlertDao alertDaoMock;

@Mock
AlertVO alertVOMock;

@Mock
Logger loggerMock;

@Mock
SMTPMailSender mailSenderMock;

private void sendMessage (){
try {
alertManagerImplMock.sendAlert(AlertManager.AlertType.ALERT_TYPE_CPU, 0, 1l, 1l, "", "");
} catch (UnsupportedEncodingException | MessagingException e) {
Assert.fail();
}
}

@Test
public void sendAlertTestSendMail() {
Mockito.doReturn(null).when(alertDaoMock).getLastAlert(Mockito.anyShort(), Mockito.anyLong(),
Mockito.anyLong(), Mockito.anyLong());
Mockito.doReturn(null).when(alertDaoMock).persist(Mockito.any());
alertManagerImplMock.recipients = new String [] {""};

sendMessage();

Mockito.verify(alertManagerImplMock).sendMessage(Mockito.any());
}

@Test
public void sendAlertTestDebugLogging() {
Mockito.doReturn(0).when(alertVOMock).getSentCount();
Mockito.doReturn(alertVOMock).when(alertDaoMock).getLastAlert(Mockito.anyShort(), Mockito.anyLong(),
Mockito.anyLong(), Mockito.anyLong());

sendMessage();

Mockito.verify(alertManagerImplMock.logger).debug(Mockito.anyString());
Mockito.verify(alertManagerImplMock, Mockito.never()).sendMessage(Mockito.any());
}

@Test
public void sendAlertTestWarnLogging() {
Mockito.doReturn(null).when(alertDaoMock).getLastAlert(Mockito.anyShort(), Mockito.anyLong(),
Mockito.anyLong(), Mockito.anyLong());
Mockito.doReturn(null).when(alertDaoMock).persist(Mockito.any());
alertManagerImplMock.recipients = null;

sendMessage();

Mockito.verify(alertManagerImplMock.logger, Mockito.times(2)).warn(Mockito.anyString());
Mockito.verify(alertManagerImplMock, Mockito.never()).sendMessage(Mockito.any());
}
}
Loading