From 2e51647e8f6e9127b6f124a92d0c083b36771fd0 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Tue, 6 Jan 2026 18:13:52 +0530 Subject: [PATCH] use separate errorcontext Signed-off-by: Abhishek Kumar --- .../cloudstack/context/CallContext.java | 24 +++++++++++++------ .../context/ErrorMessageResolver.java | 2 +- .../context/ErrorMessageResolverTest.java | 10 ++++---- .../ResourceLimitManagerImpl.java | 8 +++---- .../java/com/cloud/vm/UserVmManagerImpl.java | 2 +- 5 files changed, 28 insertions(+), 18 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/context/CallContext.java b/api/src/main/java/org/apache/cloudstack/context/CallContext.java index 3caced68c10..235198a382a 100644 --- a/api/src/main/java/org/apache/cloudstack/context/CallContext.java +++ b/api/src/main/java/org/apache/cloudstack/context/CallContext.java @@ -20,10 +20,10 @@ import java.util.HashMap; import java.util.Map; import java.util.Stack; import java.util.UUID; -import java.util.stream.Collectors; import org.apache.cloudstack.api.ApiCommandResourceType; import org.apache.cloudstack.managed.threadlocal.ManagedThreadLocal; +import org.apache.commons.collections.MapUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.ThreadContext; @@ -68,6 +68,7 @@ public class CallContext { private User user; private long userId; private final Map context = new HashMap(); + private final Map errorContext = new HashMap(); private Project project; private String apiName; @@ -418,12 +419,6 @@ public class CallContext { return context; } - public Map getContextStringKeyParameters() { - return context.entrySet().stream() - .filter(entry -> entry.getKey() instanceof String) - .collect(Collectors.toMap(entry -> (String) entry.getKey(), Map.Entry::getValue)); - } - public void putContextParameters(Map details){ if (details == null) return; for(Map.Entryentry : details.entrySet()){ @@ -431,6 +426,21 @@ public class CallContext { } } + public Map getErrorContextParameters() { + return errorContext; + } + + public void putErrorContextParameter(String key, Object value) { + errorContext.put(key, value); + } + + public void putErrorContextParameters(Map details) { + if (MapUtils.isEmpty(details)) { + return; + } + errorContext.putAll(details); + } + public static void setActionEventInfo(String eventType, String description) { CallContext context = CallContext.current(); if (context != null) { diff --git a/api/src/main/java/org/apache/cloudstack/context/ErrorMessageResolver.java b/api/src/main/java/org/apache/cloudstack/context/ErrorMessageResolver.java index 291cefc3c10..dfc8dfab83e 100644 --- a/api/src/main/java/org/apache/cloudstack/context/ErrorMessageResolver.java +++ b/api/src/main/java/org/apache/cloudstack/context/ErrorMessageResolver.java @@ -85,7 +85,7 @@ public class ErrorMessageResolver { if (variableNames.isEmpty()) { return metadata; } - Map contextMetadata = CallContext.current().getContextStringKeyParameters(); + Map contextMetadata = CallContext.current().getErrorContextParameters(); if (MapUtils.isEmpty(contextMetadata)) { return metadata; } diff --git a/api/src/test/java/org/apache/cloudstack/context/ErrorMessageResolverTest.java b/api/src/test/java/org/apache/cloudstack/context/ErrorMessageResolverTest.java index 69c8ed96107..95f9c88d2a1 100644 --- a/api/src/test/java/org/apache/cloudstack/context/ErrorMessageResolverTest.java +++ b/api/src/test/java/org/apache/cloudstack/context/ErrorMessageResolverTest.java @@ -135,7 +135,7 @@ public class ErrorMessageResolverTest { public void getCombinedMetadataFromErrorTemplate_shouldReturnEmptyMapWhenContextMetadataIsEmpty() { String template = "This template has {{var1}}."; Map metadata = Map.of(); - when(callContextMock.getContextStringKeyParameters()).thenReturn(Map.of()); + when(callContextMock.getErrorContextParameters()).thenReturn(Map.of()); Map result = ErrorMessageResolver.getCombinedMetadataFromErrorTemplate(template, metadata); Assert.assertTrue("Result should be an empty map", result.isEmpty()); } @@ -144,7 +144,7 @@ public class ErrorMessageResolverTest { public void getCombinedMetadataFromErrorTemplate_shouldCombineContextAndProvidedMetadata() { String template = "This template has {{var1}} and {{var2}}."; Map metadata = Map.of("key1", "value1"); - when(callContextMock.getContextStringKeyParameters()).thenReturn(Map.of("var1", "valueVar1", "var2", "valueVar2")); + when(callContextMock.getErrorContextParameters()).thenReturn(Map.of("var1", "valueVar1", "var2", "valueVar2")); Map result = ErrorMessageResolver.getCombinedMetadataFromErrorTemplate(template, metadata); Assert.assertEquals("Result should contain combined metadata", 3, result.size()); Assert.assertEquals("Result should contain context metadata for var1", "valueVar1", result.get("var1")); @@ -156,7 +156,7 @@ public class ErrorMessageResolverTest { public void getCombinedMetadataFromErrorTemplate_shouldIgnoreVariablesNotInContextMetadata() { String template = "This template has {{var1}} and {{var2}}."; Map metadata = Map.of("key1", "value1"); - when(callContextMock.getContextStringKeyParameters()).thenReturn(Map.of("var1", "valueVar1")); + when(callContextMock.getErrorContextParameters()).thenReturn(Map.of("var1", "valueVar1")); Map result = ErrorMessageResolver.getCombinedMetadataFromErrorTemplate(template, metadata); Assert.assertEquals("Result should contain combined metadata", 2, result.size()); Assert.assertEquals("Result should contain context metadata for var1", "valueVar1", result.get("var1")); @@ -332,7 +332,7 @@ public class ErrorMessageResolverTest { String template = "Error occurred: {{field}}"; Map metadata = Map.of("field", "value"); createTempFileWithTemplate(errorKey, template); - when(callContextMock.getContextStringKeyParameters()).thenReturn(Map.of()); + when(callContextMock.getErrorContextParameters()).thenReturn(Map.of()); String result = ErrorMessageResolver.getMessage(errorKey, metadata); Assert.assertEquals("Error occurred: value", result); } @@ -361,7 +361,7 @@ public class ErrorMessageResolverTest { String template = "Error in {{field1}} and {{field2}}."; Map metadata = Map.of("field1", "value1"); createTempFileWithTemplate(errorKey, template); - when(callContextMock.getContextStringKeyParameters()).thenReturn(Map.of("field2", "value2")); + when(callContextMock.getErrorContextParameters()).thenReturn(Map.of("field2", "value2")); String result = ErrorMessageResolver.getMessage(errorKey, metadata); Assert.assertEquals("Error in value1 and value2.", result); } diff --git a/server/src/main/java/com/cloud/resourcelimit/ResourceLimitManagerImpl.java b/server/src/main/java/com/cloud/resourcelimit/ResourceLimitManagerImpl.java index 555747c149e..af31410b924 100644 --- a/server/src/main/java/com/cloud/resourcelimit/ResourceLimitManagerImpl.java +++ b/server/src/main/java/com/cloud/resourcelimit/ResourceLimitManagerImpl.java @@ -558,7 +558,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim if (domainResourceLimit != Resource.RESOURCE_UNLIMITED && requestedDomainResourceCount > domainResourceLimit) { String message = "Maximum" + messageSuffix; - Map details = new HashMap<>(); + 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("resourceOwnerDomain", domain); @@ -567,7 +567,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim details.put("resourceAmount", convCurrentDomainResourceCount); details.put("resourceReserved", convCurrentResourceReservation); details.put("resourceRequested", convNumResources); - CallContext.current().putContextParameters(details); + CallContext.current().putErrorContextParameters(details); ResourceAllocationException e = new ResourceAllocationException(message, type); logger.error(message, e); throw e; @@ -607,7 +607,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim if (accountResourceLimit != Resource.RESOURCE_UNLIMITED && requestedResourceCount > accountResourceLimit) { String message = "Maximum" + messageSuffix; - Map details = new HashMap<>(); + 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"); @@ -615,7 +615,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim details.put("resourceAmount", convertedCurrentResourceCount); details.put("resourceReserved", convertedCurrentResourceReservation); details.put("resourceRequested", convertedNumResources); - CallContext.current().putContextParameters(details); + CallContext.current().putErrorContextParameters(details); ResourceAllocationException e = new ResourceAllocationException(message, type); logger.error(message, e); throw e; diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index b46d9703ccd..5366c408626 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -6322,7 +6322,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } private void verifyServiceOffering(BaseDeployVMCmd cmd, ServiceOffering serviceOffering) { - CallContext.current().putContextParameter("serviceOffering", serviceOffering); + CallContext.current().putErrorContextParameter("serviceOffering", serviceOffering); if (ServiceOffering.State.Inactive.equals(serviceOffering.getState())) { throw new InvalidParameterValueException("vm.deploy.serviceoffering.inactive", Collections.emptyMap());