framework changes

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
This commit is contained in:
Abhishek Kumar 2026-06-25 10:52:47 +05:30
parent 5a4c449cca
commit 1a4a5118d9
5 changed files with 71 additions and 6 deletions

View File

@ -31,7 +31,7 @@ public class InvalidParameterValueException extends CloudRuntimeException {
}
public InvalidParameterValueException(String key, Map<String, Object> metadata) {
super(ResponseMessageResolver.getMessage(key, metadata), key, metadata);
super(ResponseMessageResolver.resolve(key, metadata));
}
}

View File

@ -17,8 +17,10 @@
package com.cloud.exception;
import java.util.List;
import java.util.Map;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.context.ResponseMessageResolver;
import com.cloud.user.Account;
import com.cloud.utils.SerialVersionUID;
@ -32,6 +34,10 @@ public class PermissionDeniedException extends CloudRuntimeException {
super(message);
}
public PermissionDeniedException(String key, Map<String, Object> metadata) {
super(ResponseMessageResolver.resolve(key, metadata));
}
public PermissionDeniedException(String message, Throwable cause) {
super(message, cause);
}

View File

@ -39,7 +39,10 @@ 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.exception.PermissionDeniedException;
import com.cloud.utils.PropertiesUtil;
import com.cloud.utils.Ternary;
import com.cloud.utils.exception.CloudRuntimeException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
@ -50,7 +53,8 @@ public class ResponseMessageResolver {
protected static final String ERROR_MESSAGES_FILENAME = "error-messages.json";
protected static final String ERROR_KEY_ADMIN_SUFFIX = ".admin";
protected static final boolean INCLUDE_METADATA_ID_IN_MESSAGE = false;
protected static final boolean USE_RESOURCE_TO_STRING_IN_METADATA = false;
protected static final boolean INCLUDE_RESOURCE_ID_FOR_ADMINS_IN_METADATA = true;
private static final Pattern VARIABLE_PATTERN = Pattern.compile("\\{\\{\\s*([A-Za-z0-9_]+)\\s*\\}\\}");
@ -129,7 +133,10 @@ public class ResponseMessageResolver {
if (MapUtils.isNotEmpty(metadata)) {
for (Map.Entry<String, Object> entry : metadata.entrySet()) {
Object value = entry.getValue();
stringMap.put(entry.getKey(), getMetadataObjectStringValueAlt(value));
stringMap.put(entry.getKey(),
USE_RESOURCE_TO_STRING_IN_METADATA ?
getMetadataObjectStringValueAlt(value) :
getMetadataObjectStringValue(value));
}
}
return stringMap;
@ -192,7 +199,7 @@ public class ResponseMessageResolver {
}
Long id = null;
if (INCLUDE_METADATA_ID_IN_MESSAGE && obj instanceof InternalIdentity) {
if (INCLUDE_RESOURCE_ID_FOR_ADMINS_IN_METADATA && obj instanceof InternalIdentity) {
id = ((InternalIdentity) obj).getId();
}
@ -324,6 +331,15 @@ public class ResponseMessageResolver {
return expand(template, getStringMap(combinedMetadata));
}
public static Ternary<String, String, Map<String, Object>> resolve(String errorKey, Map<String, Object> metadata) {
String template = getTemplateForKey(errorKey);
if (template == null) {
return new Ternary<>(errorKey, errorKey, metadata);
}
Map<String, Object> combinedMetadata = getCombinedMetadataFromErrorTemplate(template, metadata);
return new Ternary<>(expand(template, getStringMap(combinedMetadata)), errorKey, combinedMetadata);
}
public static void updateExceptionResponse(ExceptionResponse response, CloudRuntimeException cre) {
String key = cre.getMessageKey();
Map<String, Object> map = cre.getMetadata();
@ -352,4 +368,32 @@ public class ResponseMessageResolver {
response.setErrorText(expand(template, stringMap));
response.setErrorMetadata(stringMap);
}
public static InvalidParameterValueException invalidParameterValueException(String errorKey, Map<String, Object> metadata) {
return new InvalidParameterValueException(errorKey, metadata);
}
public static InvalidParameterValueException invalidParameterValueException(String errorKey) {
return invalidParameterValueException(errorKey, Collections.emptyMap());
}
public static PermissionDeniedException permissionDeniedException(String errorKey, Map<String, Object> metadata) {
return new PermissionDeniedException(errorKey, metadata);
}
public static PermissionDeniedException permissionDeniedException(String errorKey) {
return permissionDeniedException(errorKey, Collections.emptyMap());
}
public static CloudRuntimeException cloudRuntimeException(String errorKey, Map<String, Object> metadata) {
return new CloudRuntimeException(resolve(errorKey, metadata));
}
public static CloudRuntimeException cloudRuntimeException(String errorKey) {
return new CloudRuntimeException(resolve(errorKey, Collections.emptyMap()));
}
public static CloudRuntimeException cloudRuntimeException(String errorKey, Map<String, Object> metadata, Throwable th) {
return new CloudRuntimeException(resolve(errorKey, metadata), th);
}
}

View File

@ -230,12 +230,12 @@ public class ResponseMessageResolverTest {
public void getMetadataObjectStringValue_shouldIncludeIdAndUuidForRootAdmin() {
DataCenter internalIdentityMock = Mockito.mock(DataCenter.class);
when(internalIdentityMock.getUuid()).thenReturn("uuid-5678");
if (ResponseMessageResolver.INCLUDE_METADATA_ID_IN_MESSAGE) {
if (ResponseMessageResolver.INCLUDE_METADATA_ID_FOR_ADMINS_IN_MESSAGE) {
when(internalIdentityMock.getId()).thenReturn(42L);
}
when(internalIdentityMock.getName()).thenReturn("AdminName");
when(CallContext.current().isCallingAccountRootAdmin()).thenReturn(true);
String expected = String.format("'AdminName' (%sUUID: uuid-5678)", ResponseMessageResolver.INCLUDE_METADATA_ID_IN_MESSAGE ? "ID: 42, " : "");
String expected = String.format("'AdminName' (%sUUID: uuid-5678)", ResponseMessageResolver.INCLUDE_METADATA_ID_FOR_ADMINS_IN_MESSAGE ? "ID: 42, " : "");
Assert.assertEquals(expected, ResponseMessageResolver.getMetadataObjectStringValue(internalIdentityMock));
}

View File

@ -28,6 +28,7 @@ import java.util.Map;
import com.cloud.utils.Pair;
import com.cloud.utils.SerialVersionUID;
import com.cloud.utils.Ternary;
/**
* wrap exceptions that you know there's no point in dealing with.
@ -63,6 +64,20 @@ public class CloudRuntimeException extends RuntimeException implements ErrorCont
setCSErrorCode(CSExceptionErrorCode.getCSErrCode(this.getClass().getName()));
}
public CloudRuntimeException(Ternary<String, String, Map<String, Object>> messageKeyAndMetadata) {
super(messageKeyAndMetadata.first());
this.messageKey = messageKeyAndMetadata.second();
this.metadata = messageKeyAndMetadata.third();
setCSErrorCode(CSExceptionErrorCode.getCSErrCode(this.getClass().getName()));
}
public CloudRuntimeException(Ternary<String, String, Map<String, Object>> messageKeyAndMetadata, Throwable th) {
super(messageKeyAndMetadata.first(), th);
this.messageKey = messageKeyAndMetadata.second();
this.metadata = messageKeyAndMetadata.third();
setCSErrorCode(CSExceptionErrorCode.getCSErrCode(this.getClass().getName()));
}
protected CloudRuntimeException() {
super();