diff --git a/framework/quota/src/org/apache/cloudstack/quota/dao/QuotaUsageDao.java b/framework/quota/src/org/apache/cloudstack/quota/dao/QuotaUsageDao.java index 462e3b21bb6..9a4312e442f 100644 --- a/framework/quota/src/org/apache/cloudstack/quota/dao/QuotaUsageDao.java +++ b/framework/quota/src/org/apache/cloudstack/quota/dao/QuotaUsageDao.java @@ -17,6 +17,7 @@ package org.apache.cloudstack.quota.dao; import com.cloud.utils.db.GenericDao; + import org.apache.cloudstack.quota.vo.QuotaUsageVO; import java.math.BigDecimal; @@ -30,4 +31,6 @@ public interface QuotaUsageDao extends GenericDao { List findQuotaUsage(Long accountId, Long domainId, Integer usageType, Date startDate, Date endDate); BigDecimal findTotalQuotaUsage(Long accountId, Long domainId, Integer usageType, Date startDate, Date endDate); + + QuotaUsageVO findLastQuotaUsageEntry(Long accountId, Long domainId, Date beforeThis); } diff --git a/framework/quota/src/org/apache/cloudstack/quota/dao/QuotaUsageDaoImpl.java b/framework/quota/src/org/apache/cloudstack/quota/dao/QuotaUsageDaoImpl.java index 2a565ff1f78..870ceebd6f9 100644 --- a/framework/quota/src/org/apache/cloudstack/quota/dao/QuotaUsageDaoImpl.java +++ b/framework/quota/src/org/apache/cloudstack/quota/dao/QuotaUsageDaoImpl.java @@ -16,6 +16,7 @@ //under the License. package org.apache.cloudstack.quota.dao; +import com.cloud.utils.db.Filter; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.QueryBuilder; import com.cloud.utils.db.SearchCriteria; @@ -74,6 +75,22 @@ public class QuotaUsageDaoImpl extends GenericDaoBase implem }); } + public QuotaUsageVO findLastQuotaUsageEntry(final Long accountId, final Long domainId, final Date beforeThis) { + return Transaction.execute(TransactionLegacy.USAGE_DB, new TransactionCallback() { + @Override + public QuotaUsageVO doInTransaction(final TransactionStatus status) { + List quotaUsageEntries = new ArrayList<>(); + Filter filter = new Filter(QuotaUsageVO.class, "startDate", false, 0L, 1L); + QueryBuilder qb = QueryBuilder.create(QuotaUsageVO.class); + qb.and(qb.entity().getAccountId(), SearchCriteria.Op.EQ, accountId); + qb.and(qb.entity().getDomainId(), SearchCriteria.Op.EQ, domainId); + qb.and(qb.entity().getStartDate(), SearchCriteria.Op.LT, beforeThis); + quotaUsageEntries = search(qb.create(), filter); + return !quotaUsageEntries.isEmpty() ? quotaUsageEntries.get(0) : null; + } + }); + } + public QuotaUsageVO persistQuotaUsage(final QuotaUsageVO quotaUsage) { return Transaction.execute(TransactionLegacy.USAGE_DB, new TransactionCallback() { @Override diff --git a/usage/src/org/apache/cloudstack/quota/QuotaManagerImpl.java b/usage/src/org/apache/cloudstack/quota/QuotaManagerImpl.java index 7d8bb54379d..e63a276975b 100644 --- a/usage/src/org/apache/cloudstack/quota/QuotaManagerImpl.java +++ b/usage/src/org/apache/cloudstack/quota/QuotaManagerImpl.java @@ -186,8 +186,33 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager { Date startDate = quotaListForAccount.get(0).getStartDate(); Date endDate = quotaListForAccount.get(0).getEndDate(); BigDecimal aggrUsage = new BigDecimal(0); + List creditsReceived = null; + + //bootstrapping + QuotaUsageVO lastQuotaUsage = _quotaUsageDao.findLastQuotaUsageEntry(account.getAccountId(), account.getDomainId(), startDate); + if (lastQuotaUsage == null) { + creditsReceived = _quotaBalanceDao.findCreditBalance(account.getAccountId(), account.getDomainId(), new Date(0), startDate); + if (creditsReceived != null) { + for (QuotaBalanceVO credit : creditsReceived) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Credit entry found " + aggrUsage.setScale(6, RoundingMode.HALF_EVEN).toString() + " on Date=" + startDate); + } + aggrUsage = aggrUsage.add(credit.getCreditBalance()); + } + } + } for (QuotaUsageVO entry : quotaListForAccount) { if (entry.getQuotaUsed().compareTo(BigDecimal.ZERO) == 0) { + // check if there were credits + creditsReceived = _quotaBalanceDao.findCreditBalance(account.getAccountId(), account.getDomainId(), entry.getStartDate(), entry.getEndDate()); + if (creditsReceived != null) { + for (QuotaBalanceVO credit : creditsReceived) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Credit entry found " + aggrUsage.setScale(6, RoundingMode.HALF_EVEN).toString() + " on Date=" + entry.getStartDate()); + } + aggrUsage = aggrUsage.add(credit.getCreditBalance()); + } + } continue; } if (s_logger.isDebugEnabled()) { @@ -207,13 +232,13 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager { startDate = entry.getStartDate(); endDate = entry.getEndDate(); - QuotaBalanceVO lastRealBalanceEntry = _quotaBalanceDao.findLastBalanceEntry(account.getAccountId(), account.getDomainId(), startDate); + QuotaBalanceVO lastRealBalanceEntry = _quotaBalanceDao.findLastBalanceEntry(account.getAccountId(), account.getDomainId(), endDate); Date lastBalanceDate = new Date(0); if (lastRealBalanceEntry != null) { lastBalanceDate = lastRealBalanceEntry.getUpdatedOn(); aggrUsage = aggrUsage.add(lastRealBalanceEntry.getCreditBalance()); } - List creditsReceived = _quotaBalanceDao.findCreditBalance(account.getAccountId(), account.getDomainId(), lastBalanceDate, endDate); + creditsReceived = _quotaBalanceDao.findCreditBalance(account.getAccountId(), account.getDomainId(), lastBalanceDate, endDate); if (creditsReceived != null) { for (QuotaBalanceVO credit : creditsReceived) { aggrUsage = aggrUsage.add(credit.getCreditBalance());