From ca13a8018e29c9782cbec0314a36429c5e840743 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Thu, 25 Jun 2026 12:29:30 +0530 Subject: [PATCH] refactor handling ResourceAllocationException Signed-off-by: Abhishek Kumar --- .../api/command/user/vm/DeployVMCmd.java | 7 ++- .../ResourceLimitManagerImpl.java | 46 ++++++++++++------- 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java index beb00c8c03c..f2c4972edd4 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java @@ -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 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()); } diff --git a/server/src/main/java/com/cloud/resourcelimit/ResourceLimitManagerImpl.java b/server/src/main/java/com/cloud/resourcelimit/ResourceLimitManagerImpl.java index ea0ef5a8be8..8a1f5c0a02a 100644 --- a/server/src/main/java/com/cloud/resourcelimit/ResourceLimitManagerImpl.java +++ b/server/src/main/java/com/cloud/resourcelimit/ResourceLimitManagerImpl.java @@ -558,14 +558,8 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim if (domainResourceLimit != Resource.RESOURCE_UNLIMITED && requestedDomainResourceCount > domainResourceLimit) { String message = "Maximum" + messageSuffix; - Map 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 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 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 lockAccountAndOwnerDomainRows(long accountId, final ResourceType type, String tag) { Set rowIdsToLock = _resourceCountDao.listAllRowsToUpdate(accountId, ResourceOwnerType.Account, type, tag); SearchCriteria sc = ResourceCountSearch.create();