Merge pull request #1254 from shapeblue/master-9174

CLOUDSTACK-9174: A deleted account results in NPEWhen an account is deleted from cloudstack for which quota is still
being calculated and if the quota reaches minimum threshold then
quota service will try to alert the user. This results in NPE and is
fixed by excluding such accounts from alerting and other quota related
mechanisms.

* pr/1254:
  CLOUDSTACK-9174: A deleted account results in NPE

Signed-off-by: Will Stevens <williamstevens@gmail.com>
This commit is contained in:
Will Stevens 2016-04-07 11:39:22 -04:00
commit e72a69a8a2
6 changed files with 21 additions and 20 deletions

View File

@ -153,6 +153,7 @@ public class QuotaAlertManagerImpl extends ManagerBase implements QuotaAlertMana
BigDecimal thresholdBalance = quotaAccount.getQuotaMinBalance();
if (accountBalance != null) {
AccountVO account = _accountDao.findById(quotaAccount.getId());
if (account == null) continue; // the account is removed
if (s_logger.isDebugEnabled()) {
s_logger.debug("checkAndSendQuotaAlertEmails: Check id=" + account.getId() + " bal=" + accountBalance + ", alertDate=" + alertDate + ", lockable=" + lockable);
}

View File

@ -360,10 +360,11 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager {
BigDecimal rawusage;
// get service offering details
ServiceOfferingVO serviceoffering = _serviceOfferingDao.findServiceOffering(usageRecord.getVmInstanceId(), usageRecord.getOfferingId());
if (serviceoffering == null) return quotalist;
rawusage = new BigDecimal(usageRecord.getRawUsage());
QuotaTariffVO tariff = _quotaTariffDao.findTariffPlanByUsageType(QuotaTypes.CPU_NUMBER, usageRecord.getEndDate());
if (tariff != null && tariff.getCurrencyValue().compareTo(BigDecimal.ZERO) != 0) {
if (tariff != null && tariff.getCurrencyValue().compareTo(BigDecimal.ZERO) != 0 && serviceoffering.getCpu() != null) {
BigDecimal cpu = new BigDecimal(serviceoffering.getCpu());
onehourcostpercpu = tariff.getCurrencyValue().multiply(aggregationRatio);
cpuquotausgage = rawusage.multiply(onehourcostpercpu).multiply(cpu);
@ -373,7 +374,7 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager {
quotalist.add(quota_usage);
}
tariff = _quotaTariffDao.findTariffPlanByUsageType(QuotaTypes.CPU_CLOCK_RATE, usageRecord.getEndDate());
if (tariff != null && tariff.getCurrencyValue().compareTo(BigDecimal.ZERO) != 0) {
if (tariff != null && tariff.getCurrencyValue().compareTo(BigDecimal.ZERO) != 0 && serviceoffering.getSpeed() != null) {
BigDecimal speed = new BigDecimal(serviceoffering.getSpeed() / 100.00);
onehourcostper100mhz = tariff.getCurrencyValue().multiply(aggregationRatio);
speedquotausage = rawusage.multiply(onehourcostper100mhz).multiply(speed);
@ -383,7 +384,7 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager {
quotalist.add(quota_usage);
}
tariff = _quotaTariffDao.findTariffPlanByUsageType(QuotaTypes.MEMORY, usageRecord.getEndDate());
if (tariff != null && tariff.getCurrencyValue().compareTo(BigDecimal.ZERO) != 0) {
if (tariff != null && tariff.getCurrencyValue().compareTo(BigDecimal.ZERO) != 0 && serviceoffering.getRamSize() != null) {
BigDecimal memory = new BigDecimal(serviceoffering.getRamSize());
onehourcostper1mb = tariff.getCurrencyValue().multiply(aggregationRatio);
memoryquotausage = rawusage.multiply(onehourcostper1mb).multiply(memory);

View File

@ -122,15 +122,17 @@ public class QuotaStatementImpl extends ManagerBase implements QuotaStatement {
Date lastStatementDate = quotaAccount.getLastStatementDate();
if (interval != null) {
AccountVO account = _accountDao.findById(quotaAccount.getId());
if (lastStatementDate == null || getDifferenceDays(lastStatementDate, new Date()) >= s_LAST_STATEMENT_SENT_DAYS + 1) {
BigDecimal quotaUsage = _quotaUsage.findTotalQuotaUsage(account.getAccountId(), account.getDomainId(), null, interval[0].getTime(), interval[1].getTime());
s_logger.info("For account=" + quotaAccount.getId() + ", quota used = " + quotaUsage);
// send statement
deferredQuotaEmailList.add(new DeferredQuotaEmail(account, quotaAccount, quotaUsage, QuotaConfig.QuotaEmailTemplateTypes.QUOTA_STATEMENT));
} else {
if (s_logger.isDebugEnabled()) {
s_logger.debug("For " + quotaAccount.getId() + " the statement has been sent recently");
if (account != null) {
if (lastStatementDate == null || getDifferenceDays(lastStatementDate, new Date()) >= s_LAST_STATEMENT_SENT_DAYS + 1) {
BigDecimal quotaUsage = _quotaUsage.findTotalQuotaUsage(account.getAccountId(), account.getDomainId(), null, interval[0].getTime(), interval[1].getTime());
s_logger.info("For account=" + quotaAccount.getId() + ", quota used = " + quotaUsage);
// send statement
deferredQuotaEmailList.add(new DeferredQuotaEmail(account, quotaAccount, quotaUsage, QuotaConfig.QuotaEmailTemplateTypes.QUOTA_STATEMENT));
} else {
if (s_logger.isDebugEnabled()) {
s_logger.debug("For " + quotaAccount.getId() + " the statement has been sent recently");
}
}
}
} else if (lastStatementDate != null) {

View File

@ -59,7 +59,7 @@ public class QuotaSummaryCmd extends BaseListCmd {
public void execute() {
Account caller = CallContext.current().getCallingAccount();
List<QuotaSummaryResponse> responses;
if (caller.getAccountId() <= 2) { //non root admin or system
if (caller.getType() == Account.ACCOUNT_TYPE_ADMIN) { //admin account
if (getAccountName() != null && getDomainId() != null)
responses = _responseBuilder.createQuotaSummaryResponse(caller.getAccountName(), caller.getDomainId());
else

View File

@ -138,6 +138,7 @@ public class QuotaResponseBuilderImpl implements QuotaResponseBuilder {
} else {
for (final QuotaAccountVO quotaAccount : _quotaAccountDao.listAllQuotaAccount()) {
AccountVO account = _accountDao.findById(quotaAccount.getId());
if (account == null) continue;
QuotaSummaryResponse qr = getQuotaSummaryResponse(account);
result.add(qr);
}
@ -167,7 +168,7 @@ public class QuotaResponseBuilderImpl implements QuotaResponseBuilder {
qr.setObjectName("summary");
return qr;
} else {
throw new InvalidParameterValueException("Quota summary response for an account requires a valid account.");
return new QuotaSummaryResponse();
}
}
@ -398,6 +399,9 @@ public class QuotaResponseBuilderImpl implements QuotaResponseBuilder {
QuotaCreditsVO result = _quotaCreditsDao.saveCredits(credits);
final AccountVO account = _accountDao.findById(accountId);
if (account == null) {
throw new InvalidParameterValueException("Account does not exist with account id " + accountId);
}
final boolean lockAccountEnforcement = "true".equalsIgnoreCase(QuotaConfig.QuotaEnableEnforcement.value());
final BigDecimal currentAccountBalance = _quotaBalanceDao.lastQuotaBalance(accountId, domainId, startOfNextDay(new Date(despositedOn.getTime())));
if (s_logger.isDebugEnabled()) {

View File

@ -328,13 +328,6 @@
});
},
detailView: {
viewAll: [{
path: 'quota.quotastatement',
label: 'label.quota.statement.quota'
},{
path: 'quota.balancestatement',
label: 'label.quota.statement.balance'
}],
actions: {
add: {
label: 'label.quota.add.credits',