From 00bd79ffeed99f503b9fe93ea584b48b9d9a0a82 Mon Sep 17 00:00:00 2001 From: Murali Reddy Date: Thu, 16 Jun 2011 17:36:04 +0530 Subject: [PATCH] bug 9419: implement api to reset resource count adding couple of fixes --- .../api/commands/UpdateResourceCountCmd.java | 28 +++++-- api/src/com/cloud/user/AccountService.java | 4 +- .../dao/ResourceCountDaoImpl.java | 12 ++- .../com/cloud/storage/dao/VolumeDaoImpl.java | 2 +- .../com/cloud/user/AccountManagerImpl.java | 80 ++++++++++--------- 5 files changed, 73 insertions(+), 53 deletions(-) diff --git a/api/src/com/cloud/api/commands/UpdateResourceCountCmd.java b/api/src/com/cloud/api/commands/UpdateResourceCountCmd.java index 5326ab4b298..556ed5c719e 100644 --- a/api/src/com/cloud/api/commands/UpdateResourceCountCmd.java +++ b/api/src/com/cloud/api/commands/UpdateResourceCountCmd.java @@ -19,16 +19,19 @@ package com.cloud.api.commands; import org.apache.log4j.Logger; - import com.cloud.api.ApiConstants; import com.cloud.api.BaseCmd; import com.cloud.api.Implementation; import com.cloud.api.Parameter; import com.cloud.api.ServerApiException; +import com.cloud.api.response.ListResponse; import com.cloud.api.response.ResourceCountResponse; import com.cloud.configuration.ResourceCount; import com.cloud.user.Account; import com.cloud.user.UserContext; +import java.util.ArrayList; +import java.util.List; + @Implementation(description="Recalculate and update resource count for an account or domain.", responseObject=ResourceCountResponse.class) public class UpdateResourceCountCmd extends BaseCmd { @@ -44,10 +47,11 @@ public class UpdateResourceCountCmd extends BaseCmd { @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="Update resource count for a specified account. Must be used with the domainId parameter.") private String accountName; - @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="Update resource counts for all accounts & child domains in specified domain. If used with the account parameter, updates resource counts for a specified account in specified domain.") + @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, required=true, description="If account parameter specified then updates resource counts for a specified account in this domain else update resource counts for all accounts & child domains in specified domain.") private Long domainId; - @Parameter(name=ApiConstants.RESOURCE_TYPE, type=CommandType.INTEGER, required=true, description="Type of resource to update. Values are 0, 1, 2, 3, and 4. 0 - Instance. Number of instances a user can create. " + + @Parameter(name=ApiConstants.RESOURCE_TYPE, type=CommandType.INTEGER, description= "Type of resource to update. If specifies valid values are 0, 1, 2, 3, and 4. If not specified will update all resource counts" + + "0 - Instance. Number of instances a user can create. " + "1 - IP. Number of public IP addresses a user can own. " + "2 - Volume. Number of disk volumes a user can create." + "3 - Snapshot. Number of snapshots a user can create." + @@ -100,13 +104,23 @@ public class UpdateResourceCountCmd extends BaseCmd { @Override public void execute(){ - ResourceCount result = _accountService.updateResourceCount(this); - if (result != null){ - ResourceCountResponse response = _responseGenerator.createResourceCountResponse(result); + List result = _accountService.updateResourceCount(this); + + if ((result != null) && (result.size()>0)){ + ListResponse response = new ListResponse(); + List countResponses = new ArrayList(); + + for (ResourceCount count : result) { + ResourceCountResponse resourceCountResponse = _responseGenerator.createResourceCountResponse(count); + resourceCountResponse.setObjectName("resourcecount"); + countResponses.add(resourceCountResponse); + } + + response.setResponses(countResponses); response.setResponseName(getCommandName()); this.setResponseObject(response); } else { throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to recalculate resource counts"); } } -} +} \ No newline at end of file diff --git a/api/src/com/cloud/user/AccountService.java b/api/src/com/cloud/user/AccountService.java index 914eb1b3844..6da5b6dc657 100644 --- a/api/src/com/cloud/user/AccountService.java +++ b/api/src/com/cloud/user/AccountService.java @@ -149,9 +149,9 @@ public interface AccountService { * * @param cmd * the command that wraps the domainId, accountId, resource type parameters - * @return the updated/created resource count + * @return the updated/created resource counts */ - ResourceCount updateResourceCount(UpdateResourceCountCmd cmd); + List updateResourceCount(UpdateResourceCountCmd cmd); /** * Search for resource limits for the given id and/or account and/or type and/or domain. diff --git a/server/src/com/cloud/configuration/dao/ResourceCountDaoImpl.java b/server/src/com/cloud/configuration/dao/ResourceCountDaoImpl.java index b05898374d3..812a10b3f83 100644 --- a/server/src/com/cloud/configuration/dao/ResourceCountDaoImpl.java +++ b/server/src/com/cloud/configuration/dao/ResourceCountDaoImpl.java @@ -88,8 +88,10 @@ public class ResourceCountDaoImpl extends GenericDaoBase persist(resourceCountVO); } } else { - resourceCountVO.setCount(count); - update(resourceCountVO.getId(), resourceCountVO); + if (count != resourceCountVO.getCount()) { + resourceCountVO.setCount(count); + update(resourceCountVO.getId(), resourceCountVO); + } } } @@ -102,8 +104,10 @@ public class ResourceCountDaoImpl extends GenericDaoBase persist(resourceCountVO); } } else { - resourceCountVO.setCount(count); - update(resourceCountVO.getId(), resourceCountVO); + if (count != resourceCountVO.getCount()) { + resourceCountVO.setCount(count); + update(resourceCountVO.getId(), resourceCountVO); + } } } diff --git a/server/src/com/cloud/storage/dao/VolumeDaoImpl.java b/server/src/com/cloud/storage/dao/VolumeDaoImpl.java index 49db3566395..4018a2634cb 100755 --- a/server/src/com/cloud/storage/dao/VolumeDaoImpl.java +++ b/server/src/com/cloud/storage/dao/VolumeDaoImpl.java @@ -330,7 +330,7 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol public Long countAllocatedVolumesForAccount(long accountId) { SearchCriteria sc = CountByAccount.create(); sc.setParameters("account", accountId); - sc.setParameters("state", new Object[] {Volume.State.Destroy, State.Expunging}); + sc.setParameters("state", Volume.State.Destroy); return customSearch(sc, null).get(0); } diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java index ca0f412e6a0..da29087cc50 100755 --- a/server/src/com/cloud/user/AccountManagerImpl.java +++ b/server/src/com/cloud/user/AccountManagerImpl.java @@ -19,6 +19,7 @@ package com.cloud.user; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -745,10 +746,10 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag @Override public long updateAccountResourceCount(long accountId, ResourceType type) { - long count=0; + Long count=null; - // this lock guards against the updates to user_vm, volume, snapshot, public _ip and template - // table as any resource creation precedes with the resourceLimitExceeded check which needs this lock too + // this lock guards against the updates to user_vm, volume, snapshot, public _ip and template table + // as any resource creation precedes with the resourceLimitExceeded check which needs this lock too if (m_resourceCountLock.lock(120)) { // 2 minutes try { switch (type) { @@ -770,7 +771,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag count = _vmTemplateDao.countTemplatesForAccount(accountId); break; } - _resourceCountDao.setAccountCount(accountId, type, count); + _resourceCountDao.setAccountCount(accountId, type, (count == null) ? 0 : count.longValue()); } catch (Exception e) { throw new CloudRuntimeException("Failed to update resource count for account with Id" + accountId); } finally { @@ -778,24 +779,23 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag } } - return count; + return (count==null)?0:count.longValue(); } @Override public long updateDomainResourceCount(long domainId, ResourceType type) { long count=0; - Domain domain =_domainDao.findById(domainId); if (m_resourceCountLock.lock(120)) { // 2 minutes try { - List domainChildren = _domainDao.findImmediateChildrenForParent(domain.getId()); + List domainChildren = _domainDao.findImmediateChildrenForParent(domainId); // for each child domain update the resource count for (DomainVO domainChild : domainChildren) { long domainCount = updateDomainResourceCount(domainChild.getId(), type); count = count + domainCount; // add the child domain count to parent domain count } - List accounts = _accountDao.findActiveAccountsForDomain(domain.getId()); + List accounts = _accountDao.findActiveAccountsForDomain(domainId); for (AccountVO account : accounts) { long accountCount = updateAccountResourceCount(account.getId(), type); count = count + accountCount; // add account's resource count to parent domain count @@ -811,63 +811,65 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag return count; } - + @Override - public ResourceCountVO updateResourceCount(UpdateResourceCountCmd cmd) throws InvalidParameterValueException, CloudRuntimeException, PermissionDeniedException{ - Account currentAccount = UserContext.current().getCaller(); + public List updateResourceCount(UpdateResourceCountCmd cmd) throws InvalidParameterValueException, CloudRuntimeException, PermissionDeniedException{ + Account callerAccount = UserContext.current().getCaller(); String accountName = cmd.getAccountName(); Long domainId = cmd.getDomainId(); Long accountId = null; long count=0; + List counts = new ArrayList(); + List resourceTypes = new ArrayList(); - ResourceType resourceType; - Integer type = cmd.getResourceType(); - try { - resourceType = ResourceType.values()[type]; - } catch (ArrayIndexOutOfBoundsException e) { - throw new InvalidParameterValueException("Please specify a valid resource type."); - } + ResourceType resourceType=null; + Integer typeId = cmd.getResourceType(); - // Either a domainId or an account name with domainId must be passed in - if ((domainId == null) && (accountName == null)) { - throw new InvalidParameterValueException("Either a domainId or account name with domainId must be passed in."); - } - - if (domainId != null) { - DomainVO domain = _domainDao.findById(domainId); - if (domain == null) { - throw new InvalidParameterValueException("Please specify a valid domain ID."); - } else if (domain.getRemoved() != null) { - throw new InvalidParameterValueException("Please specify an active domain."); + if (typeId != null) { + try { + resourceType = ResourceType.values()[typeId]; + } catch (ArrayIndexOutOfBoundsException e) { + throw new InvalidParameterValueException("Please specify a valid resource type."); } - checkAccess(currentAccount, domain); } + DomainVO domain = _domainDao.findById(domainId); + if (domain == null) { + throw new InvalidParameterValueException("Please specify a valid domain ID."); + } + checkAccess(callerAccount, domain); + if (accountName != null) { - if (domainId == null) { - throw new InvalidParameterValueException("domainId parameter is required if account name is specified"); - } Account userAccount = _accountDao.findActiveAccount(accountName, domainId); if (userAccount == null) { throw new InvalidParameterValueException("unable to find account by name " + accountName + " in domain with id " + domainId); } accountId = userAccount.getId(); - checkAccess(currentAccount, userAccount); } try { - if (accountId != null) { - count = updateAccountResourceCount(accountId, resourceType); + if (resourceType != null) { + resourceTypes.add(resourceType); } else { - count = updateDomainResourceCount(domainId, resourceType); + resourceTypes = Arrays.asList(ResourceType.values()); + } + + for (ResourceType type : resourceTypes) { + if (accountId != null) { + count = updateAccountResourceCount(accountId, type); + counts.add(new ResourceCountVO(accountId, domainId, type, count)); + } else { + count = updateDomainResourceCount(domainId, type); + counts.add(new ResourceCountVO(accountId, domainId, type, count)); + } } } catch (Exception e) { throw new CloudRuntimeException(e.getMessage()); } - return new ResourceCountVO(accountId, domainId, resourceType, count); + return counts; } - + @Override public AccountVO getSystemAccount() { if (_systemAccount == null) {