Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public enum AnalyticsEvents {
PAGE_REORDER,
GENERATE_CRUD_PAGE("generate_CRUD_PAGE"),
CREATE_SUPERUSER,
ACTION_RUN_BEHAVIOUR_CHANGED("action_RUN_BEHAVIOUR_CHANGED"),
SUBSCRIBE_MARKETING_EMAILS,
UNSUBSCRIBE_MARKETING_EMAILS,
INSTALLATION_SETUP_COMPLETE("Installation Setup Complete"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,4 +209,6 @@ public class FieldNameCE {
public static final String NONE = "none";
public static final String ORGANIZATION_ADMINISTRATOR_ROLE = "Organization Administrator Role";
public static final String INSTANCE_VARIABLES = "instanceVariables";

public static final String ACTION_CONFIGURATION_RUN_BEHAVIOUR = "runBehaviour";
}
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.appsmith.server.enums;

public enum RunBehaviourUpdateSource {
SYSTEM,
USER
}
Original file line number Diff line number Diff line change
@@ -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())
Comment thread
sneha122 marked this conversation as resolved.
.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())
: "";
Comment thread
sneha122 marked this conversation as resolved.
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
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,19 @@
import com.appsmith.external.models.Executable;
import com.appsmith.external.models.Property;
import com.appsmith.external.models.RunBehaviourEnum;
import com.appsmith.server.applications.base.ApplicationService;
import com.appsmith.server.domains.ExecutableDependencyEdge;
import com.appsmith.server.domains.Layout;
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.AppsmithException;
import com.appsmith.server.helpers.CollectionUtils;
import com.appsmith.server.helpers.ObservationHelperImpl;
import com.appsmith.server.helpers.RunBehaviourAnalyticsUtils;
import com.appsmith.server.onload.executables.ExecutableOnLoadService;
import com.appsmith.server.services.AnalyticsService;
import com.appsmith.server.services.AstService;
import com.appsmith.server.services.FeatureFlagService;
import com.fasterxml.jackson.core.type.TypeReference;
Expand Down Expand Up @@ -94,6 +99,9 @@ public class OnLoadExecutablesUtilCEImpl implements OnLoadExecutablesUtilCE {
private final ObservationRegistry observationRegistry;
private final ObservationHelperImpl observationHelper;
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.
Expand Down Expand Up @@ -307,6 +315,7 @@ public Mono<Boolean> updateExecutablesRunBehaviour(
List<String> messagesRef,
CreatorContextType creatorType) {
List<Executable> toUpdateExecutables = new ArrayList<>();
Map<String, RunBehaviourEnum> oldRunBehaviourMap = new HashMap<>();

// Fetch all the actions which exist in this page.
Flux<Executable> creatorContextExecutablesFlux =
Expand Down Expand Up @@ -373,7 +382,6 @@ public Mono<Boolean> updateExecutablesRunBehaviour(
turnedOnExecutableNames.removeAll(existingOnLoadExecutableNames);

for (Executable executable : creatorContextExecutables) {

String executableName = executable.getUserExecutableName();
// If a user has ever set execute on load, this field can not be changed
// automatically.
Expand All @@ -382,6 +390,8 @@ public Mono<Boolean> updateExecutablesRunBehaviour(
// this
// condition is false.
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
// load to
Expand Down Expand Up @@ -457,8 +467,36 @@ public Mono<Boolean> updateExecutablesRunBehaviour(

// Finally update the actions which require an update
return Flux.fromIterable(toUpdateExecutables)
.flatMap(executable -> this.updateUnpublishedExecutable(
executable.getId(), executable, creatorType))
.flatMap(executable -> {
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));
});
});
Expand All @@ -470,6 +508,11 @@ public Mono<Layout> findAndUpdateLayout(
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(
String id, Executable executable, CreatorContextType contextType) {
if (executable instanceof ActionDTO actionDTO) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package com.appsmith.server.onload.internal;

import com.appsmith.server.applications.base.ApplicationService;
import com.appsmith.server.domains.NewPage;
import com.appsmith.server.helpers.ObservationHelperImpl;
import com.appsmith.server.helpers.RunBehaviourAnalyticsUtils;
import com.appsmith.server.onload.executables.ExecutableOnLoadService;
import com.appsmith.server.services.AnalyticsService;
import com.appsmith.server.services.AstService;
import com.appsmith.server.services.FeatureFlagService;
import com.fasterxml.jackson.databind.ObjectMapper;
Expand All @@ -20,13 +23,19 @@ public OnLoadExecutablesUtilImpl(
ExecutableOnLoadService<NewPage> pageExecutableOnLoadService,
ObservationRegistry observationRegistry,
ObservationHelperImpl observationHelper,
FeatureFlagService featureFlagService) {
FeatureFlagService featureFlagService,
AnalyticsService analyticsService,
ApplicationService applicationService,
RunBehaviourAnalyticsUtils runBehaviourAnalyticsUtils) {
super(
astService,
objectMapper,
pageExecutableOnLoadService,
observationRegistry,
observationHelper,
featureFlagService);
featureFlagService,
analyticsService,
applicationService,
runBehaviourAnalyticsUtils);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.appsmith.server.services;

import com.appsmith.server.applications.base.ApplicationService;
import com.appsmith.server.datasources.base.DatasourceService;
import com.appsmith.server.helpers.RunBehaviourAnalyticsUtils;
import com.appsmith.server.layouts.UpdateLayoutService;
import com.appsmith.server.newactions.base.NewActionService;
import com.appsmith.server.newpages.base.NewPageService;
Expand All @@ -26,7 +28,9 @@ public LayoutActionServiceImpl(
DatasourceService datasourceService,
PagePermission pagePermission,
ActionPermission actionPermission,
ObservationRegistry observationRegistry) {
ObservationRegistry observationRegistry,
ApplicationService applicationService,
RunBehaviourAnalyticsUtils runBehaviourAnalyticsUtils) {

super(
analyticsService,
Expand All @@ -38,6 +42,8 @@ public LayoutActionServiceImpl(
datasourceService,
pagePermission,
actionPermission,
observationRegistry);
observationRegistry,
applicationService,
runBehaviourAnalyticsUtils);
}
}
Loading
Loading