chore: analytic events added for reactive behaviour change (#40917)
## Description This PR adds / updates following analytic events for reactivity run behaviour changes either by system or by user: Metric | Event Name | Type -- | -- | -- Run behavior change tracking | action_RUN_BEHAVIOUR_CHANGED | New Event Run behavior context on action execution | execute_ACTION_TRIGGERED -> runBehavior (property) | New Property in existing events <!-- notionvc: ce53e230-1711-4c71-8aa6-9430412e7cbb --> Fixes #`Issue Number` _or_ Fixes `Issue URL` > [!WARNING] > _If no issue exists, please create an issue first, and check with the maintainers if the issue is valid._ ## Automation /ok-to-test tags="@tag.Sanity, @tag.Widget" ### 🔍 Cypress test results <!-- This is an auto-generated comment: Cypress test results --> > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: <https://github.com/appsmithorg/appsmith/actions/runs/15700973404> > Commit: b347ce21ed946053950a22ecca084874debe254f > <a href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=15700973404&attempt=1" target="_blank">Cypress dashboard</a>. > Tags: `@tag.Sanity, @tag.Widget` > Spec: > <hr>Tue, 17 Jun 2025 07:46:20 UTC <!-- end of auto-generated comment: Cypress test results --> ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added analytics tracking for changes in the run behavior of actions and executables, capturing detailed information about each change. - **Enhancements** - Analytics events now include the run behavior configuration when actions are executed. - **Chores** - Updated internal constants to support new analytics event types and fields. - Integrated new dependencies to support analytics reporting for run behavior changes. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: “sneha122” <“sneha@appsmith.com”>
This commit is contained in:
parent
db721b568f
commit
685e9553b3
|
|
@ -24,6 +24,7 @@ public enum AnalyticsEvents {
|
||||||
PAGE_REORDER,
|
PAGE_REORDER,
|
||||||
GENERATE_CRUD_PAGE("generate_CRUD_PAGE"),
|
GENERATE_CRUD_PAGE("generate_CRUD_PAGE"),
|
||||||
CREATE_SUPERUSER,
|
CREATE_SUPERUSER,
|
||||||
|
ACTION_RUN_BEHAVIOUR_CHANGED("action_RUN_BEHAVIOUR_CHANGED"),
|
||||||
SUBSCRIBE_MARKETING_EMAILS,
|
SUBSCRIBE_MARKETING_EMAILS,
|
||||||
UNSUBSCRIBE_MARKETING_EMAILS,
|
UNSUBSCRIBE_MARKETING_EMAILS,
|
||||||
INSTALLATION_SETUP_COMPLETE("Installation Setup Complete"),
|
INSTALLATION_SETUP_COMPLETE("Installation Setup Complete"),
|
||||||
|
|
|
||||||
|
|
@ -209,4 +209,6 @@ public class FieldNameCE {
|
||||||
public static final String NONE = "none";
|
public static final String NONE = "none";
|
||||||
public static final String ORGANIZATION_ADMINISTRATOR_ROLE = "Organization Administrator Role";
|
public static final String ORGANIZATION_ADMINISTRATOR_ROLE = "Organization Administrator Role";
|
||||||
public static final String INSTANCE_VARIABLES = "instanceVariables";
|
public static final String INSTANCE_VARIABLES = "instanceVariables";
|
||||||
|
|
||||||
|
public static final String ACTION_CONFIGURATION_RUN_BEHAVIOUR = "runBehaviour";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.appsmith.server.domains;
|
||||||
|
|
||||||
|
import com.appsmith.external.models.ActionDTO;
|
||||||
|
import com.appsmith.external.models.CreatorContextType;
|
||||||
|
import com.appsmith.external.models.RunBehaviourEnum;
|
||||||
|
import com.appsmith.server.enums.RunBehaviourUpdateSource;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
public class RunBehaviourAnalyticsMetadata {
|
||||||
|
private ActionDTO actionDTO;
|
||||||
|
private RunBehaviourEnum oldRunBehaviour;
|
||||||
|
private CreatorContextType creatorContextType;
|
||||||
|
private RunBehaviourUpdateSource wasChangedBy;
|
||||||
|
private boolean isActionPartOfModuleInstance;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
package com.appsmith.server.enums;
|
||||||
|
|
||||||
|
public enum RunBehaviourUpdateSource {
|
||||||
|
SYSTEM,
|
||||||
|
USER
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,106 @@
|
||||||
|
package com.appsmith.server.helpers;
|
||||||
|
|
||||||
|
import com.appsmith.external.constants.AnalyticsEvents;
|
||||||
|
import com.appsmith.external.models.ActionDTO;
|
||||||
|
import com.appsmith.external.models.CreatorContextType;
|
||||||
|
import com.appsmith.external.models.RunBehaviourEnum;
|
||||||
|
import com.appsmith.server.applications.base.ApplicationService;
|
||||||
|
import com.appsmith.server.constants.FieldName;
|
||||||
|
import com.appsmith.server.domains.Application;
|
||||||
|
import com.appsmith.server.domains.ApplicationMode;
|
||||||
|
import com.appsmith.server.domains.RunBehaviourAnalyticsMetadata;
|
||||||
|
import com.appsmith.server.enums.RunBehaviourUpdateSource;
|
||||||
|
import com.appsmith.server.services.AnalyticsService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static java.lang.Boolean.TRUE;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class RunBehaviourAnalyticsUtils {
|
||||||
|
|
||||||
|
private final AnalyticsService analyticsService;
|
||||||
|
private final ApplicationService applicationService;
|
||||||
|
|
||||||
|
public Mono<Void> sendRunBehaviourChangedAnalytics(RunBehaviourAnalyticsMetadata params) {
|
||||||
|
ActionDTO actionDTO = params.getActionDTO();
|
||||||
|
RunBehaviourEnum oldRunBehaviour = params.getOldRunBehaviour();
|
||||||
|
CreatorContextType creatorType = params.getCreatorContextType();
|
||||||
|
RunBehaviourUpdateSource wasChangedBy = params.getWasChangedBy();
|
||||||
|
boolean isActionPartOfModuleInstance = params.isActionPartOfModuleInstance();
|
||||||
|
|
||||||
|
return Mono.justOrEmpty(actionDTO.getApplicationId())
|
||||||
|
.flatMap(applicationService::findById)
|
||||||
|
.defaultIfEmpty(new Application())
|
||||||
|
.flatMap(application -> {
|
||||||
|
Map<String, Object> data = new HashMap<>();
|
||||||
|
data.put("actionId", ObjectUtils.defaultIfNull(actionDTO.getId(), ""));
|
||||||
|
data.put("name", ObjectUtils.defaultIfNull(actionDTO.getName(), ""));
|
||||||
|
data.put("pageId", ObjectUtils.defaultIfNull(actionDTO.getPageId(), ""));
|
||||||
|
data.put("applicationId", ObjectUtils.defaultIfNull(actionDTO.getApplicationId(), ""));
|
||||||
|
data.put("pluginId", ObjectUtils.defaultIfNull(actionDTO.getPluginId(), ""));
|
||||||
|
data.put("pluginName", ObjectUtils.defaultIfNull(actionDTO.getPluginName(), ""));
|
||||||
|
data.put("createdAt", ObjectUtils.defaultIfNull(actionDTO.getCreatedAt(), ""));
|
||||||
|
data.put("oldRunBehaviour", ObjectUtils.defaultIfNull(oldRunBehaviour, ""));
|
||||||
|
data.put("newRunBehaviour", ObjectUtils.defaultIfNull(actionDTO.getRunBehaviour(), ""));
|
||||||
|
data.put("pluginType", ObjectUtils.defaultIfNull(actionDTO.getPluginType(), ""));
|
||||||
|
data.put("actionConfiguration", ObjectUtils.defaultIfNull(actionDTO.getActionConfiguration(), ""));
|
||||||
|
|
||||||
|
// Handle potential null createdAt for formatting
|
||||||
|
String actionCreated = actionDTO.getCreatedAt() != null
|
||||||
|
? DateUtils.ISO_FORMATTER.format(actionDTO.getCreatedAt())
|
||||||
|
: "";
|
||||||
|
data.put("actionCreated", actionCreated);
|
||||||
|
|
||||||
|
final String appMode = TRUE.equals(application.getViewMode())
|
||||||
|
? ApplicationMode.PUBLISHED.toString()
|
||||||
|
: ApplicationMode.EDIT.toString();
|
||||||
|
|
||||||
|
data.put("workspaceId", ObjectUtils.defaultIfNull(application.getWorkspaceId(), ""));
|
||||||
|
data.put(FieldName.APP_MODE, appMode);
|
||||||
|
data.put("appName", ObjectUtils.defaultIfNull(application.getName(), ""));
|
||||||
|
data.put("isExampleApp", ObjectUtils.defaultIfNull(application.isAppIsExample(), false));
|
||||||
|
|
||||||
|
// Handle datasource info with null checks
|
||||||
|
Map<String, Object> datasourceInfo = new HashMap<>();
|
||||||
|
if (actionDTO.getDatasource() != null) {
|
||||||
|
datasourceInfo.put(
|
||||||
|
"name",
|
||||||
|
ObjectUtils.defaultIfNull(
|
||||||
|
actionDTO.getDatasource().getName(), ""));
|
||||||
|
datasourceInfo.put(
|
||||||
|
"dsIsMock",
|
||||||
|
ObjectUtils.defaultIfNull(
|
||||||
|
actionDTO.getDatasource().getIsMock(), false));
|
||||||
|
datasourceInfo.put(
|
||||||
|
"dsIsTemplate",
|
||||||
|
ObjectUtils.defaultIfNull(
|
||||||
|
actionDTO.getDatasource().getIsTemplate(), false));
|
||||||
|
datasourceInfo.put(
|
||||||
|
"dsId",
|
||||||
|
ObjectUtils.defaultIfNull(
|
||||||
|
actionDTO.getDatasource().getId(), ""));
|
||||||
|
} else {
|
||||||
|
datasourceInfo.put("name", "");
|
||||||
|
datasourceInfo.put("dsIsMock", false);
|
||||||
|
datasourceInfo.put("dsIsTemplate", false);
|
||||||
|
datasourceInfo.put("dsId", "");
|
||||||
|
}
|
||||||
|
data.put("datasource", datasourceInfo);
|
||||||
|
|
||||||
|
data.put("wasChangedBy", ObjectUtils.defaultIfNull(wasChangedBy, ""));
|
||||||
|
data.put("creatorContextType", ObjectUtils.defaultIfNull(creatorType, CreatorContextType.PAGE));
|
||||||
|
data.put("isActionPartOfModuleInstance", isActionPartOfModuleInstance);
|
||||||
|
|
||||||
|
return analyticsService
|
||||||
|
.sendObjectEvent(AnalyticsEvents.ACTION_RUN_BEHAVIOUR_CHANGED, actionDTO, data)
|
||||||
|
.then(); // Return Mono<Void> for fire-and-forget
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -11,14 +11,19 @@ import com.appsmith.external.models.EntityReferenceType;
|
||||||
import com.appsmith.external.models.Executable;
|
import com.appsmith.external.models.Executable;
|
||||||
import com.appsmith.external.models.Property;
|
import com.appsmith.external.models.Property;
|
||||||
import com.appsmith.external.models.RunBehaviourEnum;
|
import com.appsmith.external.models.RunBehaviourEnum;
|
||||||
|
import com.appsmith.server.applications.base.ApplicationService;
|
||||||
import com.appsmith.server.domains.ExecutableDependencyEdge;
|
import com.appsmith.server.domains.ExecutableDependencyEdge;
|
||||||
import com.appsmith.server.domains.Layout;
|
import com.appsmith.server.domains.Layout;
|
||||||
import com.appsmith.server.domains.NewPage;
|
import com.appsmith.server.domains.NewPage;
|
||||||
|
import com.appsmith.server.domains.RunBehaviourAnalyticsMetadata;
|
||||||
|
import com.appsmith.server.enums.RunBehaviourUpdateSource;
|
||||||
import com.appsmith.server.exceptions.AppsmithError;
|
import com.appsmith.server.exceptions.AppsmithError;
|
||||||
import com.appsmith.server.exceptions.AppsmithException;
|
import com.appsmith.server.exceptions.AppsmithException;
|
||||||
import com.appsmith.server.helpers.CollectionUtils;
|
import com.appsmith.server.helpers.CollectionUtils;
|
||||||
import com.appsmith.server.helpers.ObservationHelperImpl;
|
import com.appsmith.server.helpers.ObservationHelperImpl;
|
||||||
|
import com.appsmith.server.helpers.RunBehaviourAnalyticsUtils;
|
||||||
import com.appsmith.server.onload.executables.ExecutableOnLoadService;
|
import com.appsmith.server.onload.executables.ExecutableOnLoadService;
|
||||||
|
import com.appsmith.server.services.AnalyticsService;
|
||||||
import com.appsmith.server.services.AstService;
|
import com.appsmith.server.services.AstService;
|
||||||
import com.appsmith.server.services.FeatureFlagService;
|
import com.appsmith.server.services.FeatureFlagService;
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
|
@ -94,6 +99,9 @@ public class OnLoadExecutablesUtilCEImpl implements OnLoadExecutablesUtilCE {
|
||||||
private final ObservationRegistry observationRegistry;
|
private final ObservationRegistry observationRegistry;
|
||||||
private final ObservationHelperImpl observationHelper;
|
private final ObservationHelperImpl observationHelper;
|
||||||
private final FeatureFlagService featureFlagService;
|
private final FeatureFlagService featureFlagService;
|
||||||
|
private final AnalyticsService analyticsService;
|
||||||
|
private final ApplicationService applicationService;
|
||||||
|
private final RunBehaviourAnalyticsUtils runBehaviourAnalyticsUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function computes the sequenced on page load executables.
|
* This function computes the sequenced on page load executables.
|
||||||
|
|
@ -307,6 +315,7 @@ public class OnLoadExecutablesUtilCEImpl implements OnLoadExecutablesUtilCE {
|
||||||
List<String> messagesRef,
|
List<String> messagesRef,
|
||||||
CreatorContextType creatorType) {
|
CreatorContextType creatorType) {
|
||||||
List<Executable> toUpdateExecutables = new ArrayList<>();
|
List<Executable> toUpdateExecutables = new ArrayList<>();
|
||||||
|
Map<String, RunBehaviourEnum> oldRunBehaviourMap = new HashMap<>();
|
||||||
|
|
||||||
// Fetch all the actions which exist in this page.
|
// Fetch all the actions which exist in this page.
|
||||||
Flux<Executable> creatorContextExecutablesFlux =
|
Flux<Executable> creatorContextExecutablesFlux =
|
||||||
|
|
@ -373,7 +382,6 @@ public class OnLoadExecutablesUtilCEImpl implements OnLoadExecutablesUtilCE {
|
||||||
turnedOnExecutableNames.removeAll(existingOnLoadExecutableNames);
|
turnedOnExecutableNames.removeAll(existingOnLoadExecutableNames);
|
||||||
|
|
||||||
for (Executable executable : creatorContextExecutables) {
|
for (Executable executable : creatorContextExecutables) {
|
||||||
|
|
||||||
String executableName = executable.getUserExecutableName();
|
String executableName = executable.getUserExecutableName();
|
||||||
// If a user has ever set execute on load, this field can not be changed
|
// If a user has ever set execute on load, this field can not be changed
|
||||||
// automatically.
|
// automatically.
|
||||||
|
|
@ -382,6 +390,8 @@ public class OnLoadExecutablesUtilCEImpl implements OnLoadExecutablesUtilCE {
|
||||||
// this
|
// this
|
||||||
// condition is false.
|
// condition is false.
|
||||||
if (FALSE.equals(executable.getUserSetOnLoad())) {
|
if (FALSE.equals(executable.getUserSetOnLoad())) {
|
||||||
|
// Store old run behaviour before updating
|
||||||
|
oldRunBehaviourMap.put(executableName, executable.getRunBehaviour());
|
||||||
|
|
||||||
// If this executable is no longer an onload executable, turn the execute on
|
// If this executable is no longer an onload executable, turn the execute on
|
||||||
// load to
|
// load to
|
||||||
|
|
@ -457,8 +467,36 @@ public class OnLoadExecutablesUtilCEImpl implements OnLoadExecutablesUtilCE {
|
||||||
|
|
||||||
// Finally update the actions which require an update
|
// Finally update the actions which require an update
|
||||||
return Flux.fromIterable(toUpdateExecutables)
|
return Flux.fromIterable(toUpdateExecutables)
|
||||||
.flatMap(executable -> this.updateUnpublishedExecutable(
|
.flatMap(executable -> {
|
||||||
executable.getId(), executable, creatorType))
|
RunBehaviourEnum oldRunBehaviour = oldRunBehaviourMap.getOrDefault(
|
||||||
|
executable.getUserExecutableName(), null);
|
||||||
|
return this.updateUnpublishedExecutable(
|
||||||
|
executable.getId(), executable, creatorType)
|
||||||
|
.flatMap(updatedExecutable -> {
|
||||||
|
if (!(updatedExecutable instanceof ActionDTO actionDTO)) {
|
||||||
|
return Mono.empty();
|
||||||
|
}
|
||||||
|
return runBehaviourAnalyticsUtils
|
||||||
|
.sendRunBehaviourChangedAnalytics(
|
||||||
|
RunBehaviourAnalyticsMetadata.builder()
|
||||||
|
.actionDTO(actionDTO)
|
||||||
|
.oldRunBehaviour(oldRunBehaviour)
|
||||||
|
.creatorContextType(creatorType)
|
||||||
|
.wasChangedBy(
|
||||||
|
RunBehaviourUpdateSource.SYSTEM)
|
||||||
|
.isActionPartOfModuleInstance(
|
||||||
|
!isRegularAction(actionDTO))
|
||||||
|
.build())
|
||||||
|
.onErrorResume(e -> {
|
||||||
|
log.warn(
|
||||||
|
"Analytics publish failed for action {}: {}",
|
||||||
|
actionDTO.getId(),
|
||||||
|
e.getMessage());
|
||||||
|
return Mono.empty();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then();
|
||||||
|
})
|
||||||
.then(Mono.just(TRUE));
|
.then(Mono.just(TRUE));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -470,6 +508,11 @@ public class OnLoadExecutablesUtilCEImpl implements OnLoadExecutablesUtilCE {
|
||||||
return getExecutableOnLoadService(creatorType).findAndUpdateLayout(creatorId, layoutId, layout);
|
return getExecutableOnLoadService(creatorType).findAndUpdateLayout(creatorId, layoutId, layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Regular action here means action created as part of application editor
|
||||||
|
protected boolean isRegularAction(ActionDTO actionDTO) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private Mono<Executable> updateUnpublishedExecutable(
|
private Mono<Executable> updateUnpublishedExecutable(
|
||||||
String id, Executable executable, CreatorContextType contextType) {
|
String id, Executable executable, CreatorContextType contextType) {
|
||||||
if (executable instanceof ActionDTO actionDTO) {
|
if (executable instanceof ActionDTO actionDTO) {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
package com.appsmith.server.onload.internal;
|
package com.appsmith.server.onload.internal;
|
||||||
|
|
||||||
|
import com.appsmith.server.applications.base.ApplicationService;
|
||||||
import com.appsmith.server.domains.NewPage;
|
import com.appsmith.server.domains.NewPage;
|
||||||
import com.appsmith.server.helpers.ObservationHelperImpl;
|
import com.appsmith.server.helpers.ObservationHelperImpl;
|
||||||
|
import com.appsmith.server.helpers.RunBehaviourAnalyticsUtils;
|
||||||
import com.appsmith.server.onload.executables.ExecutableOnLoadService;
|
import com.appsmith.server.onload.executables.ExecutableOnLoadService;
|
||||||
|
import com.appsmith.server.services.AnalyticsService;
|
||||||
import com.appsmith.server.services.AstService;
|
import com.appsmith.server.services.AstService;
|
||||||
import com.appsmith.server.services.FeatureFlagService;
|
import com.appsmith.server.services.FeatureFlagService;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
@ -20,13 +23,19 @@ public class OnLoadExecutablesUtilImpl extends OnLoadExecutablesUtilCEImpl imple
|
||||||
ExecutableOnLoadService<NewPage> pageExecutableOnLoadService,
|
ExecutableOnLoadService<NewPage> pageExecutableOnLoadService,
|
||||||
ObservationRegistry observationRegistry,
|
ObservationRegistry observationRegistry,
|
||||||
ObservationHelperImpl observationHelper,
|
ObservationHelperImpl observationHelper,
|
||||||
FeatureFlagService featureFlagService) {
|
FeatureFlagService featureFlagService,
|
||||||
|
AnalyticsService analyticsService,
|
||||||
|
ApplicationService applicationService,
|
||||||
|
RunBehaviourAnalyticsUtils runBehaviourAnalyticsUtils) {
|
||||||
super(
|
super(
|
||||||
astService,
|
astService,
|
||||||
objectMapper,
|
objectMapper,
|
||||||
pageExecutableOnLoadService,
|
pageExecutableOnLoadService,
|
||||||
observationRegistry,
|
observationRegistry,
|
||||||
observationHelper,
|
observationHelper,
|
||||||
featureFlagService);
|
featureFlagService,
|
||||||
|
analyticsService,
|
||||||
|
applicationService,
|
||||||
|
runBehaviourAnalyticsUtils);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package com.appsmith.server.services;
|
package com.appsmith.server.services;
|
||||||
|
|
||||||
|
import com.appsmith.server.applications.base.ApplicationService;
|
||||||
import com.appsmith.server.datasources.base.DatasourceService;
|
import com.appsmith.server.datasources.base.DatasourceService;
|
||||||
|
import com.appsmith.server.helpers.RunBehaviourAnalyticsUtils;
|
||||||
import com.appsmith.server.layouts.UpdateLayoutService;
|
import com.appsmith.server.layouts.UpdateLayoutService;
|
||||||
import com.appsmith.server.newactions.base.NewActionService;
|
import com.appsmith.server.newactions.base.NewActionService;
|
||||||
import com.appsmith.server.newpages.base.NewPageService;
|
import com.appsmith.server.newpages.base.NewPageService;
|
||||||
|
|
@ -26,7 +28,9 @@ public class LayoutActionServiceImpl extends LayoutActionServiceCEImpl implement
|
||||||
DatasourceService datasourceService,
|
DatasourceService datasourceService,
|
||||||
PagePermission pagePermission,
|
PagePermission pagePermission,
|
||||||
ActionPermission actionPermission,
|
ActionPermission actionPermission,
|
||||||
ObservationRegistry observationRegistry) {
|
ObservationRegistry observationRegistry,
|
||||||
|
ApplicationService applicationService,
|
||||||
|
RunBehaviourAnalyticsUtils runBehaviourAnalyticsUtils) {
|
||||||
|
|
||||||
super(
|
super(
|
||||||
analyticsService,
|
analyticsService,
|
||||||
|
|
@ -38,6 +42,8 @@ public class LayoutActionServiceImpl extends LayoutActionServiceCEImpl implement
|
||||||
datasourceService,
|
datasourceService,
|
||||||
pagePermission,
|
pagePermission,
|
||||||
actionPermission,
|
actionPermission,
|
||||||
observationRegistry);
|
observationRegistry,
|
||||||
|
applicationService,
|
||||||
|
runBehaviourAnalyticsUtils);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,16 +8,20 @@ import com.appsmith.external.models.Datasource;
|
||||||
import com.appsmith.external.models.PluginType;
|
import com.appsmith.external.models.PluginType;
|
||||||
import com.appsmith.external.models.RunBehaviourEnum;
|
import com.appsmith.external.models.RunBehaviourEnum;
|
||||||
import com.appsmith.server.acl.AclPermission;
|
import com.appsmith.server.acl.AclPermission;
|
||||||
|
import com.appsmith.server.applications.base.ApplicationService;
|
||||||
import com.appsmith.server.constants.FieldName;
|
import com.appsmith.server.constants.FieldName;
|
||||||
import com.appsmith.server.datasources.base.DatasourceService;
|
import com.appsmith.server.datasources.base.DatasourceService;
|
||||||
import com.appsmith.server.domains.Layout;
|
import com.appsmith.server.domains.Layout;
|
||||||
import com.appsmith.server.domains.NewAction;
|
import com.appsmith.server.domains.NewAction;
|
||||||
import com.appsmith.server.domains.NewPage;
|
import com.appsmith.server.domains.NewPage;
|
||||||
|
import com.appsmith.server.domains.RunBehaviourAnalyticsMetadata;
|
||||||
import com.appsmith.server.dtos.ActionMoveDTO;
|
import com.appsmith.server.dtos.ActionMoveDTO;
|
||||||
import com.appsmith.server.dtos.CreateActionMetaDTO;
|
import com.appsmith.server.dtos.CreateActionMetaDTO;
|
||||||
import com.appsmith.server.dtos.PageDTO;
|
import com.appsmith.server.dtos.PageDTO;
|
||||||
|
import com.appsmith.server.enums.RunBehaviourUpdateSource;
|
||||||
import com.appsmith.server.exceptions.AppsmithError;
|
import com.appsmith.server.exceptions.AppsmithError;
|
||||||
import com.appsmith.server.exceptions.AppsmithException;
|
import com.appsmith.server.exceptions.AppsmithException;
|
||||||
|
import com.appsmith.server.helpers.RunBehaviourAnalyticsUtils;
|
||||||
import com.appsmith.server.layouts.UpdateLayoutService;
|
import com.appsmith.server.layouts.UpdateLayoutService;
|
||||||
import com.appsmith.server.newactions.base.NewActionService;
|
import com.appsmith.server.newactions.base.NewActionService;
|
||||||
import com.appsmith.server.newpages.base.NewPageService;
|
import com.appsmith.server.newpages.base.NewPageService;
|
||||||
|
|
@ -64,6 +68,8 @@ public class LayoutActionServiceCEImpl implements LayoutActionServiceCE {
|
||||||
private final PagePermission pagePermission;
|
private final PagePermission pagePermission;
|
||||||
private final ActionPermission actionPermission;
|
private final ActionPermission actionPermission;
|
||||||
private final ObservationRegistry observationRegistry;
|
private final ObservationRegistry observationRegistry;
|
||||||
|
private final ApplicationService applicationService;
|
||||||
|
private final RunBehaviourAnalyticsUtils runBehaviourAnalyticsUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by Action controller to create Action
|
* Called by Action controller to create Action
|
||||||
|
|
@ -321,16 +327,31 @@ public class LayoutActionServiceCEImpl implements LayoutActionServiceCE {
|
||||||
.flatMap(newAction -> {
|
.flatMap(newAction -> {
|
||||||
ActionDTO action = newAction.getUnpublishedAction();
|
ActionDTO action = newAction.getUnpublishedAction();
|
||||||
|
|
||||||
|
RunBehaviourEnum oldRunBehaviour = action.getRunBehaviour();
|
||||||
|
|
||||||
action.setUserSetOnLoad(true);
|
action.setUserSetOnLoad(true);
|
||||||
action.setRunBehaviour(behaviour);
|
action.setRunBehaviour(behaviour);
|
||||||
|
|
||||||
newAction.setUnpublishedAction(action);
|
newAction.setUnpublishedAction(action);
|
||||||
|
|
||||||
return newActionService.save(newAction).flatMap(savedAction -> updateLayoutService
|
return newActionService
|
||||||
.updateLayoutByContextTypeAndContextId(action.getContextType(), action.getContextId())
|
.save(newAction)
|
||||||
.name(UPDATE_PAGE_LAYOUT_BY_PAGE_ID)
|
.flatMap(savedAction -> updateLayoutService
|
||||||
.tap(Micrometer.observation(observationRegistry))
|
.updateLayoutByContextTypeAndContextId(
|
||||||
.thenReturn(newActionService.generateActionByViewMode(savedAction, false)));
|
action.getContextType(), action.getContextId())
|
||||||
|
.name(UPDATE_PAGE_LAYOUT_BY_PAGE_ID)
|
||||||
|
.tap(Micrometer.observation(observationRegistry))
|
||||||
|
.thenReturn(newActionService.generateActionByViewMode(savedAction, false)))
|
||||||
|
.flatMap(updatedAction -> runBehaviourAnalyticsUtils
|
||||||
|
.sendRunBehaviourChangedAnalytics(RunBehaviourAnalyticsMetadata.builder()
|
||||||
|
.actionDTO(updatedAction)
|
||||||
|
.oldRunBehaviour(oldRunBehaviour)
|
||||||
|
.creatorContextType(action.getContextType())
|
||||||
|
.wasChangedBy(RunBehaviourUpdateSource.USER)
|
||||||
|
.isActionPartOfModuleInstance(!isRegularAction(updatedAction))
|
||||||
|
.build())
|
||||||
|
.onErrorResume(e -> Mono.empty())
|
||||||
|
.thenReturn(updatedAction));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -447,6 +468,11 @@ public class LayoutActionServiceCEImpl implements LayoutActionServiceCE {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Regular action here means action created as part of application editor
|
||||||
|
protected boolean isRegularAction(ActionDTO actionDTO) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
protected Mono<NewAction> validateAndGenerateActionDomainBasedOnContext(
|
protected Mono<NewAction> validateAndGenerateActionDomainBasedOnContext(
|
||||||
ActionDTO action, CreateActionMetaDTO actionMetaDTO) {
|
ActionDTO action, CreateActionMetaDTO actionMetaDTO) {
|
||||||
Boolean isJsAction = actionMetaDTO.getIsJsAction();
|
Boolean isJsAction = actionMetaDTO.getIsJsAction();
|
||||||
|
|
|
||||||
|
|
@ -1244,6 +1244,7 @@ public class ActionExecutionSolutionCEImpl implements ActionExecutionSolutionCE
|
||||||
}
|
}
|
||||||
data.put(FieldName.ACTION_CONFIGURATION, rawActionConfiguration);
|
data.put(FieldName.ACTION_CONFIGURATION, rawActionConfiguration);
|
||||||
data.put(FieldName.EVENT_DATA, eventData);
|
data.put(FieldName.EVENT_DATA, eventData);
|
||||||
|
data.put(FieldName.ACTION_CONFIGURATION_RUN_BEHAVIOUR, actionDTO.getRunBehaviour());
|
||||||
return analyticsService
|
return analyticsService
|
||||||
.sendObjectEvent(AnalyticsEvents.EXECUTE_ACTION, actionDTO, data)
|
.sendObjectEvent(AnalyticsEvents.EXECUTE_ACTION, actionDTO, data)
|
||||||
.thenReturn(request);
|
.thenReturn(request);
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,11 @@ import com.appsmith.external.models.ActionDTO;
|
||||||
import com.appsmith.external.models.CreatorContextType;
|
import com.appsmith.external.models.CreatorContextType;
|
||||||
import com.appsmith.external.models.Executable;
|
import com.appsmith.external.models.Executable;
|
||||||
import com.appsmith.external.models.RunBehaviourEnum;
|
import com.appsmith.external.models.RunBehaviourEnum;
|
||||||
|
import com.appsmith.server.applications.base.ApplicationService;
|
||||||
import com.appsmith.server.helpers.ObservationHelperImpl;
|
import com.appsmith.server.helpers.ObservationHelperImpl;
|
||||||
|
import com.appsmith.server.helpers.RunBehaviourAnalyticsUtils;
|
||||||
import com.appsmith.server.onload.executables.ExecutableOnLoadService;
|
import com.appsmith.server.onload.executables.ExecutableOnLoadService;
|
||||||
|
import com.appsmith.server.services.AnalyticsService;
|
||||||
import com.appsmith.server.services.AstService;
|
import com.appsmith.server.services.AstService;
|
||||||
import com.appsmith.server.services.FeatureFlagService;
|
import com.appsmith.server.services.FeatureFlagService;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
@ -30,6 +33,7 @@ import static java.lang.Boolean.TRUE;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.anyString;
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
|
import static org.mockito.Mockito.doAnswer;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
@ -58,23 +62,27 @@ public class OnLoadExecutablesUtilCEImplTest {
|
||||||
|
|
||||||
private OnLoadExecutablesUtilCEImpl onLoadExecutablesUtilCE;
|
private OnLoadExecutablesUtilCEImpl onLoadExecutablesUtilCE;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private AnalyticsService analyticsService;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private ApplicationService applicationService;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private RunBehaviourAnalyticsUtils runBehaviourAnalyticsUtils;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
onLoadExecutablesUtilCE = new OnLoadExecutablesUtilCEImpl(
|
|
||||||
astService,
|
|
||||||
objectMapper,
|
|
||||||
executableOnLoadService,
|
|
||||||
observationRegistry,
|
|
||||||
observationHelper,
|
|
||||||
featureFlagService);
|
|
||||||
|
|
||||||
onLoadExecutablesUtilCE = spy(new OnLoadExecutablesUtilCEImpl(
|
onLoadExecutablesUtilCE = spy(new OnLoadExecutablesUtilCEImpl(
|
||||||
astService,
|
astService,
|
||||||
objectMapper,
|
objectMapper,
|
||||||
executableOnLoadService,
|
executableOnLoadService,
|
||||||
observationRegistry,
|
observationRegistry,
|
||||||
observationHelper,
|
observationHelper,
|
||||||
featureFlagService));
|
featureFlagService,
|
||||||
|
analyticsService,
|
||||||
|
applicationService,
|
||||||
|
runBehaviourAnalyticsUtils));
|
||||||
|
|
||||||
ObservationRegistry.ObservationConfig mockObservationConfig =
|
ObservationRegistry.ObservationConfig mockObservationConfig =
|
||||||
Mockito.mock(ObservationRegistry.ObservationConfig.class);
|
Mockito.mock(ObservationRegistry.ObservationConfig.class);
|
||||||
|
|
@ -107,6 +115,9 @@ public class OnLoadExecutablesUtilCEImplTest {
|
||||||
when(executableOnLoadService.updateUnpublishedExecutable(anyString(), any(ActionDTO.class)))
|
when(executableOnLoadService.updateUnpublishedExecutable(anyString(), any(ActionDTO.class)))
|
||||||
.thenAnswer(invocation -> Mono.just(invocation.getArgument(1)));
|
.thenAnswer(invocation -> Mono.just(invocation.getArgument(1)));
|
||||||
|
|
||||||
|
// mock runBehaviourAnalyticsUtils to return mono of void
|
||||||
|
doAnswer(invocation -> Mono.empty()).when(runBehaviourAnalyticsUtils).sendRunBehaviourChangedAnalytics(any());
|
||||||
|
|
||||||
// Execute
|
// Execute
|
||||||
Mono<Boolean> result = onLoadExecutablesUtilCE.updateExecutablesRunBehaviour(
|
Mono<Boolean> result = onLoadExecutablesUtilCE.updateExecutablesRunBehaviour(
|
||||||
onLoadExecutables, creatorId, executableUpdatesRef, messagesRef, creatorType);
|
onLoadExecutables, creatorId, executableUpdatesRef, messagesRef, creatorType);
|
||||||
|
|
@ -147,6 +158,9 @@ public class OnLoadExecutablesUtilCEImplTest {
|
||||||
when(executableOnLoadService.updateUnpublishedExecutable(anyString(), any(ActionDTO.class)))
|
when(executableOnLoadService.updateUnpublishedExecutable(anyString(), any(ActionDTO.class)))
|
||||||
.thenAnswer(invocation -> Mono.just(invocation.getArgument(1)));
|
.thenAnswer(invocation -> Mono.just(invocation.getArgument(1)));
|
||||||
|
|
||||||
|
// mock runBehaviourAnalyticsUtils to return mono of void
|
||||||
|
doAnswer(invocation -> Mono.empty()).when(runBehaviourAnalyticsUtils).sendRunBehaviourChangedAnalytics(any());
|
||||||
|
|
||||||
// Execute
|
// Execute
|
||||||
Mono<Boolean> result = onLoadExecutablesUtilCE.updateExecutablesRunBehaviour(
|
Mono<Boolean> result = onLoadExecutablesUtilCE.updateExecutablesRunBehaviour(
|
||||||
onLoadExecutables, creatorId, executableUpdatesRef, messagesRef, creatorType);
|
onLoadExecutables, creatorId, executableUpdatesRef, messagesRef, creatorType);
|
||||||
|
|
@ -190,6 +204,9 @@ public class OnLoadExecutablesUtilCEImplTest {
|
||||||
when(executableOnLoadService.updateUnpublishedExecutable(anyString(), any(ActionDTO.class)))
|
when(executableOnLoadService.updateUnpublishedExecutable(anyString(), any(ActionDTO.class)))
|
||||||
.thenAnswer(invocation -> Mono.just(invocation.getArgument(1)));
|
.thenAnswer(invocation -> Mono.just(invocation.getArgument(1)));
|
||||||
|
|
||||||
|
// mock runBehaviourAnalyticsUtils to return mono of void
|
||||||
|
doAnswer(invocation -> Mono.empty()).when(runBehaviourAnalyticsUtils).sendRunBehaviourChangedAnalytics(any());
|
||||||
|
|
||||||
// Execute
|
// Execute
|
||||||
Mono<Boolean> result = onLoadExecutablesUtilCE.updateExecutablesRunBehaviour(
|
Mono<Boolean> result = onLoadExecutablesUtilCE.updateExecutablesRunBehaviour(
|
||||||
onLoadExecutables, creatorId, executableUpdatesRef, messagesRef, creatorType);
|
onLoadExecutables, creatorId, executableUpdatesRef, messagesRef, creatorType);
|
||||||
|
|
@ -260,6 +277,9 @@ public class OnLoadExecutablesUtilCEImplTest {
|
||||||
when(executableOnLoadService.updateUnpublishedExecutable(eq("1"), any()))
|
when(executableOnLoadService.updateUnpublishedExecutable(eq("1"), any()))
|
||||||
.thenReturn(Mono.just(updatedAction));
|
.thenReturn(Mono.just(updatedAction));
|
||||||
|
|
||||||
|
// mock runBehaviourAnalyticsUtils to return mono of void
|
||||||
|
doAnswer(invocation -> Mono.empty()).when(runBehaviourAnalyticsUtils).sendRunBehaviourChangedAnalytics(any());
|
||||||
|
|
||||||
// Execute and verify
|
// Execute and verify
|
||||||
StepVerifier.create(onLoadExecutablesUtilCE.updateExecutablesRunBehaviour(
|
StepVerifier.create(onLoadExecutablesUtilCE.updateExecutablesRunBehaviour(
|
||||||
onLoadExecutables, "creatorId", executableUpdates, messages, CreatorContextType.PAGE))
|
onLoadExecutables, "creatorId", executableUpdates, messages, CreatorContextType.PAGE))
|
||||||
|
|
@ -296,6 +316,9 @@ public class OnLoadExecutablesUtilCEImplTest {
|
||||||
when(executableOnLoadService.updateUnpublishedExecutable(eq("1"), any()))
|
when(executableOnLoadService.updateUnpublishedExecutable(eq("1"), any()))
|
||||||
.thenReturn(Mono.just(updatedAction));
|
.thenReturn(Mono.just(updatedAction));
|
||||||
|
|
||||||
|
// mock runBehaviourAnalyticsUtils to return mono of void
|
||||||
|
doAnswer(invocation -> Mono.empty()).when(runBehaviourAnalyticsUtils).sendRunBehaviourChangedAnalytics(any());
|
||||||
|
|
||||||
// Execute and verify
|
// Execute and verify
|
||||||
StepVerifier.create(onLoadExecutablesUtilCE.updateExecutablesRunBehaviour(
|
StepVerifier.create(onLoadExecutablesUtilCE.updateExecutablesRunBehaviour(
|
||||||
onLoadExecutables, "creatorId", executableUpdates, messages, CreatorContextType.PAGE))
|
onLoadExecutables, "creatorId", executableUpdates, messages, CreatorContextType.PAGE))
|
||||||
|
|
@ -332,6 +355,9 @@ public class OnLoadExecutablesUtilCEImplTest {
|
||||||
when(executableOnLoadService.updateUnpublishedExecutable(eq("1"), any()))
|
when(executableOnLoadService.updateUnpublishedExecutable(eq("1"), any()))
|
||||||
.thenReturn(Mono.just(updatedAction));
|
.thenReturn(Mono.just(updatedAction));
|
||||||
|
|
||||||
|
// mock runBehaviourAnalyticsUtils to return mono of void
|
||||||
|
doAnswer(invocation -> Mono.empty()).when(runBehaviourAnalyticsUtils).sendRunBehaviourChangedAnalytics(any());
|
||||||
|
|
||||||
// Execute and verify
|
// Execute and verify
|
||||||
StepVerifier.create(onLoadExecutablesUtilCE.updateExecutablesRunBehaviour(
|
StepVerifier.create(onLoadExecutablesUtilCE.updateExecutablesRunBehaviour(
|
||||||
onLoadExecutables, "creatorId", executableUpdates, messages, CreatorContextType.PAGE))
|
onLoadExecutables, "creatorId", executableUpdates, messages, CreatorContextType.PAGE))
|
||||||
|
|
@ -384,6 +410,9 @@ public class OnLoadExecutablesUtilCEImplTest {
|
||||||
when(executableOnLoadService.updateUnpublishedExecutable(eq("2"), any()))
|
when(executableOnLoadService.updateUnpublishedExecutable(eq("2"), any()))
|
||||||
.thenReturn(Mono.just(updatedAction2));
|
.thenReturn(Mono.just(updatedAction2));
|
||||||
|
|
||||||
|
// mock runBehaviourAnalyticsUtils to return mono of void
|
||||||
|
doAnswer(invocation -> Mono.empty()).when(runBehaviourAnalyticsUtils).sendRunBehaviourChangedAnalytics(any());
|
||||||
|
|
||||||
// Execute and verify
|
// Execute and verify
|
||||||
StepVerifier.create(onLoadExecutablesUtilCE.updateExecutablesRunBehaviour(
|
StepVerifier.create(onLoadExecutablesUtilCE.updateExecutablesRunBehaviour(
|
||||||
onLoadExecutables, "creatorId", executableUpdates, messages, CreatorContextType.PAGE))
|
onLoadExecutables, "creatorId", executableUpdates, messages, CreatorContextType.PAGE))
|
||||||
|
|
@ -439,6 +468,9 @@ public class OnLoadExecutablesUtilCEImplTest {
|
||||||
when(executableOnLoadService.updateUnpublishedExecutable(eq("2"), any()))
|
when(executableOnLoadService.updateUnpublishedExecutable(eq("2"), any()))
|
||||||
.thenReturn(Mono.just(updatedAction2));
|
.thenReturn(Mono.just(updatedAction2));
|
||||||
|
|
||||||
|
// mock runBehaviourAnalyticsUtils to return mono of void
|
||||||
|
doAnswer(invocation -> Mono.empty()).when(runBehaviourAnalyticsUtils).sendRunBehaviourChangedAnalytics(any());
|
||||||
|
|
||||||
// Execute and verify
|
// Execute and verify
|
||||||
StepVerifier.create(onLoadExecutablesUtilCE.updateExecutablesRunBehaviour(
|
StepVerifier.create(onLoadExecutablesUtilCE.updateExecutablesRunBehaviour(
|
||||||
onLoadExecutables, "creatorId", executableUpdates, messages, CreatorContextType.PAGE))
|
onLoadExecutables, "creatorId", executableUpdates, messages, CreatorContextType.PAGE))
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user