From 7c4c67b52021412f627ebd65aacf26749f7be6cb Mon Sep 17 00:00:00 2001 From: Abhinandan Prateek Date: Wed, 29 Jul 2015 17:20:58 +0530 Subject: [PATCH] quota fixed misc boundary conditions --- .../api/command/QuotaStatementCmd.java | 2 +- .../api/response/QuotaBalanceResponse.java | 2 +- .../response/QuotaResponseBuilderImpl.java | 24 ++++++------- .../apache/cloudstack/quota/QuotaService.java | 4 +++ .../cloudstack/quota/QuotaServiceImpl.java | 36 +++++++++++++------ .../cloudstack/quota/dao/QuotaBalanceDao.java | 2 -- .../quota/dao/QuotaBalanceDaoImpl.java | 9 ++--- .../quota/job/QuotaManagerImpl.java | 24 +++++++++---- 8 files changed, 64 insertions(+), 39 deletions(-) diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/command/QuotaStatementCmd.java b/plugins/database/quota/src/org/apache/cloudstack/api/command/QuotaStatementCmd.java index 978002c1eb4..9ec1a3d349c 100644 --- a/plugins/database/quota/src/org/apache/cloudstack/api/command/QuotaStatementCmd.java +++ b/plugins/database/quota/src/org/apache/cloudstack/api/command/QuotaStatementCmd.java @@ -123,7 +123,7 @@ public class QuotaStatementCmd extends BaseCmd { @Override public long getEntityOwnerId() { - Long accountId = _accountService.finalyzeAccountId(accountName, domainId, null, true); + Long accountId = _accountService.getActiveAccountByName(accountName, domainId).getAccountId(); if (accountId == null) { return CallContext.current().getCallingAccount().getId(); } diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaBalanceResponse.java b/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaBalanceResponse.java index fc78b954b22..2e0c23f21ec 100644 --- a/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaBalanceResponse.java +++ b/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaBalanceResponse.java @@ -124,7 +124,7 @@ public class QuotaBalanceResponse extends BaseResponse { QuotaCreditsResponse cr = new QuotaCreditsResponse(); cr.setCredits(credit.getCreditBalance()); cr.setUpdatedOn(credit.getUpdatedOn()); - credits.add(cr); + credits.add(0, cr); } public Date getStartDate() { diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaResponseBuilderImpl.java b/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaResponseBuilderImpl.java index 3b50aecf3e2..4eb6758b6f2 100644 --- a/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaResponseBuilderImpl.java +++ b/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaResponseBuilderImpl.java @@ -104,31 +104,31 @@ public class QuotaResponseBuilderImpl implements QuotaResponseBuilder { } Collections.sort(quotaBalance, new Comparator() { public int compare(QuotaBalanceVO o1, QuotaBalanceVO o2) { - return o1.getUpdatedOn().compareTo(o2.getUpdatedOn()); // asc + return o2.getUpdatedOn().compareTo(o1.getUpdatedOn()); // desc } }); QuotaBalanceResponse resp = new QuotaBalanceResponse(); BigDecimal lastCredits = new BigDecimal(0); - boolean consecutive=true; + boolean consecutive = true; for (Iterator it = quotaBalance.iterator(); it.hasNext();) { QuotaBalanceVO entry = it.next(); - s_logger.info("Date=" + entry.getUpdatedOn().toGMTString() + " balance=" + entry.getCreditBalance() + " credit=" + entry.getCreditsId()); + s_logger.info("createQuotaBalanceResponse: Date=" + entry.getUpdatedOn().toGMTString() + " balance=" + entry.getCreditBalance() + " credit=" + entry.getCreditsId()); if (entry.getCreditsId() > 0) { - if (consecutive){ + if (consecutive) { lastCredits = lastCredits.add(entry.getCreditBalance()); } resp.addCredits(entry); it.remove(); - } - else { - consecutive= false; + } else { + consecutive = false; } } if (quotaBalance.size() > 0) { - QuotaBalanceVO startItem = quotaBalance.get(0); - QuotaBalanceVO endItem = quotaBalance.get(quotaBalance.size() - 1); + // order is desc last item is the start item + QuotaBalanceVO startItem = quotaBalance.get(quotaBalance.size() - 1); + QuotaBalanceVO endItem = quotaBalance.get(0); resp.setStartDate(startDate); resp.setStartQuota(startItem.getCreditBalance()); resp.setEndDate(endDate); @@ -216,7 +216,7 @@ public class QuotaResponseBuilderImpl implements QuotaResponseBuilder { result.add(tariffPlan); } } else { - result = _quotaTariffDao.listAllTariffPlans(now); + result = _quotaTariffDao.listAllTariffPlans(_quotaService.startOfNextDay(now)); } return result; } @@ -287,7 +287,7 @@ public class QuotaResponseBuilderImpl implements QuotaResponseBuilder { TransactionLegacy.open(TransactionLegacy.CLOUD_DB).close(); final AccountVO account = _accountDao.findById(accountId); final boolean lockAccountEnforcement = QuotaConfig.QuotaEnableEnforcement.value().equalsIgnoreCase("true"); - final BigDecimal currentAccountBalance = _quotaBalanceDao.lastQuotaBalance(accountId, domainId, new Date()); + final BigDecimal currentAccountBalance = _quotaBalanceDao.lastQuotaBalance(accountId, domainId, _quotaService.startOfNextDay()); if (lockAccountEnforcement && (currentAccountBalance.compareTo(new BigDecimal(0)) >= 0)) { if (account.getState() == Account.State.locked) { try { @@ -372,7 +372,7 @@ public class QuotaResponseBuilderImpl implements QuotaResponseBuilder { resp.addCredits(entry); } resp.setEndQuota(lastCredits); - resp.setEndDate(_quotaService.computeAdjustedTime(new Date())); + resp.setEndDate(_quotaService.computeAdjustedTime(_quotaService.startOfNextDay())); resp.setCurrency(QuotaConfig.QuotaCurrencySymbol.value()); resp.setObjectName("balance"); return resp; diff --git a/plugins/database/quota/src/org/apache/cloudstack/quota/QuotaService.java b/plugins/database/quota/src/org/apache/cloudstack/quota/QuotaService.java index 19eb7a3b18f..e48bfba428a 100644 --- a/plugins/database/quota/src/org/apache/cloudstack/quota/QuotaService.java +++ b/plugins/database/quota/src/org/apache/cloudstack/quota/QuotaService.java @@ -31,4 +31,8 @@ public interface QuotaService extends PluggableService { List getQuotaBalance(Long accountId, String accountName, Long domainId, Date startDate, Date endDate); Date computeAdjustedTime(Date date); + + Date startOfNextDay(Date dt); + + Date startOfNextDay(); } diff --git a/plugins/database/quota/src/org/apache/cloudstack/quota/QuotaServiceImpl.java b/plugins/database/quota/src/org/apache/cloudstack/quota/QuotaServiceImpl.java index 9155d71ea4a..30069dcb190 100644 --- a/plugins/database/quota/src/org/apache/cloudstack/quota/QuotaServiceImpl.java +++ b/plugins/database/quota/src/org/apache/cloudstack/quota/QuotaServiceImpl.java @@ -171,11 +171,10 @@ public class QuotaServiceImpl extends ManagerBase implements QuotaService, Confi } else { return qbrecords; } - } if (endDate.after(new Date())) { + } else if (endDate.after(startOfNextDay(new Date()))) { throw new InvalidParameterValueException("Incorrect Date Range. End date:" + endDate + " should not be in future. "); - } - else if (startDate.before(endDate)) { - Date adjustedEndDate = computeAdjustedTime(endDate); + } else if (startDate.before(endDate)) { + Date adjustedEndDate = startOfNextDay(endDate); s_logger.debug("Getting quota balance records for account: " + accountId + ", domainId: " + domainId + ", between " + adjustedStartDate + " and " + adjustedEndDate); List qbrecords = _quotaBalanceDao.findQuotaBalance(accountId, domainId, adjustedStartDate, adjustedEndDate); s_logger.info("Found records size=" + qbrecords.size()); @@ -187,6 +186,7 @@ public class QuotaServiceImpl extends ManagerBase implements QuotaService, Confi } else { throw new InvalidParameterValueException("Incorrect Date Range. Start date: " + startDate + " is after end date:" + endDate); } + } @Override @@ -215,18 +215,16 @@ public class QuotaServiceImpl extends ManagerBase implements QuotaService, Confi } TransactionLegacy.open(opendb).close(); + endDate = startOfNextDay(endDate); if (startDate.after(endDate)) { throw new InvalidParameterValueException("Incorrect Date Range. Start date: " + startDate + " is after end date:" + endDate); } - if (endDate.after(new Date())) { + if (endDate.after(startOfNextDay(new Date()))) { throw new InvalidParameterValueException("Incorrect Date Range. End date:" + endDate + " should not be in future. "); } - Date adjustedStartDate = computeAdjustedTime(startDate); - Date adjustedEndDate = computeAdjustedTime(endDate); - - s_logger.debug("Getting quota records for account: " + accountId + ", domainId: " + domainId + ", between " + adjustedStartDate + " and " + adjustedEndDate); - return _quotaUsageDao.findQuotaUsage(accountId, domainId, usageType, adjustedStartDate, adjustedEndDate); + s_logger.debug("Getting quota records for account: " + accountId + ", domainId: " + domainId + ", between " + startDate + " and " + endDate); + return _quotaUsageDao.findQuotaUsage(accountId, domainId, usageType, startDate, endDate); } @Override @@ -254,4 +252,22 @@ public class QuotaServiceImpl extends ManagerBase implements QuotaService, Confi return calTS.getTime(); } + @Override + public Date startOfNextDay(Date dt) { + Calendar c = Calendar.getInstance(); + c.setTime(dt); + c.add(Calendar.DATE, 1); + dt = c.getTime(); + return dt; + } + + @Override + public Date startOfNextDay() { + Calendar c = Calendar.getInstance(); + c.setTime(new Date()); + c.add(Calendar.DATE, 1); + Date dt = c.getTime(); + return dt; + } + } diff --git a/plugins/database/quota/src/org/apache/cloudstack/quota/dao/QuotaBalanceDao.java b/plugins/database/quota/src/org/apache/cloudstack/quota/dao/QuotaBalanceDao.java index 1f6a961241e..2e478775730 100644 --- a/plugins/database/quota/src/org/apache/cloudstack/quota/dao/QuotaBalanceDao.java +++ b/plugins/database/quota/src/org/apache/cloudstack/quota/dao/QuotaBalanceDao.java @@ -40,6 +40,4 @@ public interface QuotaBalanceDao extends GenericDao { BigDecimal lastQuotaBalance(Long accountId, Long domainId, Date startDate); - BigDecimal lastQuotaBalance(Long accountId, Long domainId); - } diff --git a/plugins/database/quota/src/org/apache/cloudstack/quota/dao/QuotaBalanceDaoImpl.java b/plugins/database/quota/src/org/apache/cloudstack/quota/dao/QuotaBalanceDaoImpl.java index dd2b71c9a66..4830a52ad11 100644 --- a/plugins/database/quota/src/org/apache/cloudstack/quota/dao/QuotaBalanceDaoImpl.java +++ b/plugins/database/quota/src/org/apache/cloudstack/quota/dao/QuotaBalanceDaoImpl.java @@ -163,7 +163,7 @@ public class QuotaBalanceDaoImpl extends GenericDaoBase im // get records before startDate to find start balance for (Iterator it = quotaUsageRecords.iterator(); it.hasNext();) { QuotaBalanceVO entry = it.next(); - s_logger.info("Date=" + entry.getUpdatedOn().toGMTString() + " balance=" + entry.getCreditBalance() + " credit=" + entry.getCreditsId()); + s_logger.info("findQuotaBalance Date=" + entry.getUpdatedOn().toGMTString() + " balance=" + entry.getCreditBalance() + " credit=" + entry.getCreditsId()); if (entry.getCreditsId() > 0) { trimmedRecords.add(entry); } else { @@ -181,11 +181,6 @@ public class QuotaBalanceDaoImpl extends GenericDaoBase im return trimmedRecords; } - @Override - public BigDecimal lastQuotaBalance(final Long accountId, final Long domainId) { - return lastQuotaBalance(accountId, domainId, new Date()); - } - @Override public BigDecimal lastQuotaBalance(final Long accountId, final Long domainId, Date startDate) { List quotaBalance = findQuotaBalance(accountId, domainId, startDate); @@ -195,7 +190,7 @@ public class QuotaBalanceDaoImpl extends GenericDaoBase im BigDecimal finalBalance = new BigDecimal(0); for (Iterator it = quotaBalance.iterator(); it.hasNext();) { QuotaBalanceVO entry = it.next(); - s_logger.info("Date=" + entry.getUpdatedOn().toGMTString() + " balance=" + entry.getCreditBalance() + " credit=" + entry.getCreditsId()); + s_logger.info("lastQuotaBalance Date=" + entry.getUpdatedOn().toGMTString() + " balance=" + entry.getCreditBalance() + " credit=" + entry.getCreditsId()); finalBalance.add(entry.getCreditBalance()); } return finalBalance; diff --git a/plugins/database/quota/src/org/apache/cloudstack/quota/job/QuotaManagerImpl.java b/plugins/database/quota/src/org/apache/cloudstack/quota/job/QuotaManagerImpl.java index 855c3d69c0d..d60cc2e4546 100644 --- a/plugins/database/quota/src/org/apache/cloudstack/quota/job/QuotaManagerImpl.java +++ b/plugins/database/quota/src/org/apache/cloudstack/quota/job/QuotaManagerImpl.java @@ -39,6 +39,7 @@ 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 org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.quota.constant.QuotaConfig; import org.apache.cloudstack.quota.constant.QuotaTypes; @@ -66,10 +67,12 @@ import javax.mail.Session; import javax.mail.URLName; import javax.mail.internet.InternetAddress; import javax.naming.ConfigurationException; + import java.io.UnsupportedEncodingException; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.ArrayList; +import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -268,8 +271,8 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager { } private void checkAndSendQuotaAlertEmails() { - List deferredQuotaEmailList = new ArrayList(); - final Date currentDate = new Date(); + List deferredQuotaEmailList = new ArrayList(); + final Date currentDate = startOfNextDay(); final BigDecimal zeroBalance = new BigDecimal(0); final BigDecimal thresholdBalance = new BigDecimal(QuotaConfig.QuotaLimitCritical.value()); final boolean lockAccountEnforcement = QuotaConfig.QuotaEnableEnforcement.value().equalsIgnoreCase("true"); @@ -291,7 +294,7 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager { } } - for (DeferredQuotaEmail emailToBeSent: deferredQuotaEmailList) { + for (DeferredQuotaEmail emailToBeSent : deferredQuotaEmailList) { s_logger.debug("Attempting to send quota alert email to users of account: " + emailToBeSent.getAccount().getAccountName()); sendQuotaAlert(emailToBeSent); } @@ -460,7 +463,7 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager { String userNames = ""; final List emailRecipients = new ArrayList(); - for (UserVO user: usersInAccount) { + for (UserVO user : usersInAccount) { userNames += String.format("%s <%s>,", user.getUsername(), user.getEmail()); emailRecipients.add(user.getEmail()); } @@ -482,7 +485,8 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager { try { _emailQuotaAlert.sendQuotaAlert(emailRecipients, subject, body); } 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(), account.getUuid(), emailRecipients, 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(), + account.getUuid(), emailRecipients, e)); } } else { s_logger.error(String.format("No quota email template found for type %s, cannot send quota alert email to account %s(%s)", emailType, account.getAccountName(), account.getUuid())); @@ -568,7 +572,7 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager { msg.setSender(new InternetAddress(_emailSender, _emailSender)); msg.setFrom(new InternetAddress(_emailSender, _emailSender)); - for (String email: emails) { + for (String email : emails) { if (email != null && !email.isEmpty()) { try { InternetAddress address = new InternetAddress(email, email); @@ -599,4 +603,12 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager { } } + public Date startOfNextDay() { + Calendar c = Calendar.getInstance(); + c.setTime(new Date()); + c.add(Calendar.DATE, 1); + Date dt = c.getTime(); + return dt; + } + }