Skip to content

Commit 06ef61b

Browse files
Merge pull request #2443 from rafaelweingartner/CLOUDSTACK-9338
[CLOUDSTACK-9338] ACS is not accounting resources of VMs with custom service offering properly
2 parents f8d98fd + 601d095 commit 06ef61b

4 files changed

Lines changed: 413 additions & 184 deletions

File tree

engine/schema/src/main/java/com/cloud/configuration/dao/ResourceCountDao.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,18 @@ public interface ResourceCountDao extends GenericDao<ResourceCountVO, Long> {
5757
Set<Long> listRowsToUpdateForDomain(long domainId, ResourceType type);
5858

5959
long removeEntriesByOwner(long ownerId, ResourceOwnerType ownerType);
60+
61+
/**
62+
* Counts the number of CPU cores allocated for the given account.
63+
*
64+
* Side note: This method is not using the "resource_count" table. It is executing the actual count instead.
65+
*/
66+
long countCpuNumberAllocatedToAccount(long accountId);
67+
68+
/**
69+
* Counts the amount of memory allocated for the given account.
70+
*
71+
* Side note: This method is not using the "resource_count" table. It is executing the actual count instead.
72+
*/
73+
long countMemoryAllocatedToAccount(long accountId);
6074
}

engine/schema/src/main/java/com/cloud/configuration/dao/ResourceCountDaoImpl.java

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
// under the License.
1717
package com.cloud.configuration.dao;
1818

19+
import java.sql.PreparedStatement;
20+
import java.sql.ResultSet;
21+
import java.sql.SQLException;
1922
import java.util.ArrayList;
2023
import java.util.HashSet;
2124
import java.util.List;
@@ -24,24 +27,25 @@
2427
import javax.annotation.PostConstruct;
2528
import javax.inject.Inject;
2629

27-
import com.cloud.domain.DomainVO;
28-
import com.cloud.user.AccountVO;
29-
import com.cloud.utils.db.JoinBuilder;
3030
import org.springframework.stereotype.Component;
3131

3232
import com.cloud.configuration.Resource;
3333
import com.cloud.configuration.Resource.ResourceOwnerType;
3434
import com.cloud.configuration.Resource.ResourceType;
3535
import com.cloud.configuration.ResourceCountVO;
3636
import com.cloud.configuration.ResourceLimit;
37+
import com.cloud.domain.DomainVO;
3738
import com.cloud.domain.dao.DomainDao;
3839
import com.cloud.exception.UnsupportedServiceException;
40+
import com.cloud.user.AccountVO;
3941
import com.cloud.user.dao.AccountDao;
4042
import com.cloud.utils.db.DB;
4143
import com.cloud.utils.db.GenericDaoBase;
44+
import com.cloud.utils.db.JoinBuilder;
4245
import com.cloud.utils.db.SearchBuilder;
4346
import com.cloud.utils.db.SearchCriteria;
4447
import com.cloud.utils.db.TransactionLegacy;
48+
import com.cloud.utils.exception.CloudRuntimeException;
4549

4650
@Component
4751
public class ResourceCountDaoImpl extends GenericDaoBase<ResourceCountVO, Long> implements ResourceCountDao {
@@ -51,9 +55,9 @@ public class ResourceCountDaoImpl extends GenericDaoBase<ResourceCountVO, Long>
5155
private final SearchBuilder<ResourceCountVO> DomainSearch;
5256

5357
@Inject
54-
protected DomainDao _domainDao;
58+
private DomainDao _domainDao;
5559
@Inject
56-
protected AccountDao _accountDao;
60+
private AccountDao _accountDao;
5761

5862
public ResourceCountDaoImpl() {
5963
TypeSearch = createSearchBuilder();
@@ -248,4 +252,41 @@ public long removeEntriesByOwner(long ownerId, ResourceOwnerType ownerType) {
248252
return 0;
249253
}
250254

255+
private String baseSqlCountComputingResourceAllocatedToAccount = "Select "
256+
+ " SUM((CASE "
257+
+ " WHEN so.%s is not null THEN so.%s "
258+
+ " ELSE CONVERT(vmd.value, UNSIGNED INTEGER) "
259+
+ " END)) as total "
260+
+ " from vm_instance vm "
261+
+ " join service_offering_view so on so.id = vm.service_offering_id "
262+
+ " left join user_vm_details vmd on vmd.vm_id = vm.id and vmd.name = '%s' "
263+
+ " where vm.type = 'User' and state not in ('Destroyed', 'Error', 'Expunging') and display_vm = true and account_id = ? ";
264+
@Override
265+
public long countCpuNumberAllocatedToAccount(long accountId) {
266+
String sqlCountCpuNumberAllocatedToAccount = String.format(baseSqlCountComputingResourceAllocatedToAccount, ResourceType.cpu, ResourceType.cpu, "cpuNumber");
267+
return executeSqlCountComputingResourcesForAccount(accountId, sqlCountCpuNumberAllocatedToAccount);
268+
}
269+
270+
@Override
271+
public long countMemoryAllocatedToAccount(long accountId) {
272+
String serviceOfferingRamSizeField = "ram_size";
273+
String sqlCountCpuNumberAllocatedToAccount = String.format(baseSqlCountComputingResourceAllocatedToAccount, serviceOfferingRamSizeField, serviceOfferingRamSizeField, "memory");
274+
return executeSqlCountComputingResourcesForAccount(accountId, sqlCountCpuNumberAllocatedToAccount);
275+
}
276+
277+
private long executeSqlCountComputingResourcesForAccount(long accountId, String sqlCountComputingResourcesAllocatedToAccount) {
278+
try (TransactionLegacy tx = TransactionLegacy.currentTxn()) {
279+
PreparedStatement pstmt = tx.prepareAutoCloseStatement(sqlCountComputingResourcesAllocatedToAccount);
280+
pstmt.setLong(1, accountId);
281+
282+
ResultSet rs = pstmt.executeQuery();
283+
if (!rs.next()) {
284+
throw new CloudRuntimeException(String.format("An unexpected case happened while counting allocated computing resources for account: " + accountId));
285+
}
286+
return rs.getLong("total");
287+
} catch (SQLException e) {
288+
throw new CloudRuntimeException(e);
289+
}
290+
}
291+
251292
}

0 commit comments

Comments
 (0)