2323
2424import org .apache .cloudstack .api .ApiCommandResourceType ;
2525import org .apache .cloudstack .managed .threadlocal .ManagedThreadLocal ;
26- import org .apache .logging . log4j . Logger ;
26+ import org .apache .commons . collections . MapUtils ;
2727import org .apache .logging .log4j .LogManager ;
28+ import org .apache .logging .log4j .Logger ;
29+ import org .apache .logging .log4j .ThreadContext ;
30+ import org .springframework .beans .factory .NoSuchBeanDefinitionException ;
2831
2932import com .cloud .exception .CloudAuthenticationException ;
3033import com .cloud .projects .Project ;
3134import com .cloud .user .Account ;
35+ import com .cloud .user .AccountService ;
3236import com .cloud .user .User ;
3337import com .cloud .utils .UuidUtils ;
38+ import com .cloud .utils .component .ComponentContext ;
3439import com .cloud .utils .db .EntityManager ;
3540import com .cloud .utils .exception .CloudRuntimeException ;
36- import org .apache .logging .log4j .ThreadContext ;
3741
3842/**
3943 * CallContext records information about the environment the call is made. This
@@ -53,6 +57,7 @@ protected Stack<CallContext> initialValue() {
5357 private String contextId ;
5458 private Account account ;
5559 private long accountId ;
60+ private Boolean isAccountRootAdmin = null ;
5661 private long startEventId = 0 ;
5762 private String eventDescription ;
5863 private String eventDetails ;
@@ -64,6 +69,7 @@ protected Stack<CallContext> initialValue() {
6469 private long userId ;
6570 private final Map <Object , Object > context = new HashMap <Object , Object >();
6671 private final Map <String , String > apiResourcesUuids = new HashMap <>();
72+ private final Map <String , Object > errorContext = new HashMap <>();
6773 private Project project ;
6874 private String apiName ;
6975
@@ -135,6 +141,25 @@ public Account getCallingAccount() {
135141 return account ;
136142 }
137143
144+ public boolean isCallingAccountRootAdmin () {
145+ if (isAccountRootAdmin != null ) {
146+ return isAccountRootAdmin ;
147+ }
148+ if (account == null && s_entityMgr == null ) {
149+ return false ;
150+ }
151+ Account caller = getCallingAccount ();
152+ AccountService accountService ;
153+ try {
154+ accountService = ComponentContext .getDelegateComponentOfType (AccountService .class );
155+ } catch (NoSuchBeanDefinitionException e ) {
156+ LOGGER .warn ("Falling back to account type check for isRootAdmin for account ID: {} as no AccountService bean found: {}" , accountId , e .getMessage ());
157+ return caller != null && caller .getType () == Account .Type .ADMIN ;
158+ }
159+ isAccountRootAdmin = accountService .isRootAdmin (caller );
160+ return isAccountRootAdmin ;
161+ }
162+
138163 public static CallContext current () {
139164 CallContext context = s_currentContext .get ();
140165
@@ -408,6 +433,21 @@ public void putContextParameters(Map<Object, Object> details){
408433 }
409434 }
410435
436+ public Map <String , Object > getErrorContextParameters () {
437+ return errorContext ;
438+ }
439+
440+ public void putErrorContextParameter (String key , Object value ) {
441+ errorContext .put (key , value );
442+ }
443+
444+ public void putErrorContextParameters (Map <String , Object > details ) {
445+ if (MapUtils .isEmpty (details )) {
446+ return ;
447+ }
448+ errorContext .putAll (details );
449+ }
450+
411451 public static void setActionEventInfo (String eventType , String description ) {
412452 CallContext context = CallContext .current ();
413453 if (context != null ) {
0 commit comments