mirror of https://github.com/apache/cloudstack.git
quota: fixed transaction, boundary conditions
This commit is contained in:
parent
c13b329df7
commit
6688220cb2
|
|
@ -128,13 +128,10 @@ public class QuotaBalanceCmd extends BaseCmd {
|
|||
|
||||
QuotaBalanceResponse response;
|
||||
if (getEndDate() == null) {
|
||||
response = _quotaDBUtils.createQuotaLastBalanceResponse(quotaUsage);
|
||||
response = _quotaDBUtils.createQuotaLastBalanceResponse(quotaUsage, startDate);
|
||||
} else {
|
||||
response = _quotaDBUtils.createQuotaBalanceResponse(quotaUsage);
|
||||
response.setEndDate(endDate);
|
||||
response = _quotaDBUtils.createQuotaBalanceResponse(quotaUsage, startDate, endDate);
|
||||
}
|
||||
response.setStartDate(startDate);
|
||||
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,13 +40,13 @@ public interface QuotaDBUtils {
|
|||
|
||||
QuotaStatementResponse createQuotaStatementResponse(List<QuotaUsageVO> quotaUsage);
|
||||
|
||||
QuotaBalanceResponse createQuotaBalanceResponse(List<QuotaBalanceVO> quotaUsage);
|
||||
QuotaBalanceResponse createQuotaBalanceResponse(List<QuotaBalanceVO> quotaUsage, Date startDate, Date endDate);
|
||||
|
||||
Pair<List<? extends UsageVO>, Integer> getUsageRecords(long accountId, long domainId);
|
||||
|
||||
ServiceOfferingVO findServiceOffering(Long vmId, long serviceOfferingId);
|
||||
|
||||
QuotaBalanceResponse createQuotaLastBalanceResponse(List<QuotaBalanceVO> quotaBalance);
|
||||
QuotaBalanceResponse createQuotaLastBalanceResponse(List<QuotaBalanceVO> quotaBalance, Date startDate);
|
||||
|
||||
QuotaCreditsResponse addQuotaCredits(Long accountId, Long domainId, Double amount, Long updatedBy, Date despositedOn);
|
||||
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ public class QuotaDBUtilsImpl implements QuotaDBUtils {
|
|||
}
|
||||
|
||||
@Override
|
||||
public QuotaBalanceResponse createQuotaLastBalanceResponse(List<QuotaBalanceVO> quotaBalance) {
|
||||
public QuotaBalanceResponse createQuotaLastBalanceResponse(List<QuotaBalanceVO> quotaBalance, Date startDate) {
|
||||
if (quotaBalance.size() == 0) {
|
||||
new InvalidParameterValueException("There are no balance entries on or before the requested date.");
|
||||
}
|
||||
|
|
@ -101,17 +101,17 @@ public class QuotaDBUtilsImpl implements QuotaDBUtils {
|
|||
lastCredits=lastCredits.add(entry.getCreditBalance());
|
||||
}
|
||||
else {
|
||||
resp.setStartDate(entry.getUpdatedOn());
|
||||
resp.setStartQuota(entry.getCreditBalance().add(lastCredits));
|
||||
break; // add only consecutive credit entries
|
||||
}
|
||||
}
|
||||
resp.setStartDate(startDate);
|
||||
resp.setObjectName("balance");
|
||||
return resp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QuotaBalanceResponse createQuotaBalanceResponse(List<QuotaBalanceVO> quotaBalance) {
|
||||
public QuotaBalanceResponse createQuotaBalanceResponse(List<QuotaBalanceVO> quotaBalance, Date startDate, Date endDate) {
|
||||
if (quotaBalance.size() == 0) {
|
||||
new InvalidParameterValueException("The request period does not contain balance entries.");
|
||||
}
|
||||
|
|
@ -133,9 +133,9 @@ public class QuotaDBUtilsImpl implements QuotaDBUtils {
|
|||
if (quotaBalance.size() > 0) {
|
||||
QuotaBalanceVO startItem = quotaBalance.get(0);
|
||||
QuotaBalanceVO endItem = quotaBalance.get(quotaBalance.size() - 1);
|
||||
resp.setStartDate(startItem.getUpdatedOn());
|
||||
resp.setStartDate(startDate);
|
||||
resp.setStartQuota(startItem.getCreditBalance());
|
||||
resp.setEndDate(endItem.getUpdatedOn());
|
||||
resp.setEndDate(endDate);
|
||||
resp.setEndQuota(endItem.getCreditBalance());
|
||||
} else {
|
||||
resp.setStartQuota(new BigDecimal(0));
|
||||
|
|
|
|||
|
|
@ -154,34 +154,36 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager {
|
|||
} while ((usageRecords != null) && !usageRecords.first().isEmpty());
|
||||
// list of quotas for this account
|
||||
s_logger.info("Quota entries size = " + quotalistforaccount.size());
|
||||
quotalistforaccount.add(new QuotaUsageVO());
|
||||
Date startDate = new Date(0);
|
||||
Date endDate = new Date(0);
|
||||
BigDecimal aggrUsage = new BigDecimal(0);
|
||||
for (QuotaUsageVO entry : quotalistforaccount) {
|
||||
if (startDate.compareTo(entry.getStartDate()) != 0) {
|
||||
QuotaBalanceVO lastrealbalanceentry = _quotaBalanceDao.findLastBalanceEntry(account.getAccountId(), account.getDomainId(), startDate);
|
||||
Date lastbalancedate;
|
||||
if (lastrealbalanceentry != null) {
|
||||
lastbalancedate = lastrealbalanceentry.getUpdatedOn();
|
||||
aggrUsage = aggrUsage.add(lastrealbalanceentry.getCreditBalance());
|
||||
} else {
|
||||
lastbalancedate = new Date(0);
|
||||
}
|
||||
if (quotalistforaccount.size() > 0) { // balance to be processed
|
||||
quotalistforaccount.add(new QuotaUsageVO());
|
||||
Date startDate = new Date(0);
|
||||
Date endDate = new Date(0);
|
||||
BigDecimal aggrUsage = new BigDecimal(0);
|
||||
for (QuotaUsageVO entry : quotalistforaccount) {
|
||||
if (startDate.compareTo(entry.getStartDate()) != 0) {
|
||||
QuotaBalanceVO lastrealbalanceentry = _quotaBalanceDao.findLastBalanceEntry(account.getAccountId(), account.getDomainId(), startDate);
|
||||
Date lastbalancedate;
|
||||
if (lastrealbalanceentry != null) {
|
||||
lastbalancedate = lastrealbalanceentry.getUpdatedOn();
|
||||
aggrUsage = aggrUsage.add(lastrealbalanceentry.getCreditBalance());
|
||||
} else {
|
||||
lastbalancedate = new Date(0);
|
||||
}
|
||||
|
||||
List<QuotaBalanceVO> creditsrcvd = _quotaBalanceDao.findCreditBalance(account.getAccountId(), account.getDomainId(), lastbalancedate, endDate);
|
||||
for (QuotaBalanceVO credit : creditsrcvd) {
|
||||
aggrUsage = aggrUsage.add(credit.getCreditBalance());
|
||||
}
|
||||
List<QuotaBalanceVO> creditsrcvd = _quotaBalanceDao.findCreditBalance(account.getAccountId(), account.getDomainId(), lastbalancedate, endDate);
|
||||
for (QuotaBalanceVO credit : creditsrcvd) {
|
||||
aggrUsage = aggrUsage.add(credit.getCreditBalance());
|
||||
}
|
||||
|
||||
QuotaBalanceVO newbalance = new QuotaBalanceVO(account.getAccountId(), account.getDomainId(), aggrUsage, endDate);
|
||||
_quotaBalanceDao.persist(newbalance);
|
||||
aggrUsage = new BigDecimal(0);
|
||||
QuotaBalanceVO newbalance = new QuotaBalanceVO(account.getAccountId(), account.getDomainId(), aggrUsage, endDate);
|
||||
_quotaBalanceDao.persist(newbalance);
|
||||
aggrUsage = new BigDecimal(0);
|
||||
}
|
||||
startDate = entry.getStartDate();
|
||||
endDate = entry.getEndDate();
|
||||
aggrUsage = aggrUsage.subtract(entry.getQuotaUsed());
|
||||
}
|
||||
startDate = entry.getStartDate();
|
||||
endDate = entry.getEndDate();
|
||||
aggrUsage = aggrUsage.subtract(entry.getQuotaUsed());
|
||||
}
|
||||
}// balance processed
|
||||
} // END ACCOUNT
|
||||
jobResult = true;
|
||||
} catch (Exception e) {
|
||||
|
|
|
|||
|
|
@ -168,12 +168,26 @@ public class QuotaServiceImpl extends ManagerBase implements QuotaService, Confi
|
|||
Date adjustedStartDate = computeAdjustedTime(startDate, usageTZ);
|
||||
|
||||
if (endDate == null) {
|
||||
s_logger.debug("getting quota balance records for account: " + accountId + ", domainId: " + domainId + ", on or before " + adjustedStartDate);
|
||||
return _quotaBalanceDao.findQuotaBalance(accountId, domainId, adjustedStartDate);
|
||||
s_logger.debug("Getting quota balance records for account: " + accountId + ", domainId: " + domainId + ", on or before " + adjustedStartDate);
|
||||
List<QuotaBalanceVO> qbrecords = _quotaBalanceDao.findQuotaBalance(accountId, domainId, adjustedStartDate);
|
||||
s_logger.info("Found records size=" + qbrecords.size());
|
||||
if (qbrecords.size() == 0){
|
||||
throw new InvalidParameterValueException("Incorrect Date there are no quota records before this date " + adjustedStartDate);
|
||||
}
|
||||
else {
|
||||
return qbrecords;
|
||||
}
|
||||
} else if (startDate.before(endDate)) {
|
||||
Date adjustedEndDate = computeAdjustedTime(endDate, usageTZ);
|
||||
s_logger.debug("getting quota balance records for account: " + accountId + ", domainId: " + domainId + ", between " + adjustedStartDate + " and " + adjustedEndDate);
|
||||
return _quotaBalanceDao.findQuotaBalance(accountId, domainId, adjustedStartDate, adjustedEndDate);
|
||||
s_logger.debug("Getting quota balance records for account: " + accountId + ", domainId: " + domainId + ", between " + adjustedStartDate + " and " + adjustedEndDate);
|
||||
List<QuotaBalanceVO> qbrecords = _quotaBalanceDao.findQuotaBalance(accountId, domainId, adjustedStartDate, adjustedEndDate);
|
||||
s_logger.info("Found records size=" + qbrecords.size());
|
||||
if (qbrecords.size() == 0){
|
||||
throw new InvalidParameterValueException("Incorrect Date range there are no quota records between these dates start date " + adjustedStartDate + " and end date:" + endDate);
|
||||
}
|
||||
else {
|
||||
return qbrecords;
|
||||
}
|
||||
} else {
|
||||
throw new InvalidParameterValueException("Incorrect Date Range. Start date: " + startDate + " is after end date:" + endDate);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,12 +18,14 @@ package org.apache.cloudstack.quota.dao;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import javax.ejb.Local;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.apache.cloudstack.quota.QuotaBalanceVO;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
|
|
@ -33,6 +35,7 @@ import com.cloud.utils.db.TransactionLegacy;
|
|||
@Component
|
||||
@Local(value = { QuotaBalanceDao.class })
|
||||
public class QuotaBalanceDaoImpl extends GenericDaoBase<QuotaBalanceVO, Long> implements QuotaBalanceDao {
|
||||
private static final Logger s_logger = Logger.getLogger(QuotaBalanceDaoImpl.class.getName());
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
|
|
@ -121,6 +124,21 @@ public class QuotaBalanceDaoImpl extends GenericDaoBase<QuotaBalanceVO, Long> im
|
|||
return new ArrayList<QuotaBalanceVO>();
|
||||
}
|
||||
quotaUsageRecords = listBy(sc);
|
||||
|
||||
// get records before startDate to find start balance
|
||||
List<QuotaBalanceVO> quotaUsageOnOrBeforeStartDate = findQuotaBalance(accountId, domainId, startDate);
|
||||
for (Iterator<QuotaBalanceVO> it = quotaUsageOnOrBeforeStartDate.iterator(); it.hasNext();) {
|
||||
QuotaBalanceVO entry = it.next();
|
||||
s_logger.info("Date=" + entry.getUpdatedOn().toGMTString() + " balance=" + entry.getCreditBalance() + " credit=" + entry.getCreditsId());
|
||||
if (entry.getCreditsId() > 0) {
|
||||
quotaUsageRecords.add(entry);
|
||||
} else {
|
||||
quotaUsageRecords.add(entry);
|
||||
break; // add only consecutive credit entries and last
|
||||
// balance entry
|
||||
}
|
||||
}
|
||||
|
||||
} finally {
|
||||
txn.close();
|
||||
}
|
||||
|
|
@ -136,6 +154,7 @@ public class QuotaBalanceDaoImpl extends GenericDaoBase<QuotaBalanceVO, Long> im
|
|||
|
||||
TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB);
|
||||
List<QuotaBalanceVO> quotaUsageRecords = null;
|
||||
List<QuotaBalanceVO> trimmedRecords = new ArrayList<QuotaBalanceVO>();
|
||||
try {
|
||||
Filter filter = new Filter(QuotaBalanceVO.class, "updatedOn", false, 0L, 100L);
|
||||
// ASSUMPTION there will be less than 100 continuous credit
|
||||
|
|
@ -151,12 +170,26 @@ public class QuotaBalanceDaoImpl extends GenericDaoBase<QuotaBalanceVO, Long> im
|
|||
sc.addAnd("updatedOn", SearchCriteria.Op.LTEQ, startDate);
|
||||
}
|
||||
quotaUsageRecords = search(sc, filter);
|
||||
|
||||
// get records before startDate to find start balance
|
||||
for (Iterator<QuotaBalanceVO> it = quotaUsageRecords.iterator(); it.hasNext();) {
|
||||
QuotaBalanceVO entry = it.next();
|
||||
s_logger.info("Date=" + entry.getUpdatedOn().toGMTString() + " balance=" + entry.getCreditBalance() + " credit=" + entry.getCreditsId());
|
||||
if (entry.getCreditsId() > 0) {
|
||||
trimmedRecords.add(entry);
|
||||
} else {
|
||||
trimmedRecords.add(entry);
|
||||
break; // add only consecutive credit entries and last
|
||||
// balance entry
|
||||
}
|
||||
}
|
||||
|
||||
} finally {
|
||||
txn.close();
|
||||
}
|
||||
|
||||
TransactionLegacy.open(opendb).close();
|
||||
return quotaUsageRecords;
|
||||
return trimmedRecords;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ public class QuotaTariffDaoImpl extends GenericDaoBase<QuotaTariffVO, Long> impl
|
|||
|
||||
@Override
|
||||
public QuotaTariffVO findTariffPlanByUsageType(final int usageType) {
|
||||
short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
QuotaTariffVO result = null;
|
||||
TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB);
|
||||
try {
|
||||
|
|
@ -53,14 +54,15 @@ public class QuotaTariffDaoImpl extends GenericDaoBase<QuotaTariffVO, Long> impl
|
|||
result = findOneBy(sc);
|
||||
} finally {
|
||||
txn.close();
|
||||
// Switch back to Cloud DB
|
||||
TransactionLegacy.open(TransactionLegacy.CLOUD_DB).close();
|
||||
// Switch back
|
||||
TransactionLegacy.open(opendb).close();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<QuotaTariffVO> listAllTariffPlans() {
|
||||
short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
List<QuotaTariffVO> result = null;
|
||||
TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB);
|
||||
try {
|
||||
|
|
@ -69,17 +71,19 @@ public class QuotaTariffDaoImpl extends GenericDaoBase<QuotaTariffVO, Long> impl
|
|||
result = listBy(sc);
|
||||
} finally {
|
||||
txn.close();
|
||||
// Switch back to Cloud DB
|
||||
TransactionLegacy.open(TransactionLegacy.CLOUD_DB).close();
|
||||
// Switch back
|
||||
TransactionLegacy.open(opendb).close();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateQuotaTariff(QuotaTariffVO plan) {
|
||||
TransactionLegacy.open(TransactionLegacy.USAGE_DB).close(); // Switch to Usage DB
|
||||
short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
TransactionLegacy.open(TransactionLegacy.USAGE_DB).close(); // Switch to
|
||||
// Usage DB
|
||||
boolean result = this.update(plan.getId(), plan);
|
||||
TransactionLegacy.open(TransactionLegacy.CLOUD_DB).close(); // Switch back to Cloud DB
|
||||
TransactionLegacy.open(opendb).close(); // Switch back
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue