Skip to content

Commit 6c9f0c1

Browse files
authored
Fix apache#3448 quota calculation for monthly tariffs (apache#5517)
* Fix quota calculation for monthly tariffs * Remove unused parameter
1 parent 81b49b8 commit 6c9f0c1

2 files changed

Lines changed: 20 additions & 21 deletions

File tree

framework/quota/src/main/java/org/apache/cloudstack/quota/QuotaManagerImpl.java

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -139,16 +139,15 @@ public List<QuotaUsageVO> aggregatePendingQuotaRecordsForAccount(final AccountVO
139139
}
140140
s_logger.info("Getting pending quota records for account=" + account.getAccountName());
141141
for (UsageVO usageRecord : usageRecords.first()) {
142-
BigDecimal aggregationRatio = new BigDecimal(_aggregationDuration).divide(s_minutesInMonth, 8, RoundingMode.HALF_EVEN);
143142
switch (usageRecord.getUsageType()) {
144143
case QuotaTypes.RUNNING_VM:
145-
List<QuotaUsageVO> lq = updateQuotaRunningVMUsage(usageRecord, aggregationRatio);
144+
List<QuotaUsageVO> lq = updateQuotaRunningVMUsage(usageRecord);
146145
if (!lq.isEmpty()) {
147146
quotaListForAccount.addAll(lq);
148147
}
149148
break;
150149
case QuotaTypes.ALLOCATED_VM:
151-
QuotaUsageVO qu = updateQuotaAllocatedVMUsage(usageRecord, aggregationRatio);
150+
QuotaUsageVO qu = updateQuotaAllocatedVMUsage(usageRecord);
152151
if (qu != null) {
153152
quotaListForAccount.add(qu);
154153
}
@@ -159,7 +158,7 @@ public List<QuotaUsageVO> aggregatePendingQuotaRecordsForAccount(final AccountVO
159158
case QuotaTypes.VOLUME:
160159
case QuotaTypes.VM_SNAPSHOT:
161160
case QuotaTypes.BACKUP:
162-
qu = updateQuotaDiskUsage(usageRecord, aggregationRatio, usageRecord.getUsageType());
161+
qu = updateQuotaDiskUsage(usageRecord, usageRecord.getUsageType());
163162
if (qu != null) {
164163
quotaListForAccount.add(qu);
165164
}
@@ -170,7 +169,7 @@ public List<QuotaUsageVO> aggregatePendingQuotaRecordsForAccount(final AccountVO
170169
case QuotaTypes.NETWORK_OFFERING:
171170
case QuotaTypes.SECURITY_GROUP:
172171
case QuotaTypes.VPN_USERS:
173-
qu = updateQuotaRaw(usageRecord, aggregationRatio, usageRecord.getUsageType());
172+
qu = updateQuotaRaw(usageRecord, usageRecord.getUsageType());
174173
if (qu != null) {
175174
quotaListForAccount.add(qu);
176175
}
@@ -333,14 +332,14 @@ public boolean calculateQuotaUsage() {
333332
return true;
334333
}
335334

336-
public QuotaUsageVO updateQuotaDiskUsage(UsageVO usageRecord, final BigDecimal aggregationRatio, final int quotaType) {
335+
public QuotaUsageVO updateQuotaDiskUsage(UsageVO usageRecord, final int quotaType) {
337336
QuotaUsageVO quota_usage = null;
338337
QuotaTariffVO tariff = _quotaTariffDao.findTariffPlanByUsageType(quotaType, usageRecord.getEndDate());
339338
if (tariff != null && tariff.getCurrencyValue().compareTo(BigDecimal.ZERO) != 0) {
340339
BigDecimal quotaUsgage;
341340
BigDecimal onehourcostpergb;
342341
BigDecimal noofgbinuse;
343-
onehourcostpergb = tariff.getCurrencyValue().multiply(aggregationRatio);
342+
onehourcostpergb = tariff.getCurrencyValue().divide(s_hoursInMonth, 8, RoundingMode.HALF_DOWN);
344343
noofgbinuse = new BigDecimal(usageRecord.getSize()).divide(s_gb, 8, RoundingMode.HALF_EVEN);
345344
quotaUsgage = new BigDecimal(usageRecord.getRawUsage()).multiply(onehourcostpergb).multiply(noofgbinuse);
346345
quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), usageRecord.getUsageType(),
@@ -352,7 +351,7 @@ public QuotaUsageVO updateQuotaDiskUsage(UsageVO usageRecord, final BigDecimal a
352351
return quota_usage;
353352
}
354353

355-
public List<QuotaUsageVO> updateQuotaRunningVMUsage(UsageVO usageRecord, final BigDecimal aggregationRatio) {
354+
public List<QuotaUsageVO> updateQuotaRunningVMUsage(UsageVO usageRecord) {
356355
List<QuotaUsageVO> quotalist = new ArrayList<QuotaUsageVO>();
357356
QuotaUsageVO quota_usage;
358357
BigDecimal cpuquotausgage, speedquotausage, memoryquotausage, vmusage;
@@ -368,7 +367,7 @@ public List<QuotaUsageVO> updateQuotaRunningVMUsage(UsageVO usageRecord, final B
368367
QuotaTariffVO tariff = _quotaTariffDao.findTariffPlanByUsageType(QuotaTypes.CPU_NUMBER, usageRecord.getEndDate());
369368
if (tariff != null && tariff.getCurrencyValue().compareTo(BigDecimal.ZERO) != 0 && serviceoffering.getCpu() != null) {
370369
BigDecimal cpu = new BigDecimal(serviceoffering.getCpu());
371-
onehourcostpercpu = tariff.getCurrencyValue().multiply(aggregationRatio);
370+
onehourcostpercpu = tariff.getCurrencyValue().divide(s_hoursInMonth, 8, RoundingMode.HALF_DOWN);
372371
cpuquotausgage = rawusage.multiply(onehourcostpercpu).multiply(cpu);
373372
quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), QuotaTypes.CPU_NUMBER,
374373
cpuquotausgage, usageRecord.getStartDate(), usageRecord.getEndDate());
@@ -377,8 +376,8 @@ public List<QuotaUsageVO> updateQuotaRunningVMUsage(UsageVO usageRecord, final B
377376
}
378377
tariff = _quotaTariffDao.findTariffPlanByUsageType(QuotaTypes.CPU_CLOCK_RATE, usageRecord.getEndDate());
379378
if (tariff != null && tariff.getCurrencyValue().compareTo(BigDecimal.ZERO) != 0 && serviceoffering.getSpeed() != null) {
380-
BigDecimal speed = new BigDecimal(serviceoffering.getSpeed() / 100.00);
381-
onehourcostper100mhz = tariff.getCurrencyValue().multiply(aggregationRatio);
379+
BigDecimal speed = new BigDecimal(serviceoffering.getSpeed()*serviceoffering.getCpu() / 100.00);
380+
onehourcostper100mhz = tariff.getCurrencyValue().divide(s_hoursInMonth, 8, RoundingMode.HALF_DOWN);
382381
speedquotausage = rawusage.multiply(onehourcostper100mhz).multiply(speed);
383382
quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), QuotaTypes.CPU_CLOCK_RATE,
384383
speedquotausage, usageRecord.getStartDate(), usageRecord.getEndDate());
@@ -388,7 +387,7 @@ public List<QuotaUsageVO> updateQuotaRunningVMUsage(UsageVO usageRecord, final B
388387
tariff = _quotaTariffDao.findTariffPlanByUsageType(QuotaTypes.MEMORY, usageRecord.getEndDate());
389388
if (tariff != null && tariff.getCurrencyValue().compareTo(BigDecimal.ZERO) != 0 && serviceoffering.getRamSize() != null) {
390389
BigDecimal memory = new BigDecimal(serviceoffering.getRamSize());
391-
onehourcostper1mb = tariff.getCurrencyValue().multiply(aggregationRatio);
390+
onehourcostper1mb = tariff.getCurrencyValue().divide(s_hoursInMonth, 8, RoundingMode.HALF_DOWN);
392391
memoryquotausage = rawusage.multiply(onehourcostper1mb).multiply(memory);
393392
quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), QuotaTypes.MEMORY, memoryquotausage,
394393
usageRecord.getStartDate(), usageRecord.getEndDate());
@@ -397,7 +396,7 @@ public List<QuotaUsageVO> updateQuotaRunningVMUsage(UsageVO usageRecord, final B
397396
}
398397
tariff = _quotaTariffDao.findTariffPlanByUsageType(QuotaTypes.RUNNING_VM, usageRecord.getEndDate());
399398
if (tariff != null && tariff.getCurrencyValue().compareTo(BigDecimal.ZERO) != 0) {
400-
onehourcostforvmusage = tariff.getCurrencyValue().multiply(aggregationRatio);
399+
onehourcostforvmusage = tariff.getCurrencyValue().divide(s_hoursInMonth, 8, RoundingMode.HALF_DOWN);
401400
vmusage = rawusage.multiply(onehourcostforvmusage);
402401
quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), QuotaTypes.RUNNING_VM, vmusage,
403402
usageRecord.getStartDate(), usageRecord.getEndDate());
@@ -410,13 +409,13 @@ public List<QuotaUsageVO> updateQuotaRunningVMUsage(UsageVO usageRecord, final B
410409
return quotalist;
411410
}
412411

413-
public QuotaUsageVO updateQuotaAllocatedVMUsage(UsageVO usageRecord, final BigDecimal aggregationRatio) {
412+
public QuotaUsageVO updateQuotaAllocatedVMUsage(UsageVO usageRecord) {
414413
QuotaUsageVO quota_usage = null;
415414
QuotaTariffVO tariff = _quotaTariffDao.findTariffPlanByUsageType(QuotaTypes.ALLOCATED_VM, usageRecord.getEndDate());
416415
if (tariff != null && tariff.getCurrencyValue().compareTo(BigDecimal.ZERO) != 0) {
417416
BigDecimal vmusage;
418417
BigDecimal onehourcostforvmusage;
419-
onehourcostforvmusage = tariff.getCurrencyValue().multiply(aggregationRatio);
418+
onehourcostforvmusage = tariff.getCurrencyValue().divide(s_hoursInMonth, 8, RoundingMode.HALF_DOWN);
420419
vmusage = new BigDecimal(usageRecord.getRawUsage()).multiply(onehourcostforvmusage);
421420
quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), QuotaTypes.ALLOCATED_VM, vmusage,
422421
usageRecord.getStartDate(), usageRecord.getEndDate());
@@ -428,13 +427,13 @@ public QuotaUsageVO updateQuotaAllocatedVMUsage(UsageVO usageRecord, final BigDe
428427
return quota_usage;
429428
}
430429

431-
public QuotaUsageVO updateQuotaRaw(UsageVO usageRecord, final BigDecimal aggregationRatio, final int ruleType) {
430+
public QuotaUsageVO updateQuotaRaw(UsageVO usageRecord, final int ruleType) {
432431
QuotaUsageVO quota_usage = null;
433432
QuotaTariffVO tariff = _quotaTariffDao.findTariffPlanByUsageType(ruleType, usageRecord.getEndDate());
434433
if (tariff != null && tariff.getCurrencyValue().compareTo(BigDecimal.ZERO) != 0) {
435434
BigDecimal ruleusage;
436435
BigDecimal onehourcost;
437-
onehourcost = tariff.getCurrencyValue().multiply(aggregationRatio);
436+
onehourcost = tariff.getCurrencyValue().divide(s_hoursInMonth, 8, RoundingMode.HALF_DOWN);
438437
ruleusage = new BigDecimal(usageRecord.getRawUsage()).multiply(onehourcost);
439438
quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), ruleType, ruleusage,
440439
usageRecord.getStartDate(), usageRecord.getEndDate());

framework/quota/src/test/java/org/apache/cloudstack/quota/QuotaManagerImplTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ public void testAggregatePendingQuotaRecordsForAccount() {
151151

152152
QuotaUsageVO quotaUsageVO = new QuotaUsageVO();
153153
quotaUsageVO.setAccountId(2L);
154-
Mockito.doReturn(quotaUsageVO).when(quotaManager).updateQuotaAllocatedVMUsage(Mockito.eq(usageVO), Mockito.any(BigDecimal.class));
154+
Mockito.doReturn(quotaUsageVO).when(quotaManager).updateQuotaAllocatedVMUsage(Mockito.eq(usageVO));
155155

156156
assertTrue(quotaManager.aggregatePendingQuotaRecordsForAccount(accountVO, new Pair<List<? extends UsageVO>, Integer>(null, 0)).size() == 0);
157157
assertTrue(quotaManager.aggregatePendingQuotaRecordsForAccount(accountVO, usageRecords).size() == 1);
@@ -172,11 +172,11 @@ public void testUpdateQuotaRecords() {
172172

173173
QuotaUsageVO qu = quotaManager.updateQuotaNetwork(usageVO, UsageTypes.NETWORK_BYTES_SENT);
174174
assertTrue(qu.getQuotaUsed().compareTo(BigDecimal.ZERO) > 0);
175-
qu = quotaManager.updateQuotaAllocatedVMUsage(usageVO, new BigDecimal(0.5));
175+
qu = quotaManager.updateQuotaAllocatedVMUsage(usageVO);
176176
assertTrue(qu.getQuotaUsed().compareTo(BigDecimal.ZERO) > 0);
177-
qu = quotaManager.updateQuotaDiskUsage(usageVO, new BigDecimal(0.5), UsageTypes.VOLUME);
177+
qu = quotaManager.updateQuotaDiskUsage(usageVO, UsageTypes.VOLUME);
178178
assertTrue(qu.getQuotaUsed().compareTo(BigDecimal.ZERO) > 0);
179-
qu = quotaManager.updateQuotaRaw(usageVO, new BigDecimal(0.5), UsageTypes.VPN_USERS);
179+
qu = quotaManager.updateQuotaRaw(usageVO, UsageTypes.VPN_USERS);
180180
assertTrue(qu.getQuotaUsed().compareTo(BigDecimal.ZERO) > 0);
181181

182182
Mockito.verify(quotaUsageDao, Mockito.times(4)).persistQuotaUsage(Mockito.any(QuotaUsageVO.class));

0 commit comments

Comments
 (0)