refactor handling ResourceAllocationException

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
This commit is contained in:
Abhishek Kumar 2026-06-25 12:29:30 +05:30
parent 1a4a5118d9
commit ca13a8018e
2 changed files with 34 additions and 19 deletions

View File

@ -17,9 +17,11 @@
package org.apache.cloudstack.api.command.user.vm;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Stream;
import com.cloud.configuration.Resource;
import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.cloudstack.api.ACL;
import org.apache.cloudstack.api.APICommand;
@ -163,10 +165,11 @@ public class DeployVMCmd extends BaseDeployVMCmd {
}
protected void handleCreateResourceAllocationException(ResourceAllocationException ex) {
if (ex.getMessage() != null && ex.getMessage().startsWith("Maximum amount")) {
Map<String, Object> errorContext = CallContext.current().getErrorContextParameters();
if (Resource.ResourceOwnerType.Account.equals(errorContext.get("resourceLimitCause"))) {
throw new ServerApiException(ApiErrorCode.RESOURCE_ALLOCATION_ERROR,
"vm.deploy.resourcelimit.exceeded.account", Collections.emptyMap());
} else if (ex.getMessage() != null && ex.getMessage().startsWith("Maximum domain resource limits")) {
} else if (Resource.ResourceOwnerType.Domain.equals(errorContext.get("resourceLimitCause"))) {
throw new ServerApiException(ApiErrorCode.RESOURCE_ALLOCATION_ERROR,
"vm.deploy.resourcelimit.exceeded.domain", Collections.emptyMap());
}

View File

@ -558,14 +558,8 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
if (domainResourceLimit != Resource.RESOURCE_UNLIMITED && requestedDomainResourceCount > domainResourceLimit) {
String message = "Maximum" + messageSuffix;
Map<String, Object> details = new HashMap<>();
details.put("resourceTypeDisplay", StringUtils.isBlank(tag) ? type.getDisplayName() : type.getDisplayName() + " (tag: " + tag + ")");
details.put("resourceOwnerDomain", domain);
details.put("resourceLimit", convDomainResourceLimit);
details.put("resourceAmount", convCurrentDomainResourceCount);
details.put("resourceReserved", convCurrentResourceReservation);
details.put("resourceRequested", convNumResources);
CallContext.current().putErrorContextParameters(details);
addResourceLimitErrorContext(domain, null, null, type, tag, convDomainResourceLimit,
convCurrentDomainResourceCount, convCurrentResourceReservation, convNumResources);
ResourceAllocationException e = new ResourceAllocationException(message, type);
logger.error(message, e);
throw e;
@ -605,21 +599,39 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
if (accountResourceLimit != Resource.RESOURCE_UNLIMITED && requestedResourceCount > accountResourceLimit) {
String message = "Maximum" + messageSuffix;
Map<String, Object> details = new HashMap<>();
details.put("resourceTypeDisplay", StringUtils.isBlank(tag) ? type.getDisplayName() : type.getDisplayName() + " (tag: " + tag + ")");
details.put("resourceOwner", ObjectUtils.firstNonNull(project, account));
details.put("resourceOwnerType", project == null ? "Account" : "Project");
details.put("resourceLimit", convertedAccountResourceLimit);
details.put("resourceAmount", convertedCurrentResourceCount);
details.put("resourceReserved", convertedCurrentResourceReservation);
details.put("resourceRequested", convertedNumResources);
CallContext.current().putErrorContextParameters(details);
addResourceLimitErrorContext(null, account, project, type, tag, convertedAccountResourceLimit,
convertedCurrentResourceCount, convertedCurrentResourceReservation, convertedNumResources);
ResourceAllocationException e = new ResourceAllocationException(message, type);
logger.error(message, e);
throw e;
}
}
private void addResourceLimitErrorContext(Domain domain, Account account, Project project, ResourceType type,
String tag, String convertedResourceLimit,
String convertedCurrentResourceCount,
String convertedCurrentResourceReservation,
String convertedNumResources) {
Map<String, Object> details = new HashMap<>();
details.put("resourceTypeDisplay", StringUtils.isBlank(tag) ?
type.getDisplayName() :
type.getDisplayName() + " (tag: " + tag + ")");
if (domain != null) {
details.put("resourceLimitCause", ResourceOwnerType.Domain);
details.put("resourceOwnerDomain", domain);
}
if (account != null) {
details.put("resourceLimitCause", ResourceOwnerType.Account);
details.put("resourceOwner", ObjectUtils.firstNonNull(project, account));
details.put("resourceOwnerType", project == null ? "Account" : "Project");
}
details.put("resourceLimit", convertedResourceLimit);
details.put("resourceAmount", convertedCurrentResourceCount);
details.put("resourceReserved", convertedCurrentResourceReservation);
details.put("resourceRequested", convertedNumResources);
CallContext.current().putErrorContextParameters(details);
}
protected List<ResourceCountVO> lockAccountAndOwnerDomainRows(long accountId, final ResourceType type, String tag) {
Set<Long> rowIdsToLock = _resourceCountDao.listAllRowsToUpdate(accountId, ResourceOwnerType.Account, type, tag);
SearchCriteria<ResourceCountVO> sc = ResourceCountSearch.create();