mirror of https://github.com/apache/cloudstack.git
handle resourceallocationexception
Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
This commit is contained in:
parent
1036df831f
commit
6878f49d97
|
|
@ -22,32 +22,34 @@ public interface Resource {
|
|||
String UNLIMITED = "Unlimited";
|
||||
|
||||
enum ResourceType { // All storage type resources are allocated_storage and not the physical storage.
|
||||
user_vm("user_vm", 0),
|
||||
public_ip("public_ip", 1),
|
||||
volume("volume", 2),
|
||||
snapshot("snapshot", 3),
|
||||
template("template", 4),
|
||||
project("project", 5),
|
||||
network("network", 6),
|
||||
vpc("vpc", 7),
|
||||
cpu("cpu", 8),
|
||||
memory("memory", 9),
|
||||
primary_storage("primary_storage", 10),
|
||||
secondary_storage("secondary_storage", 11),
|
||||
backup("backup", 12),
|
||||
backup_storage("backup_storage", 13),
|
||||
bucket("bucket", 14),
|
||||
object_storage("object_storage", 15),
|
||||
gpu("gpu", 16);
|
||||
user_vm("user_vm", "Instance", 0),
|
||||
public_ip("public_ip", "Public IP", 1),
|
||||
volume("volume", "Volume", 2),
|
||||
snapshot("snapshot", "Snapshot", 3),
|
||||
template("template", "Template", 4),
|
||||
project("project", "Project", 5),
|
||||
network("network", "Network", 6),
|
||||
vpc("vpc", "VPC", 7),
|
||||
cpu("cpu", "CPU", 8),
|
||||
memory("memory", "Memory", 9),
|
||||
primary_storage("primary_storage", "Primary Storage", 10),
|
||||
secondary_storage("secondary_storage", "Secondary Storage", 11),
|
||||
backup("backup", "Backup", 12),
|
||||
backup_storage("backup_storage", "Backup Storage", 13),
|
||||
bucket("bucket", "Bucket", 14),
|
||||
object_storage("object_storage", "Object Storage", 15),
|
||||
gpu("gpu", "GPU", 16);
|
||||
|
||||
private String name;
|
||||
private String displayName;
|
||||
private int ordinal;
|
||||
public static final long bytesToKiB = 1024;
|
||||
public static final long bytesToMiB = bytesToKiB * 1024;
|
||||
public static final long bytesToGiB = bytesToMiB * 1024;
|
||||
|
||||
ResourceType(String name, int ordinal) {
|
||||
ResourceType(String name, String displayName, int ordinal) {
|
||||
this.name = name;
|
||||
this.displayName = displayName;
|
||||
this.ordinal = ordinal;
|
||||
}
|
||||
|
||||
|
|
@ -55,6 +57,10 @@ public interface Resource {
|
|||
return name;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public int getOrdinal() {
|
||||
return ordinal;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,9 @@
|
|||
package org.apache.cloudstack.api;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.cloudstack.context.ErrorMessageResolver;
|
||||
|
||||
import com.cloud.exception.CloudException;
|
||||
import com.cloud.utils.exception.CSExceptionErrorCode;
|
||||
|
|
@ -34,6 +37,14 @@ public class ServerApiException extends CloudRuntimeException {
|
|||
setCSErrorCode(CSExceptionErrorCode.getCSErrCode(ServerApiException.class.getName()));
|
||||
}
|
||||
|
||||
public ServerApiException(ApiErrorCode errorCode, String messageKey, Map<String, Object> errorMetadata) {
|
||||
_errorCode = errorCode;
|
||||
this.messageKey = messageKey;
|
||||
this.metadata = errorMetadata;
|
||||
_description = ErrorMessageResolver.getMessage(messageKey, errorMetadata);
|
||||
setCSErrorCode(CSExceptionErrorCode.getCSErrCode(ServerApiException.class.getName()));
|
||||
}
|
||||
|
||||
public ServerApiException(ApiErrorCode errorCode, String description) {
|
||||
_errorCode = errorCode;
|
||||
_description = description;
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.vm;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
|
|
@ -157,7 +158,18 @@ public class DeployVMCmd extends BaseDeployVMCmd {
|
|||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
|
||||
} catch (ResourceAllocationException ex) {
|
||||
logger.warn("Exception: ", ex);
|
||||
throw new ServerApiException(ApiErrorCode.RESOURCE_ALLOCATION_ERROR, ex.getMessage());
|
||||
handleCreateResourceAllocationException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
protected void handleCreateResourceAllocationException(ResourceAllocationException ex) {
|
||||
if (ex.getMessage() != null && ex.getMessage().startsWith("Maximum amount")) {
|
||||
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")) {
|
||||
throw new ServerApiException(ApiErrorCode.RESOURCE_ALLOCATION_ERROR,
|
||||
"vm.deploy.resourcelimit.exceeded.domain", Collections.emptyMap());
|
||||
}
|
||||
throw new ServerApiException(ApiErrorCode.RESOURCE_ALLOCATION_ERROR, ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ import org.apache.commons.lang3.StringUtils;
|
|||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.utils.PropertiesUtil;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
|
|
@ -287,12 +286,15 @@ public class ErrorMessageResolver {
|
|||
|
||||
if (key == null) {
|
||||
Throwable cause = cre.getCause();
|
||||
if (!(cause instanceof InvalidParameterValueException)) {
|
||||
if (!(cause instanceof CloudRuntimeException)) {
|
||||
return;
|
||||
}
|
||||
InvalidParameterValueException ipve = (InvalidParameterValueException) cause;
|
||||
key = ipve.getMessageKey();
|
||||
map = ipve.getMetadata();
|
||||
CloudRuntimeException causeEx = (CloudRuntimeException) cause;
|
||||
key = causeEx.getMessageKey();
|
||||
if (key == null) {
|
||||
return;
|
||||
}
|
||||
map = causeEx.getMetadata();
|
||||
}
|
||||
response.setErrorTextKey(key);
|
||||
String template = getTemplateForKey(key);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,10 @@
|
|||
"vm.deploy.diskoffering.with.diskoffering.details": "Unable to deploy Instance as both a disk offering ID and data disk offering details were provided. Specify only one.",
|
||||
"vm.deploy.hypervisor.volume.snapshot.not.supported": "Unable to deploy Instance because deployment from an existing volume or snapshot is supported only on the KVM hypervisor.",
|
||||
"vm.deploy.network.not.found.ip.map": "The network selected {{networkId}} in IP to network map could not be found. It may have been removed or is no longer accessible.",
|
||||
"vm.deploy.resourcelimit.exceeded.account": "Unable to deploy Instance because allocating {{resourceRequested}} more {{resourceTypeDisplay}} would exceed the {{resourceOwnerType}} limits. Current: {{resourceAmount}}, Reserved: {{resourceReserved}}, Limit: {{resourceLimit}}. Release unused resources, then retry.",
|
||||
"vm.deploy.resourcelimit.exceeded.account.admin": "Unable to deploy Instance because allocating {{resourceRequested}} more {{resourceTypeDisplay}} would exceed the {{resourceOwnerType}} limits for {{resourceOwner}}. Current: {{resourceAmount}}, Reserved: {{resourceReserved}}, Limit: {{resourceLimit}}. Release unused resources or increase the limit, then retry.",
|
||||
"vm.deploy.resourcelimit.exceeded.domain": "Unable to deploy Instance because allocating {{resourceRequested}} more {{resourceTypeDisplay}} would exceed the domain limits. Current: {{resourceAmount}}, Reserved: {{resourceReserved}}, Limit: {{resourceLimit}}. Release unused resources, then retry.",
|
||||
"vm.deploy.resourcelimit.exceeded.domain.admin": "Unable to deploy Instance because allocating {{resourceRequested}} more {{resourceTypeDisplay}} would exceed the limits for domain {{resourceOwnerDomain}}. Current: {{resourceAmount}}, Reserved: {{resourceReserved}}, Limit: {{resourceLimit}}. Release unused resources or increase the limit, then retry.",
|
||||
"vm.deploy.serviceoffering.fixed.parameters.not.allowed": "Unable to deploy the instance because the selected service offering {{serviceOffering}} does not allow specifying {{cpuNumberKey}}, {{cpuSpeedKey}}, or {{memory}}.",
|
||||
"vm.deploy.serviceoffering.fixed.parameters.not.allowed.admin": "Unable to deploy the instance because the selected service offering {{serviceOffering}} is not a dynamic offering and it does not allow specifying {{cpuNumberKey}}, {{cpuSpeedKey}}, or {{memory}}.",
|
||||
"vm.deploy.serviceoffering.inactive": "Unable to deploy Instance as the given service offering {{serviceOffering}} is inactive. Specify an active service offering.",
|
||||
|
|
|
|||
|
|
@ -558,6 +558,16 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||
|
||||
if (domainResourceLimit != Resource.RESOURCE_UNLIMITED && requestedDomainResourceCount > domainResourceLimit) {
|
||||
String message = "Maximum" + messageSuffix;
|
||||
Map<Object, 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("resourceOwnerDomain", domain);
|
||||
details.put("resourceOwnerType", project == null ? "Account" : "Project");
|
||||
details.put("resourceLimit", convDomainResourceLimit);
|
||||
details.put("resourceAmount", convCurrentDomainResourceCount);
|
||||
details.put("resourceReserved", convCurrentResourceReservation);
|
||||
details.put("resourceRequested", convNumResources);
|
||||
CallContext.current().putContextParameters(details);
|
||||
ResourceAllocationException e = new ResourceAllocationException(message, type);
|
||||
logger.error(message, e);
|
||||
throw e;
|
||||
|
|
@ -597,6 +607,15 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
|||
|
||||
if (accountResourceLimit != Resource.RESOURCE_UNLIMITED && requestedResourceCount > accountResourceLimit) {
|
||||
String message = "Maximum" + messageSuffix;
|
||||
Map<Object, 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().putContextParameters(details);
|
||||
ResourceAllocationException e = new ResourceAllocationException(message, type);
|
||||
logger.error(message, e);
|
||||
throw e;
|
||||
|
|
|
|||
Loading…
Reference in New Issue