From df51afb7a14de1c2d5ea086a343500c8cf434f4f Mon Sep 17 00:00:00 2001 From: Suresh Kumar Anaparti Date: Fri, 2 Aug 2024 18:09:26 +0530 Subject: [PATCH 1/5] Update project account in the events for all project events, except for create project events --- .../user/account/AddUserToProjectCmd.java | 2 +- .../user/account/DeleteUserFromProjectCmd.java | 1 - .../cloud/event/ActionEventInterceptor.java | 6 ++++-- .../java/com/cloud/event/ActionEventUtils.java | 6 +++++- .../com/cloud/projects/ProjectManagerImpl.java | 18 +++++++++--------- 5 files changed, 19 insertions(+), 14 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/account/AddUserToProjectCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/account/AddUserToProjectCmd.java index d38ae057f058..9cd845c774c5 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/account/AddUserToProjectCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/account/AddUserToProjectCmd.java @@ -103,7 +103,7 @@ public String getEventType() { @Override public String getEventDescription() { - return "Adding user "+getUsername()+" to Project "+getProjectId(); + return "Adding user " + getUsername() + " to project: " + getProjectId(); } ///////////////////////////////////////////////////// diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/account/DeleteUserFromProjectCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/account/DeleteUserFromProjectCmd.java index 596fb876008c..fbcffb7332c2 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/account/DeleteUserFromProjectCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/account/DeleteUserFromProjectCmd.java @@ -83,7 +83,6 @@ public String getEventDescription() { return "Removing user " + userId + " from project: " + projectId; } - @Override public long getEntityOwnerId() { Project project = _projectService.getProject(projectId); diff --git a/server/src/main/java/com/cloud/event/ActionEventInterceptor.java b/server/src/main/java/com/cloud/event/ActionEventInterceptor.java index ee025c825f50..be7f47b04228 100644 --- a/server/src/main/java/com/cloud/event/ActionEventInterceptor.java +++ b/server/src/main/java/com/cloud/event/ActionEventInterceptor.java @@ -88,13 +88,14 @@ public void interceptComplete(Method method, Object target, Object event) { for (ActionEvent actionEvent : getActionEvents(method)) { CallContext ctx = CallContext.current(); long userId = ctx.getCallingUserId(); - long accountId = ctx.getProject() != null ? ctx.getProject().getProjectAccountId() : ctx.getCallingAccountId(); //This should be the entity owner id rather than the Calling User Account Id. long startEventId = ctx.getStartEventId(); String eventDescription = getEventDescription(actionEvent, ctx); Long eventResourceId = getEventResourceId(actionEvent, ctx); String eventResourceType = getEventResourceType(actionEvent, ctx); String eventType = getEventType(actionEvent, ctx); boolean isEventDisplayEnabled = ctx.isEventDisplayEnabled(); + boolean projectCreateEvent = "project".equalsIgnoreCase(eventResourceType) && actionEvent.create(); + long accountId = ctx.getProject() != null && !projectCreateEvent ? ctx.getProject().getProjectAccountId() : ctx.getCallingAccountId(); //This should be the entity owner id rather than the Calling User Account Id. if (eventType.equals("")) return; @@ -118,13 +119,14 @@ public void interceptException(Method method, Object target, Object event) { for (ActionEvent actionEvent : getActionEvents(method)) { CallContext ctx = CallContext.current(); long userId = ctx.getCallingUserId(); - long accountId = ctx.getCallingAccountId(); long startEventId = ctx.getStartEventId(); String eventDescription = getEventDescription(actionEvent, ctx); Long eventResourceId = getEventResourceId(actionEvent, ctx); String eventResourceType = getEventResourceType(actionEvent, ctx); String eventType = getEventType(actionEvent, ctx); boolean isEventDisplayEnabled = ctx.isEventDisplayEnabled(); + boolean projectCreateEvent = "project".equalsIgnoreCase(eventResourceType) && actionEvent.create(); + long accountId = ctx.getProject() != null && !projectCreateEvent ? ctx.getProject().getProjectAccountId() : ctx.getCallingAccountId(); //This should be the entity owner id rather than the Calling User Account Id. if (eventType.equals("")) return; diff --git a/server/src/main/java/com/cloud/event/ActionEventUtils.java b/server/src/main/java/com/cloud/event/ActionEventUtils.java index 36461d20e421..e3e1d84b5a3a 100644 --- a/server/src/main/java/com/cloud/event/ActionEventUtils.java +++ b/server/src/main/java/com/cloud/event/ActionEventUtils.java @@ -110,6 +110,9 @@ public static Long onActionEvent(Long userId, Long accountId, Long domainId, Str */ public static Long onScheduledActionEvent(Long userId, Long accountId, String type, String description, Long resourceId, String resourceType, boolean eventDisplayEnabled, long startEventId) { Ternary resourceDetails = getResourceDetails(resourceId, resourceType, type); + CallContext ctx = CallContext.current(); + boolean projectCreateEvent = "project".equalsIgnoreCase(resourceType) && EventTypes.EVENT_PROJECT_CREATE.equalsIgnoreCase(type); + accountId = ctx.getProject() != null && !projectCreateEvent ? ctx.getProject().getProjectAccountId() : accountId; //This should be the entity owner id rather than the Calling User Account Id. publishOnEventBus(userId, accountId, EventCategory.ACTION_EVENT.getName(), type, com.cloud.event.Event.State.Scheduled, description, resourceDetails.second(), resourceDetails.third()); Event event = persistActionEvent(userId, accountId, null, null, type, Event.State.Scheduled, eventDisplayEnabled, description, resourceDetails.first(), resourceDetails.third(), startEventId); return event.getId(); @@ -123,7 +126,8 @@ public static void startNestedActionEvent(String eventType, String eventDescript public static void onStartedActionEventFromContext(String eventType, String eventDescription, Long resourceId, String resourceType, boolean eventDisplayEnabled) { CallContext ctx = CallContext.current(); long userId = ctx.getCallingUserId(); - long accountId = ctx.getProject() != null ? ctx.getProject().getProjectAccountId() : ctx.getCallingAccountId(); //This should be the entity owner id rather than the Calling User Account Id. + boolean projectCreateEvent = "project".equalsIgnoreCase(resourceType) && EventTypes.EVENT_PROJECT_CREATE.equalsIgnoreCase(eventType); + long accountId = ctx.getProject() != null && !projectCreateEvent ? ctx.getProject().getProjectAccountId() : ctx.getCallingAccountId(); //This should be the entity owner id rather than the Calling User Account Id. long startEventId = ctx.getStartEventId(); if (!eventType.equals("")) diff --git a/server/src/main/java/com/cloud/projects/ProjectManagerImpl.java b/server/src/main/java/com/cloud/projects/ProjectManagerImpl.java index 19776d4993f5..15633e986ec0 100644 --- a/server/src/main/java/com/cloud/projects/ProjectManagerImpl.java +++ b/server/src/main/java/com/cloud/projects/ProjectManagerImpl.java @@ -279,16 +279,16 @@ public Project doInTransaction(TransactionStatus status) { assignAccountToProject(project, ownerFinal.getId(), ProjectAccount.Role.Admin, Optional.ofNullable(finalUser).map(User::getId).orElse(null), null); - if (project != null) { - CallContext.current().setEventDetails("Project id=" + project.getId()); - CallContext.current().putContextParameter(Project.class, project.getUuid()); - } + if (project != null) { + CallContext.current().setEventDetails("Project id=" + project.getId()); + CallContext.current().putContextParameter(Project.class, project.getUuid()); + } - //Increment resource count + //Increment resource count _resourceLimitMgr.incrementResourceCount(ownerFinal.getId(), ResourceType.project); - return project; - } + return project; + } }); messageBus.publish(_name, ProjectManager.MESSAGE_CREATE_TUNGSTEN_PROJECT_EVENT, PublishScope.LOCAL, project); @@ -297,7 +297,7 @@ public Project doInTransaction(TransactionStatus status) { } @Override - @ActionEvent(eventType = EventTypes.EVENT_PROJECT_CREATE, eventDescription = "creating project", async = true) + @ActionEvent(eventType = EventTypes.EVENT_PROJECT_CREATE, eventDescription = "enabling project", async = true, create = true) @DB public Project enableProject(long projectId) { Account caller = CallContext.current().getCallingAccount(); @@ -1275,7 +1275,7 @@ public List listPermittedProjectAccounts(long accountId) { } @Override - @ActionEvent(eventType = EventTypes.EVENT_PROJECT_ACTIVATE, eventDescription = "activating project") + @ActionEvent(eventType = EventTypes.EVENT_PROJECT_ACTIVATE, eventDescription = "activating project", async = true) @DB public Project activateProject(final long projectId) { Account caller = CallContext.current().getCallingAccount(); From ec4ea3e5d2984cdbc06a00fb6d75b8ee28f7bb38 Mon Sep 17 00:00:00 2001 From: Suresh Kumar Anaparti Date: Thu, 22 Aug 2024 15:27:05 +0530 Subject: [PATCH 2/5] refactored project create event check --- .../src/main/java/com/cloud/event/ActionEventInterceptor.java | 4 ++-- .../src/main/java/com/cloud/projects/ProjectManagerImpl.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/server/src/main/java/com/cloud/event/ActionEventInterceptor.java b/server/src/main/java/com/cloud/event/ActionEventInterceptor.java index be7f47b04228..84bb63e29e5e 100644 --- a/server/src/main/java/com/cloud/event/ActionEventInterceptor.java +++ b/server/src/main/java/com/cloud/event/ActionEventInterceptor.java @@ -94,7 +94,7 @@ public void interceptComplete(Method method, Object target, Object event) { String eventResourceType = getEventResourceType(actionEvent, ctx); String eventType = getEventType(actionEvent, ctx); boolean isEventDisplayEnabled = ctx.isEventDisplayEnabled(); - boolean projectCreateEvent = "project".equalsIgnoreCase(eventResourceType) && actionEvent.create(); + boolean projectCreateEvent = "project".equalsIgnoreCase(eventResourceType) && EventTypes.EVENT_PROJECT_CREATE.equalsIgnoreCase(eventType); long accountId = ctx.getProject() != null && !projectCreateEvent ? ctx.getProject().getProjectAccountId() : ctx.getCallingAccountId(); //This should be the entity owner id rather than the Calling User Account Id. if (eventType.equals("")) @@ -125,7 +125,7 @@ public void interceptException(Method method, Object target, Object event) { String eventResourceType = getEventResourceType(actionEvent, ctx); String eventType = getEventType(actionEvent, ctx); boolean isEventDisplayEnabled = ctx.isEventDisplayEnabled(); - boolean projectCreateEvent = "project".equalsIgnoreCase(eventResourceType) && actionEvent.create(); + boolean projectCreateEvent = "project".equalsIgnoreCase(eventResourceType) && EventTypes.EVENT_PROJECT_CREATE.equalsIgnoreCase(eventType); long accountId = ctx.getProject() != null && !projectCreateEvent ? ctx.getProject().getProjectAccountId() : ctx.getCallingAccountId(); //This should be the entity owner id rather than the Calling User Account Id. if (eventType.equals("")) diff --git a/server/src/main/java/com/cloud/projects/ProjectManagerImpl.java b/server/src/main/java/com/cloud/projects/ProjectManagerImpl.java index 15633e986ec0..abdd48cd4ae1 100644 --- a/server/src/main/java/com/cloud/projects/ProjectManagerImpl.java +++ b/server/src/main/java/com/cloud/projects/ProjectManagerImpl.java @@ -297,7 +297,7 @@ public Project doInTransaction(TransactionStatus status) { } @Override - @ActionEvent(eventType = EventTypes.EVENT_PROJECT_CREATE, eventDescription = "enabling project", async = true, create = true) + @ActionEvent(eventType = EventTypes.EVENT_PROJECT_CREATE, eventDescription = "creating project", async = true) @DB public Project enableProject(long projectId) { Account caller = CallContext.current().getCallingAccount(); From c797b3ef8bfb8f14dd1348e681c62a3d72579c5d Mon Sep 17 00:00:00 2001 From: Suresh Kumar Anaparti Date: Thu, 22 Aug 2024 18:45:03 +0530 Subject: [PATCH 3/5] updated project create event check --- .../main/java/com/cloud/event/ActionEventInterceptor.java | 6 ++---- server/src/main/java/com/cloud/event/ActionEventUtils.java | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/server/src/main/java/com/cloud/event/ActionEventInterceptor.java b/server/src/main/java/com/cloud/event/ActionEventInterceptor.java index 84bb63e29e5e..fd3609faba50 100644 --- a/server/src/main/java/com/cloud/event/ActionEventInterceptor.java +++ b/server/src/main/java/com/cloud/event/ActionEventInterceptor.java @@ -94,8 +94,7 @@ public void interceptComplete(Method method, Object target, Object event) { String eventResourceType = getEventResourceType(actionEvent, ctx); String eventType = getEventType(actionEvent, ctx); boolean isEventDisplayEnabled = ctx.isEventDisplayEnabled(); - boolean projectCreateEvent = "project".equalsIgnoreCase(eventResourceType) && EventTypes.EVENT_PROJECT_CREATE.equalsIgnoreCase(eventType); - long accountId = ctx.getProject() != null && !projectCreateEvent ? ctx.getProject().getProjectAccountId() : ctx.getCallingAccountId(); //This should be the entity owner id rather than the Calling User Account Id. + long accountId = ctx.getProject() != null && !EventTypes.EVENT_PROJECT_CREATE.equalsIgnoreCase(eventType) ? ctx.getProject().getProjectAccountId() : ctx.getCallingAccountId(); //This should be the entity owner id rather than the Calling User Account Id. if (eventType.equals("")) return; @@ -125,8 +124,7 @@ public void interceptException(Method method, Object target, Object event) { String eventResourceType = getEventResourceType(actionEvent, ctx); String eventType = getEventType(actionEvent, ctx); boolean isEventDisplayEnabled = ctx.isEventDisplayEnabled(); - boolean projectCreateEvent = "project".equalsIgnoreCase(eventResourceType) && EventTypes.EVENT_PROJECT_CREATE.equalsIgnoreCase(eventType); - long accountId = ctx.getProject() != null && !projectCreateEvent ? ctx.getProject().getProjectAccountId() : ctx.getCallingAccountId(); //This should be the entity owner id rather than the Calling User Account Id. + long accountId = ctx.getProject() != null && !EventTypes.EVENT_PROJECT_CREATE.equalsIgnoreCase(eventType) ? ctx.getProject().getProjectAccountId() : ctx.getCallingAccountId(); //This should be the entity owner id rather than the Calling User Account Id. if (eventType.equals("")) return; diff --git a/server/src/main/java/com/cloud/event/ActionEventUtils.java b/server/src/main/java/com/cloud/event/ActionEventUtils.java index e3e1d84b5a3a..c791b854ec89 100644 --- a/server/src/main/java/com/cloud/event/ActionEventUtils.java +++ b/server/src/main/java/com/cloud/event/ActionEventUtils.java @@ -111,8 +111,7 @@ public static Long onActionEvent(Long userId, Long accountId, Long domainId, Str public static Long onScheduledActionEvent(Long userId, Long accountId, String type, String description, Long resourceId, String resourceType, boolean eventDisplayEnabled, long startEventId) { Ternary resourceDetails = getResourceDetails(resourceId, resourceType, type); CallContext ctx = CallContext.current(); - boolean projectCreateEvent = "project".equalsIgnoreCase(resourceType) && EventTypes.EVENT_PROJECT_CREATE.equalsIgnoreCase(type); - accountId = ctx.getProject() != null && !projectCreateEvent ? ctx.getProject().getProjectAccountId() : accountId; //This should be the entity owner id rather than the Calling User Account Id. + accountId = ctx.getProject() != null && !EventTypes.EVENT_PROJECT_CREATE.equalsIgnoreCase(type) ? ctx.getProject().getProjectAccountId() : accountId; //This should be the entity owner id rather than the Calling User Account Id. publishOnEventBus(userId, accountId, EventCategory.ACTION_EVENT.getName(), type, com.cloud.event.Event.State.Scheduled, description, resourceDetails.second(), resourceDetails.third()); Event event = persistActionEvent(userId, accountId, null, null, type, Event.State.Scheduled, eventDisplayEnabled, description, resourceDetails.first(), resourceDetails.third(), startEventId); return event.getId(); @@ -126,8 +125,7 @@ public static void startNestedActionEvent(String eventType, String eventDescript public static void onStartedActionEventFromContext(String eventType, String eventDescription, Long resourceId, String resourceType, boolean eventDisplayEnabled) { CallContext ctx = CallContext.current(); long userId = ctx.getCallingUserId(); - boolean projectCreateEvent = "project".equalsIgnoreCase(resourceType) && EventTypes.EVENT_PROJECT_CREATE.equalsIgnoreCase(eventType); - long accountId = ctx.getProject() != null && !projectCreateEvent ? ctx.getProject().getProjectAccountId() : ctx.getCallingAccountId(); //This should be the entity owner id rather than the Calling User Account Id. + long accountId = ctx.getProject() != null && !EventTypes.EVENT_PROJECT_CREATE.equalsIgnoreCase(eventType) ? ctx.getProject().getProjectAccountId() : ctx.getCallingAccountId(); //This should be the entity owner id rather than the Calling User Account Id. long startEventId = ctx.getStartEventId(); if (!eventType.equals("")) From fa6b04e2cb787ed82f50f34af5eb37b4418e3774 Mon Sep 17 00:00:00 2001 From: Suresh Kumar Anaparti Date: Thu, 22 Aug 2024 21:05:28 +0530 Subject: [PATCH 4/5] review comments --- .../java/com/cloud/event/ActionEventInterceptor.java | 4 ++-- .../src/main/java/com/cloud/event/ActionEventUtils.java | 9 ++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/server/src/main/java/com/cloud/event/ActionEventInterceptor.java b/server/src/main/java/com/cloud/event/ActionEventInterceptor.java index fd3609faba50..9554ae34cb61 100644 --- a/server/src/main/java/com/cloud/event/ActionEventInterceptor.java +++ b/server/src/main/java/com/cloud/event/ActionEventInterceptor.java @@ -94,7 +94,7 @@ public void interceptComplete(Method method, Object target, Object event) { String eventResourceType = getEventResourceType(actionEvent, ctx); String eventType = getEventType(actionEvent, ctx); boolean isEventDisplayEnabled = ctx.isEventDisplayEnabled(); - long accountId = ctx.getProject() != null && !EventTypes.EVENT_PROJECT_CREATE.equalsIgnoreCase(eventType) ? ctx.getProject().getProjectAccountId() : ctx.getCallingAccountId(); //This should be the entity owner id rather than the Calling User Account Id. + long accountId = ActionEventUtils.getOwnerAccountId(ctx, eventType, ctx.getCallingAccountId()); if (eventType.equals("")) return; @@ -124,7 +124,7 @@ public void interceptException(Method method, Object target, Object event) { String eventResourceType = getEventResourceType(actionEvent, ctx); String eventType = getEventType(actionEvent, ctx); boolean isEventDisplayEnabled = ctx.isEventDisplayEnabled(); - long accountId = ctx.getProject() != null && !EventTypes.EVENT_PROJECT_CREATE.equalsIgnoreCase(eventType) ? ctx.getProject().getProjectAccountId() : ctx.getCallingAccountId(); //This should be the entity owner id rather than the Calling User Account Id. + long accountId = ActionEventUtils.getOwnerAccountId(ctx, eventType, ctx.getCallingAccountId()); if (eventType.equals("")) return; diff --git a/server/src/main/java/com/cloud/event/ActionEventUtils.java b/server/src/main/java/com/cloud/event/ActionEventUtils.java index c791b854ec89..4450f6edb118 100644 --- a/server/src/main/java/com/cloud/event/ActionEventUtils.java +++ b/server/src/main/java/com/cloud/event/ActionEventUtils.java @@ -111,7 +111,7 @@ public static Long onActionEvent(Long userId, Long accountId, Long domainId, Str public static Long onScheduledActionEvent(Long userId, Long accountId, String type, String description, Long resourceId, String resourceType, boolean eventDisplayEnabled, long startEventId) { Ternary resourceDetails = getResourceDetails(resourceId, resourceType, type); CallContext ctx = CallContext.current(); - accountId = ctx.getProject() != null && !EventTypes.EVENT_PROJECT_CREATE.equalsIgnoreCase(type) ? ctx.getProject().getProjectAccountId() : accountId; //This should be the entity owner id rather than the Calling User Account Id. + accountId = getOwnerAccountId(ctx, type, accountId); publishOnEventBus(userId, accountId, EventCategory.ACTION_EVENT.getName(), type, com.cloud.event.Event.State.Scheduled, description, resourceDetails.second(), resourceDetails.third()); Event event = persistActionEvent(userId, accountId, null, null, type, Event.State.Scheduled, eventDisplayEnabled, description, resourceDetails.first(), resourceDetails.third(), startEventId); return event.getId(); @@ -125,7 +125,7 @@ public static void startNestedActionEvent(String eventType, String eventDescript public static void onStartedActionEventFromContext(String eventType, String eventDescription, Long resourceId, String resourceType, boolean eventDisplayEnabled) { CallContext ctx = CallContext.current(); long userId = ctx.getCallingUserId(); - long accountId = ctx.getProject() != null && !EventTypes.EVENT_PROJECT_CREATE.equalsIgnoreCase(eventType) ? ctx.getProject().getProjectAccountId() : ctx.getCallingAccountId(); //This should be the entity owner id rather than the Calling User Account Id. + long accountId = getOwnerAccountId(ctx, eventType, ctx.getCallingAccountId()); long startEventId = ctx.getStartEventId(); if (!eventType.equals("")) @@ -395,7 +395,10 @@ private static void populateFirstClassEntities(Map eventDescript s_logger.trace("Caught exception while populating first class entities for event bus, moving on"); } } - } + public static long getOwnerAccountId(CallContext ctx, String eventType, long callingAccountId) { + long accountId = ctx.getProject() != null && !EventTypes.EVENT_PROJECT_CREATE.equalsIgnoreCase(eventType) ? ctx.getProject().getProjectAccountId() : callingAccountId; //This should be the entity owner id rather than the Calling User Account Id. + return accountId; + } } From 97a3fb718fb687278841db9dfab7757ab852236e Mon Sep 17 00:00:00 2001 From: Suresh Kumar Anaparti Date: Mon, 26 Aug 2024 15:54:05 +0530 Subject: [PATCH 5/5] keep calling account for update & delete project events --- server/src/main/java/com/cloud/event/ActionEventUtils.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/src/main/java/com/cloud/event/ActionEventUtils.java b/server/src/main/java/com/cloud/event/ActionEventUtils.java index 4450f6edb118..87dd4ef8af90 100644 --- a/server/src/main/java/com/cloud/event/ActionEventUtils.java +++ b/server/src/main/java/com/cloud/event/ActionEventUtils.java @@ -22,6 +22,7 @@ import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; +import java.util.List; import java.util.Map; import javax.annotation.PostConstruct; @@ -398,7 +399,8 @@ private static void populateFirstClassEntities(Map eventDescript } public static long getOwnerAccountId(CallContext ctx, String eventType, long callingAccountId) { - long accountId = ctx.getProject() != null && !EventTypes.EVENT_PROJECT_CREATE.equalsIgnoreCase(eventType) ? ctx.getProject().getProjectAccountId() : callingAccountId; //This should be the entity owner id rather than the Calling User Account Id. + List mainProjectEvents = List.of(EventTypes.EVENT_PROJECT_CREATE, EventTypes.EVENT_PROJECT_UPDATE, EventTypes.EVENT_PROJECT_DELETE); + long accountId = ctx.getProject() != null && !mainProjectEvents.stream().anyMatch(eventType::equalsIgnoreCase) ? ctx.getProject().getProjectAccountId() : callingAccountId; //This should be the entity owner id rather than the Calling User Account Id. return accountId; } }