diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/enums/FeatureFlagEnum.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/enums/FeatureFlagEnum.java index e3e96745784a..9849422cd531 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/enums/FeatureFlagEnum.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/enums/FeatureFlagEnum.java @@ -14,6 +14,7 @@ public enum FeatureFlagEnum { APP_NAVIGATION_LOGO_UPLOAD, release_embed_hide_share_settings_enabled, rollout_datasource_test_rate_limit_enabled, + release_google_sheets_shared_drive_support_enabled, // Deprecated CE flags over here release_git_autocommit_feature_enabled, diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/plugins/PluginExecutor.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/plugins/PluginExecutor.java index d912594f4a5a..a95a7c2988ac 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/plugins/PluginExecutor.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/plugins/PluginExecutor.java @@ -247,6 +247,50 @@ default Mono executeParameterizedWithMetrics( .tap(Micrometer.observation(observationRegistry)); } + // TODO: Following methods of executeParameterizedWithFlags, executeParameterizedWithMetricsAndFlags, + // triggerWithFlags are + // added + // to support feature flags in the plugin modules. Current implementation of featureFlagService is only available in + // server module + // and not available in any of the plugin modules due to dependencies on SessionUserService, TenantService etc. + // Hence, these methods are added to support feature flags in the plugin modules. + // Ideal solution would be to move featureFlagService and its dependencies to the shared interface module + // But this is a bigger change and will be done in future. Current change of passing flags was done to resolve + // release blocker + // https://github.com/appsmithorg/appsmith/issues/37714 + // Once thorogh testing of shared drive support is done, we can remove this tech debt of passing feature flags like + // this. + default Mono executeParameterizedWithFlags( + C connection, + ExecuteActionDTO executeActionDTO, + DatasourceConfiguration datasourceConfiguration, + ActionConfiguration actionConfiguration, + Map featureFlagMap) { + return this.executeParameterized(connection, executeActionDTO, datasourceConfiguration, actionConfiguration); + } + + default Mono executeParameterizedWithMetricsAndFlags( + C connection, + ExecuteActionDTO executeActionDTO, + DatasourceConfiguration datasourceConfiguration, + ActionConfiguration actionConfiguration, + ObservationRegistry observationRegistry, + Map featureFlagMap) { + return this.executeParameterizedWithFlags( + connection, executeActionDTO, datasourceConfiguration, actionConfiguration, featureFlagMap) + .tag("plugin", this.getClass().getName()) + .name(ACTION_EXECUTION_PLUGIN_EXECUTION) + .tap(Micrometer.observation(observationRegistry)); + } + + default Mono triggerWithFlags( + C connection, + DatasourceConfiguration datasourceConfiguration, + TriggerRequestDTO request, + Map featureFlagMap) { + return this.trigger(connection, datasourceConfiguration, request); + } + /** * This function is responsible for preparing the action and datasource configurations to be ready for execution. * diff --git a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/ExecutionMethod.java b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/ExecutionMethod.java index ae6bef0a7c94..552f61f9323d 100644 --- a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/ExecutionMethod.java +++ b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/ExecutionMethod.java @@ -77,7 +77,9 @@ default Mono executePrerequisites(MethodConfig methodConfig, OAuth2 oaut return Mono.just(true); } - WebClient.RequestHeadersSpec getExecutionClient(WebClient webClient, MethodConfig methodConfig); + default WebClient.RequestHeadersSpec getExecutionClient(WebClient webClient, MethodConfig methodConfig) { + return null; + } default JsonNode transformExecutionResponse( JsonNode response, MethodConfig methodConfig, Set userAuthorizedSheetIds) { @@ -102,4 +104,9 @@ default Map getDataTypeConversionMap() { conversionMap.put(DataType.FLOAT, DataType.DOUBLE); return conversionMap; } + + default WebClient.RequestHeadersSpec getExecutionClientWithFlags( + WebClient webClient, MethodConfig methodConfig, Map featureFlagMap) { + return getExecutionClient(webClient, methodConfig); + } } diff --git a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/FileListMethod.java b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/FileListMethod.java index 2d6b3aea8e17..4e092ee38022 100644 --- a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/FileListMethod.java +++ b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/FileListMethod.java @@ -1,5 +1,6 @@ package com.external.config; +import com.appsmith.external.enums.FeatureFlagEnum; import com.appsmith.external.exceptions.pluginExceptions.AppsmithPluginException; import com.external.constants.ErrorMessages; import com.external.enums.GoogleSheetMethodEnum; @@ -24,8 +25,9 @@ * API reference: https://developers.google.com/sheets/api/guides/migration#list_spreadsheets_for_the_authenticated_user */ public class FileListMethod implements ExecutionMethod, TriggerMethod { - ObjectMapper objectMapper; + private final String SHARED_DRIVE_PARAMS = + "&includeItemsFromAllDrives=true&supportsAllDrives=true&corpora=allDrives"; public FileListMethod(ObjectMapper objectMapper) { this.objectMapper = objectMapper; @@ -37,10 +39,16 @@ public boolean validateExecutionMethodRequest(MethodConfig methodConfig) { } @Override - public WebClient.RequestHeadersSpec getExecutionClient(WebClient webClient, MethodConfig methodConfig) { + public WebClient.RequestHeadersSpec getExecutionClientWithFlags( + WebClient webClient, MethodConfig methodConfig, Map featureFlagMap) { + // TODO: Flags are needed here for google sheets integration to support shared drive behind a flag + // Once thoroughly tested, this flag can be removed + Boolean isSharedDriveSupportEnabled = featureFlagMap.getOrDefault( + FeatureFlagEnum.release_google_sheets_shared_drive_support_enabled.name(), Boolean.FALSE); UriComponentsBuilder uriBuilder = getBaseUriBuilder( this.BASE_DRIVE_API_URL, - "?includeItemsFromAllDrives=true&supportsAllDrives=true&orderBy=name&q=mimeType%3D'application%2Fvnd.google-apps.spreadsheet'%20and%20trashed%3Dfalse", + "?orderBy=name&q=mimeType%3D'application%2Fvnd.google-apps.spreadsheet'%20and%20trashed%3Dfalse" + + (isSharedDriveSupportEnabled.equals(Boolean.TRUE) ? SHARED_DRIVE_PARAMS : ""), true); return webClient @@ -74,8 +82,9 @@ public boolean validateTriggerMethodRequest(MethodConfig methodConfig) { } @Override - public WebClient.RequestHeadersSpec getTriggerClient(WebClient webClient, MethodConfig methodConfig) { - return this.getExecutionClient(webClient, methodConfig); + public WebClient.RequestHeadersSpec getTriggerClientWithFlags( + WebClient webClient, MethodConfig methodConfig, Map featureFlagMap) { + return this.getExecutionClientWithFlags(webClient, methodConfig, featureFlagMap); } @Override diff --git a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/TriggerMethod.java b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/TriggerMethod.java index 3528aea5db6b..0a385e64e770 100644 --- a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/TriggerMethod.java +++ b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/config/TriggerMethod.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.databind.JsonNode; import org.springframework.web.reactive.function.client.WebClient; +import java.util.Map; import java.util.Set; /** @@ -21,7 +22,17 @@ public interface TriggerMethod { /** * Returns with the specification required to hit that particular trigger request */ - WebClient.RequestHeadersSpec getTriggerClient(WebClient webClient, MethodConfig methodConfig); + default WebClient.RequestHeadersSpec getTriggerClient(WebClient webClient, MethodConfig methodConfig) { + return null; + } + + /** + * Returns with the specification required to hit that particular trigger request + */ + default WebClient.RequestHeadersSpec getTriggerClientWithFlags( + WebClient webClient, MethodConfig methodConfig, Map featureFlagMap) { + return getTriggerClient(webClient, methodConfig); + } /** * Transforms the response from the end point into an Appsmith friendly structure diff --git a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/plugins/GoogleSheetsPlugin.java b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/plugins/GoogleSheetsPlugin.java index f336d54b8fc2..f006c050dd36 100644 --- a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/plugins/GoogleSheetsPlugin.java +++ b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/java/com/external/plugins/GoogleSheetsPlugin.java @@ -81,6 +81,23 @@ public Mono executeParameterized( ExecuteActionDTO executeActionDTO, DatasourceConfiguration datasourceConfiguration, ActionConfiguration actionConfiguration) { + return executeParameterizedWithFlags( + connection, executeActionDTO, datasourceConfiguration, actionConfiguration, null); + } + + @Override + public Mono trigger( + Void connection, DatasourceConfiguration datasourceConfiguration, TriggerRequestDTO request) { + return triggerWithFlags(connection, datasourceConfiguration, request, null); + } + + @Override + public Mono executeParameterizedWithFlags( + Void connection, + ExecuteActionDTO executeActionDTO, + DatasourceConfiguration datasourceConfiguration, + ActionConfiguration actionConfiguration, + Map featureFlagMap) { log.debug(Thread.currentThread().getName() + ": executeParameterized() called for GoogleSheets plugin."); boolean smartJsonSubstitution; @@ -133,13 +150,14 @@ public Mono executeParameterized( prepareConfigurationsForExecution(executeActionDTO, actionConfiguration, datasourceConfiguration); - return this.executeCommon(connection, datasourceConfiguration, actionConfiguration); + return this.executeCommon(connection, datasourceConfiguration, actionConfiguration, featureFlagMap); } public Mono executeCommon( Void connection, DatasourceConfiguration datasourceConfiguration, - ActionConfiguration actionConfiguration) { + ActionConfiguration actionConfiguration, + Map featureFlagMap) { log.debug(Thread.currentThread().getName() + ": executeCommon() called for GoogleSheets plugin."); // Initializing object for error condition @@ -185,7 +203,7 @@ public Mono executeCommon( // method .flatMap(res -> { return executionMethod - .getExecutionClient(client, methodConfig) + .getExecutionClientWithFlags(client, methodConfig, featureFlagMap) .headers(headers -> headers.set( "Authorization", "Bearer " @@ -319,8 +337,11 @@ public Object substituteValueInInput( } @Override - public Mono trigger( - Void connection, DatasourceConfiguration datasourceConfiguration, TriggerRequestDTO request) { + public Mono triggerWithFlags( + Void connection, + DatasourceConfiguration datasourceConfiguration, + TriggerRequestDTO request, + Map featureFlagMap) { log.debug(Thread.currentThread().getName() + ": trigger() called for GoogleSheets plugin."); final TriggerMethod triggerMethod = GoogleSheetsMethodStrategy.getTriggerMethod(request, objectMapper); MethodConfig methodConfig = new MethodConfig(request); @@ -343,7 +364,7 @@ public Mono trigger( validateAndGetUserAuthorizedSheetIds(datasourceConfiguration, methodConfig); return triggerMethod - .getTriggerClient(client, methodConfig) + .getTriggerClientWithFlags(client, methodConfig, featureFlagMap) .headers(headers -> headers.set( "Authorization", "Bearer " + oauth2.getAuthenticationResponse().getToken())) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/solutions/PluginTriggerSolutionCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/solutions/PluginTriggerSolutionCEImpl.java index ace596c38c93..a983e279d1eb 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/solutions/PluginTriggerSolutionCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/solutions/PluginTriggerSolutionCEImpl.java @@ -9,6 +9,7 @@ import com.appsmith.server.helpers.PluginExecutorHelper; import com.appsmith.server.repositories.PluginRepository; import com.appsmith.server.services.ConfigService; +import com.appsmith.server.services.FeatureFlagService; import com.appsmith.server.services.TenantService; import com.appsmith.server.solutions.DatasourceTriggerSolution; import org.apache.commons.lang3.StringUtils; @@ -28,18 +29,21 @@ public class PluginTriggerSolutionCEImpl implements PluginTriggerSolutionCE { private final PluginRepository pluginRepository; private final ConfigService configService; private final TenantService tenantService; + private final FeatureFlagService featureFlagService; public PluginTriggerSolutionCEImpl( DatasourceTriggerSolution datasourceTriggerSolution, PluginExecutorHelper pluginExecutorHelper, PluginRepository pluginRepository, ConfigService configService, - TenantService tenantService) { + TenantService tenantService, + FeatureFlagService featureFlagService) { this.datasourceTriggerSolution = datasourceTriggerSolution; this.pluginExecutorHelper = pluginExecutorHelper; this.pluginRepository = pluginRepository; this.configService = configService; this.tenantService = tenantService; + this.featureFlagService = featureFlagService; } /** @@ -74,6 +78,11 @@ public Mono trigger( Mono pluginExecutorMono = pluginMono.flatMap(plugin -> pluginExecutorHelper.getPluginExecutor(Mono.just(plugin))); + // TODO: Flags are needed here for google sheets integration to support shared drive behind a flag + // Once thoroughly tested, this flag can be removed + Map featureFlagMap = + featureFlagService.getCachedTenantFeatureFlags().getFeatures(); + /* * Since there is no datasource provided, we are passing the Datasource Context connection and datasourceConfiguration as null. * We will leave the execution to respective plugin executor. @@ -83,8 +92,8 @@ public Mono trigger( PluginExecutor pluginExecutor = pair.getT2(); setHeadersToTriggerRequest(plugin, httpHeaders, triggerRequestDTO); return setTenantAndInstanceId(triggerRequestDTO) - .flatMap(updatedTriggerRequestDTO -> - ((PluginExecutor) pluginExecutor).trigger(null, null, updatedTriggerRequestDTO)); + .flatMap(updatedTriggerRequestDTO -> ((PluginExecutor) pluginExecutor) + .triggerWithFlags(null, null, updatedTriggerRequestDTO, featureFlagMap)); }); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/solutions/PluginTriggerSolutionImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/solutions/PluginTriggerSolutionImpl.java index f40ff60094d9..373235b5e09d 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/solutions/PluginTriggerSolutionImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/solutions/PluginTriggerSolutionImpl.java @@ -3,6 +3,7 @@ import com.appsmith.server.helpers.PluginExecutorHelper; import com.appsmith.server.repositories.PluginRepository; import com.appsmith.server.services.ConfigService; +import com.appsmith.server.services.FeatureFlagService; import com.appsmith.server.services.TenantService; import com.appsmith.server.solutions.DatasourceTriggerSolution; import org.springframework.stereotype.Component; @@ -14,7 +15,14 @@ public PluginTriggerSolutionImpl( PluginExecutorHelper pluginExecutorHelper, PluginRepository pluginRepository, ConfigService configService, - TenantService tenantService) { - super(datasourceTriggerSolution, pluginExecutorHelper, pluginRepository, configService, tenantService); + TenantService tenantService, + FeatureFlagService featureFlagService) { + super( + datasourceTriggerSolution, + pluginExecutorHelper, + pluginRepository, + configService, + tenantService, + featureFlagService); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ActionExecutionSolutionImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ActionExecutionSolutionImpl.java index 1412bd1b6e70..6f3413f55d94 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ActionExecutionSolutionImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ActionExecutionSolutionImpl.java @@ -13,6 +13,7 @@ import com.appsmith.server.services.AuthenticationValidator; import com.appsmith.server.services.ConfigService; import com.appsmith.server.services.DatasourceContextService; +import com.appsmith.server.services.FeatureFlagService; import com.appsmith.server.services.SessionUserService; import com.appsmith.server.services.TenantService; import com.appsmith.server.solutions.ce.ActionExecutionSolutionCEImpl; @@ -42,7 +43,8 @@ public ActionExecutionSolutionImpl( ConfigService configService, TenantService tenantService, CommonConfig commonConfig, - ActionExecutionSolutionHelper actionExecutionSolutionHelper) { + ActionExecutionSolutionHelper actionExecutionSolutionHelper, + FeatureFlagService featureFlagService) { super( newActionService, actionPermission, @@ -63,6 +65,7 @@ public ActionExecutionSolutionImpl( configService, tenantService, commonConfig, - actionExecutionSolutionHelper); + actionExecutionSolutionHelper, + featureFlagService); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/DatasourceTriggerSolutionImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/DatasourceTriggerSolutionImpl.java index 3993270da9db..a892502e7ffb 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/DatasourceTriggerSolutionImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/DatasourceTriggerSolutionImpl.java @@ -7,6 +7,7 @@ import com.appsmith.server.services.AuthenticationValidator; import com.appsmith.server.services.ConfigService; import com.appsmith.server.services.DatasourceContextService; +import com.appsmith.server.services.FeatureFlagService; import com.appsmith.server.services.TenantService; import com.appsmith.server.solutions.ce.DatasourceTriggerSolutionCEImpl; import lombok.extern.slf4j.Slf4j; @@ -28,7 +29,8 @@ public DatasourceTriggerSolutionImpl( DatasourcePermission datasourcePermission, EnvironmentPermission environmentPermission, ConfigService configService, - TenantService tenantService) { + TenantService tenantService, + FeatureFlagService featureFlagService) { super( datasourceService, datasourceStorageService, @@ -40,6 +42,7 @@ public DatasourceTriggerSolutionImpl( datasourcePermission, environmentPermission, configService, - tenantService); + tenantService, + featureFlagService); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImpl.java index 794d24af0b98..3ced1a0a3978 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImpl.java @@ -45,6 +45,7 @@ import com.appsmith.server.services.AuthenticationValidator; import com.appsmith.server.services.ConfigService; import com.appsmith.server.services.DatasourceContextService; +import com.appsmith.server.services.FeatureFlagService; import com.appsmith.server.services.SessionUserService; import com.appsmith.server.services.TenantService; import com.appsmith.server.solutions.ActionPermission; @@ -73,6 +74,7 @@ import java.time.Duration; import java.time.Instant; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; @@ -122,6 +124,7 @@ public class ActionExecutionSolutionCEImpl implements ActionExecutionSolutionCE private final TenantService tenantService; private final ActionExecutionSolutionHelper actionExecutionSolutionHelper; private final CommonConfig commonConfig; + private final FeatureFlagService featureFlagService; static final String PARAM_KEY_REGEX = "^k\\d+$"; static final String BLOB_KEY_REGEX = @@ -150,7 +153,8 @@ public ActionExecutionSolutionCEImpl( ConfigService configService, TenantService tenantService, CommonConfig commonConfig, - ActionExecutionSolutionHelper actionExecutionSolutionHelper) { + ActionExecutionSolutionHelper actionExecutionSolutionHelper, + FeatureFlagService featureFlagService) { this.newActionService = newActionService; this.actionPermission = actionPermission; this.observationRegistry = observationRegistry; @@ -171,6 +175,7 @@ public ActionExecutionSolutionCEImpl( this.tenantService = tenantService; this.commonConfig = commonConfig; this.actionExecutionSolutionHelper = actionExecutionSolutionHelper; + this.featureFlagService = featureFlagService; this.patternList.add(Pattern.compile(PARAM_KEY_REGEX)); this.patternList.add(Pattern.compile(BLOB_KEY_REGEX)); @@ -726,13 +731,20 @@ protected Mono verifyDatasourceAndMakeRequest( // Now that we have the context (connection details), execute the action. Instant requestedAt = Instant.now(); + Map features = featureFlagService.getCachedTenantFeatureFlags() != null + ? featureFlagService.getCachedTenantFeatureFlags().getFeatures() + : Collections.emptyMap(); + + // TODO: Flags are needed here for google sheets integration to support shared drive behind a flag + // Once thoroughly tested, this flag can be removed return ((PluginExecutor) pluginExecutor) - .executeParameterizedWithMetrics( + .executeParameterizedWithMetricsAndFlags( resourceContext.getConnection(), executeActionDTO, datasourceStorage1.getDatasourceConfiguration(), actionDTO.getActionConfiguration(), - observationRegistry) + observationRegistry, + features) .map(actionExecutionResult -> { ActionExecutionRequest actionExecutionRequest = actionExecutionResult.getRequest(); if (actionExecutionRequest == null) { diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/DatasourceTriggerSolutionCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/DatasourceTriggerSolutionCEImpl.java index 374264fdaf8d..c4a571037d27 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/DatasourceTriggerSolutionCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/solutions/ce/DatasourceTriggerSolutionCEImpl.java @@ -17,6 +17,7 @@ import com.appsmith.server.services.AuthenticationValidator; import com.appsmith.server.services.ConfigService; import com.appsmith.server.services.DatasourceContextService; +import com.appsmith.server.services.FeatureFlagService; import com.appsmith.server.services.TenantService; import com.appsmith.server.solutions.DatasourcePermission; import com.appsmith.server.solutions.DatasourceStructureSolution; @@ -27,6 +28,7 @@ import reactor.util.function.Tuple2; import java.util.ArrayList; +import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; @@ -53,6 +55,7 @@ public class DatasourceTriggerSolutionCEImpl implements DatasourceTriggerSolutio private final EnvironmentPermission environmentPermission; private final ConfigService configService; private final TenantService tenantService; + private final FeatureFlagService featureFlagService; public Mono trigger( String datasourceId, String environmentId, TriggerRequestDTO triggerRequestDTO) { @@ -104,6 +107,12 @@ public Mono trigger( final Plugin plugin = tuple.getT2(); final PluginExecutor pluginExecutor = tuple.getT3(); + // TODO: Flags are needed here for google sheets integration to support shared drive behind a flag + // Once thoroughly tested, this flag can be removed + Map featureFlagMap = featureFlagService.getCachedTenantFeatureFlags() != null + ? featureFlagService.getCachedTenantFeatureFlags().getFeatures() + : Collections.emptyMap(); + return datasourceContextService .getDatasourceContext(datasourceStorage, plugin) // Now that we have the context (connection details), execute the action. @@ -111,10 +120,11 @@ public Mono trigger( // However the context comes from evaluated datasource. .flatMap(resourceContext -> setTenantAndInstanceId(triggerRequestDTO) .flatMap(updatedTriggerRequestDTO -> ((PluginExecutor) pluginExecutor) - .trigger( + .triggerWithFlags( resourceContext.getConnection(), datasourceStorage.getDatasourceConfiguration(), - updatedTriggerRequestDTO))); + updatedTriggerRequestDTO, + featureFlagMap))); }); // If the plugin hasn't implemented the trigger function, go for the default implementation diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImplTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImplTest.java index 603142af9435..ff664b5ee37c 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImplTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCEImplTest.java @@ -24,6 +24,7 @@ import com.appsmith.server.services.AuthenticationValidator; import com.appsmith.server.services.ConfigService; import com.appsmith.server.services.DatasourceContextService; +import com.appsmith.server.services.FeatureFlagService; import com.appsmith.server.services.SessionUserService; import com.appsmith.server.services.TenantService; import com.appsmith.server.solutions.ActionPermission; @@ -136,6 +137,9 @@ class ActionExecutionSolutionCEImplTest { @SpyBean ActionExecutionSolutionHelper actionExecutionSolutionHelper; + @SpyBean + FeatureFlagService featureFlagService; + @Autowired EnvironmentPermission environmentPermission; @@ -167,7 +171,8 @@ public void beforeEach() { configService, tenantService, commonConfig, - actionExecutionSolutionHelper); + actionExecutionSolutionHelper, + featureFlagService); ObservationRegistry.ObservationConfig mockObservationConfig = Mockito.mock(ObservationRegistry.ObservationConfig.class); diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCETest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCETest.java index cd2fe3a498aa..306012b752bc 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCETest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/solutions/ce/ActionExecutionSolutionCETest.java @@ -327,6 +327,8 @@ private Mono executeAction( Mockito.when(pluginExecutorHelper.getPluginExecutor(any())).thenReturn(Mono.just(pluginExecutor)); Mockito.when(pluginExecutor.executeParameterizedWithMetrics(any(), any(), any(), any(), any())) .thenReturn(Mono.just(mockResult)); + Mockito.when(pluginExecutor.executeParameterizedWithMetricsAndFlags(any(), any(), any(), any(), any(), any())) + .thenReturn(Mono.just(mockResult)); Mockito.when(pluginExecutor.datasourceCreate(any())).thenReturn(Mono.empty()); Mockito.doReturn(Mono.just(false)) .when(spyDatasourceService) @@ -527,6 +529,8 @@ public void testActionExecuteErrorResponse() { Mockito.when(pluginExecutorHelper.getPluginExecutor(any())).thenReturn(Mono.just(pluginExecutor)); Mockito.when(pluginExecutor.executeParameterizedWithMetrics(any(), any(), any(), any(), any())) .thenReturn(Mono.error(pluginException)); + Mockito.when(pluginExecutor.executeParameterizedWithMetricsAndFlags(any(), any(), any(), any(), any(), any())) + .thenReturn(Mono.error(pluginException)); Mockito.when(pluginExecutor.datasourceCreate(any())).thenReturn(Mono.empty()); Mockito.doReturn(Mono.just(false)) .when(spyDatasourceService) @@ -584,6 +588,8 @@ public void testActionExecuteNullPaginationParameters() { Mockito.when(pluginExecutorHelper.getPluginExecutor(any())).thenReturn(Mono.just(pluginExecutor)); Mockito.when(pluginExecutor.executeParameterizedWithMetrics(any(), any(), any(), any(), any())) .thenReturn(Mono.error(pluginException)); + Mockito.when(pluginExecutor.executeParameterizedWithMetricsAndFlags(any(), any(), any(), any(), any(), any())) + .thenReturn(Mono.error(pluginException)); Mockito.when(pluginExecutor.datasourceCreate(any())).thenReturn(Mono.empty()); Mockito.doReturn(Mono.just(false)) .when(spyDatasourceService) @@ -635,6 +641,9 @@ public void testActionExecuteSecondaryStaleConnection() { Mockito.when(pluginExecutor.executeParameterizedWithMetrics(any(), any(), any(), any(), any())) .thenReturn(Mono.error(new StaleConnectionException())) .thenReturn(Mono.error(new StaleConnectionException())); + Mockito.when(pluginExecutor.executeParameterizedWithMetricsAndFlags(any(), any(), any(), any(), any(), any())) + .thenReturn(Mono.error(new StaleConnectionException())) + .thenReturn(Mono.error(new StaleConnectionException())); Mockito.when(pluginExecutor.datasourceCreate(any())).thenReturn(Mono.empty()); Mockito.doReturn(Mono.just(false)) .when(spyDatasourceService) @@ -686,6 +695,8 @@ public void testActionExecuteTimeout() { Mockito.when(pluginExecutorHelper.getPluginExecutor(any())).thenReturn(Mono.just(pluginExecutor)); Mockito.when(pluginExecutor.executeParameterizedWithMetrics(any(), any(), any(), any(), any())) .thenAnswer(x -> Mono.delay(Duration.ofMillis(1000)).ofType(ActionExecutionResult.class)); + Mockito.when(pluginExecutor.executeParameterizedWithMetricsAndFlags(any(), any(), any(), any(), any(), any())) + .thenAnswer(x -> Mono.delay(Duration.ofMillis(1000)).ofType(ActionExecutionResult.class)); Mockito.when(pluginExecutor.datasourceCreate(any())).thenReturn(Mono.empty()); Mockito.doReturn(Mono.just(false)) .when(spyDatasourceService) @@ -716,8 +727,9 @@ public void checkRecoveryFromStaleConnections() { Mockito.when(pluginExecutorHelper.getPluginExecutor(any())).thenReturn(Mono.just(pluginExecutor)); Mockito.when(pluginExecutor.executeParameterizedWithMetrics(any(), any(), any(), any(), any())) - .thenThrow(new StaleConnectionException()) - .thenReturn(Mono.just(mockResult)); + .thenThrow(new StaleConnectionException()); + Mockito.when(pluginExecutor.executeParameterizedWithMetricsAndFlags(any(), any(), any(), any(), any(), any())) + .thenThrow(new StaleConnectionException()); Mockito.when(pluginExecutor.datasourceCreate(any())).thenReturn(Mono.empty()); Mockito.when(pluginExecutor.getHintMessages(any(), any())) .thenReturn(Mono.zip(Mono.just(new HashSet<>()), Mono.just(new HashSet<>())));