bug 9419: implement api to reset resource count

adding couple of fixes
This commit is contained in:
Murali Reddy 2011-06-16 17:36:04 +05:30
parent c7e347e9a4
commit 00bd79ffee
5 changed files with 73 additions and 53 deletions

View File

@ -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<? extends ResourceCount> result = _accountService.updateResourceCount(this);
if ((result != null) && (result.size()>0)){
ListResponse<ResourceCountResponse> response = new ListResponse<ResourceCountResponse>();
List<ResourceCountResponse> countResponses = new ArrayList<ResourceCountResponse>();
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");
}
}
}
}

View File

@ -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<? extends ResourceCount> updateResourceCount(UpdateResourceCountCmd cmd);
/**
* Search for resource limits for the given id and/or account and/or type and/or domain.

View File

@ -88,8 +88,10 @@ public class ResourceCountDaoImpl extends GenericDaoBase<ResourceCountVO, Long>
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<ResourceCountVO, Long>
persist(resourceCountVO);
}
} else {
resourceCountVO.setCount(count);
update(resourceCountVO.getId(), resourceCountVO);
if (count != resourceCountVO.getCount()) {
resourceCountVO.setCount(count);
update(resourceCountVO.getId(), resourceCountVO);
}
}
}

View File

@ -330,7 +330,7 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
public Long countAllocatedVolumesForAccount(long accountId) {
SearchCriteria<Long> 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);
}

View File

@ -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<DomainVO> domainChildren = _domainDao.findImmediateChildrenForParent(domain.getId());
List<DomainVO> 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<AccountVO> accounts = _accountDao.findActiveAccountsForDomain(domain.getId());
List<AccountVO> 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<ResourceCountVO> 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<ResourceCountVO> counts = new ArrayList<ResourceCountVO>();
List<ResourceType> resourceTypes = new ArrayList<ResourceType>();
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) {