feat: Added new api to fetch preview data (#26298)
This commit is contained in:
parent
6b239561da
commit
5b609e0e8f
|
|
@ -155,6 +155,24 @@ public enum AppsmithPluginError implements BasePluginError {
|
|||
ErrorType.INTERNAL_ERROR,
|
||||
"{1}",
|
||||
"{2}"),
|
||||
PLUGIN_GET_PREVIEW_DATA_ERROR(
|
||||
500,
|
||||
AppsmithPluginErrorCode.PLUGIN_GET_PREVIEW_DATA_ERROR.getCode(),
|
||||
AppsmithPluginErrorCode.PLUGIN_GET_PREVIEW_DATA_ERROR.getDescription(),
|
||||
AppsmithErrorAction.DEFAULT,
|
||||
"Failed to get preview data",
|
||||
ErrorType.DATASOURCE_CONFIGURATION_ERROR,
|
||||
"{0}",
|
||||
"{1}"),
|
||||
PLUGIN_UNSUPPORTED_OPERATION(
|
||||
500,
|
||||
AppsmithPluginErrorCode.PLUGIN_UNSUPPORTED_OPERATION.getCode(),
|
||||
AppsmithPluginErrorCode.PLUGIN_UNSUPPORTED_OPERATION.getDescription(),
|
||||
AppsmithErrorAction.DEFAULT,
|
||||
"Unsupported Operation",
|
||||
ErrorType.INTERNAL_ERROR,
|
||||
"{0}",
|
||||
"{1}"),
|
||||
;
|
||||
|
||||
private final Integer httpErrorCode;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,9 @@ public enum AppsmithPluginErrorCode {
|
|||
PLUGIN_UQI_WHERE_CONDITION_UNKNOWN("PE-UQI-5000", "Where condition could not be parsed"),
|
||||
GENERIC_STALE_CONNECTION("PE-STC-5000", "Secondary stale connection error"),
|
||||
PLUGIN_EXECUTE_ARGUMENT_ERROR("PE-ARG-5000", "Wrong arguments provided"),
|
||||
PLUGIN_VALIDATE_DATASOURCE_ERROR("PE-DSE-5005", "Failed to validate datasource");
|
||||
PLUGIN_VALIDATE_DATASOURCE_ERROR("PE-DSE-5005", "Failed to validate datasource"),
|
||||
PLUGIN_GET_PREVIEW_DATA_ERROR("PE-DSE-5006", "Failed to get preview data"),
|
||||
PLUGIN_UNSUPPORTED_OPERATION("PE-DSE-5007", "Unsupported Operation");
|
||||
|
||||
private final String code;
|
||||
private final String description;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import com.appsmith.external.models.ActionConfiguration;
|
|||
import com.appsmith.external.models.ActionExecutionResult;
|
||||
import com.appsmith.external.models.DatasourceConfiguration;
|
||||
import com.appsmith.external.models.DatasourceStructure;
|
||||
import com.appsmith.external.models.DatasourceStructure.Template;
|
||||
import com.appsmith.external.models.DatasourceTestResult;
|
||||
import com.appsmith.external.models.Param;
|
||||
import com.appsmith.external.models.TriggerRequestDTO;
|
||||
|
|
@ -325,4 +326,12 @@ public interface PluginExecutor<C> extends ExtensionPoint, CrudTemplateService {
|
|||
List<ActionConfiguration> actionConfigurationList, Object... args) {
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
/*
|
||||
* This method returns ActionConfiguration required in order to fetch preview data,
|
||||
* that needs to be shown on datasource review page.
|
||||
*/
|
||||
default ActionConfiguration getSchemaPreviewActionConfig(Template queryTemplate) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import com.appsmith.external.models.ActionExecutionResult;
|
|||
import com.appsmith.external.models.DBAuth;
|
||||
import com.appsmith.external.models.DatasourceConfiguration;
|
||||
import com.appsmith.external.models.DatasourceStructure;
|
||||
import com.appsmith.external.models.DatasourceStructure.Template;
|
||||
import com.appsmith.external.models.Endpoint;
|
||||
import com.appsmith.external.models.MustacheBindingToken;
|
||||
import com.appsmith.external.models.Param;
|
||||
|
|
@ -60,6 +61,7 @@ import java.sql.Time;
|
|||
import java.sql.Timestamp;
|
||||
import java.sql.Types;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
|
@ -268,6 +270,21 @@ public class PostgresPlugin extends BasePlugin {
|
|||
explicitCastDataTypes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionConfiguration getSchemaPreviewActionConfig(Template queryTemplate) {
|
||||
ActionConfiguration actionConfig = new ActionConfiguration();
|
||||
// Sets query body
|
||||
actionConfig.setBody(queryTemplate.getBody());
|
||||
|
||||
// Sets prepared statement to false
|
||||
Property preparedStatement = new Property();
|
||||
preparedStatement.setValue(false);
|
||||
List<Property> pluginSpecifiedTemplates = new ArrayList<Property>();
|
||||
pluginSpecifiedTemplates.add(preparedStatement);
|
||||
actionConfig.setPluginSpecifiedTemplates(pluginSpecifiedTemplates);
|
||||
return actionConfig;
|
||||
}
|
||||
|
||||
private Mono<ActionExecutionResult> executeCommon(
|
||||
HikariDataSource connection,
|
||||
DatasourceConfiguration datasourceConfiguration,
|
||||
|
|
@ -285,6 +302,7 @@ public class PostgresPlugin extends BasePlugin {
|
|||
String transformedQuery = preparedStatement ? replaceQuestionMarkWithDollarIndex(query) : query;
|
||||
List<RequestParamDTO> requestParams =
|
||||
List.of(new RequestParamDTO(ACTION_CONFIGURATION_BODY, transformedQuery, null, null, psParams));
|
||||
Instant requestedAt = Instant.now();
|
||||
|
||||
return Mono.fromCallable(() -> {
|
||||
Connection connectionFromPool;
|
||||
|
|
@ -544,6 +562,9 @@ public class PostgresPlugin extends BasePlugin {
|
|||
request.setQuery(query);
|
||||
request.setProperties(requestData);
|
||||
request.setRequestParams(requestParams);
|
||||
if (request.getRequestedAt() == null) {
|
||||
request.setRequestedAt(requestedAt);
|
||||
}
|
||||
ActionExecutionResult result = actionExecutionResult;
|
||||
result.setRequest(request);
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
package com.appsmith.server.controllers.ce;
|
||||
|
||||
import com.appsmith.external.models.ActionExecutionResult;
|
||||
import com.appsmith.external.models.Datasource;
|
||||
import com.appsmith.external.models.DatasourceStorageDTO;
|
||||
import com.appsmith.external.models.DatasourceStructure;
|
||||
import com.appsmith.external.models.DatasourceStructure.Template;
|
||||
import com.appsmith.external.models.DatasourceTestResult;
|
||||
import com.appsmith.external.models.TriggerRequestDTO;
|
||||
import com.appsmith.external.models.TriggerResultDTO;
|
||||
|
|
@ -206,4 +208,16 @@ public class DatasourceControllerCE {
|
|||
.trigger(datasourceId, environmentId, triggerRequestDTO)
|
||||
.map(triggerResultDTO -> new ResponseDTO<>(HttpStatus.OK.value(), triggerResultDTO, null));
|
||||
}
|
||||
|
||||
@JsonView(Views.Public.class)
|
||||
@PostMapping("/{datasourceId}/schema-preview")
|
||||
public Mono<ResponseDTO<ActionExecutionResult>> getSchemaPreviewData(
|
||||
@PathVariable String datasourceId,
|
||||
@RequestBody Template template,
|
||||
@RequestHeader(name = FieldName.ENVIRONMENT_ID, required = false) String environmentId) {
|
||||
log.debug("Going to get schema preview data for datasource with id: '{}'.", datasourceId);
|
||||
return datasourceStructureSolution
|
||||
.getSchemaPreviewData(datasourceId, environmentId, template)
|
||||
.map(actionExecutionResult -> new ResponseDTO<>(HttpStatus.OK.value(), actionExecutionResult, null));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
package com.appsmith.server.solutions.ce;
|
||||
|
||||
import com.appsmith.external.models.ActionExecutionResult;
|
||||
import com.appsmith.external.models.DatasourceStorage;
|
||||
import com.appsmith.external.models.DatasourceStructure;
|
||||
import com.appsmith.external.models.DatasourceStructure.Template;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public interface DatasourceStructureSolutionCE {
|
||||
|
|
@ -9,4 +11,7 @@ public interface DatasourceStructureSolutionCE {
|
|||
Mono<DatasourceStructure> getStructure(String datasourceId, boolean ignoreCache, String environmentName);
|
||||
|
||||
Mono<DatasourceStructure> getStructure(DatasourceStorage datasourceStorage, boolean ignoreCache);
|
||||
|
||||
Mono<ActionExecutionResult> getSchemaPreviewData(
|
||||
String datasourceId, String environmentName, Template queryTemplate);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,9 +4,13 @@ import com.appsmith.external.constants.AnalyticsEvents;
|
|||
import com.appsmith.external.exceptions.pluginExceptions.AppsmithPluginError;
|
||||
import com.appsmith.external.exceptions.pluginExceptions.AppsmithPluginException;
|
||||
import com.appsmith.external.exceptions.pluginExceptions.StaleConnectionException;
|
||||
import com.appsmith.external.models.ActionConfiguration;
|
||||
import com.appsmith.external.models.ActionExecutionResult;
|
||||
import com.appsmith.external.models.Datasource;
|
||||
import com.appsmith.external.models.DatasourceStorage;
|
||||
import com.appsmith.external.models.DatasourceStorageStructure;
|
||||
import com.appsmith.external.models.DatasourceStructure;
|
||||
import com.appsmith.external.models.DatasourceStructure.Template;
|
||||
import com.appsmith.external.plugins.PluginExecutor;
|
||||
import com.appsmith.server.constants.FieldName;
|
||||
import com.appsmith.server.exceptions.AppsmithError;
|
||||
|
|
@ -172,4 +176,80 @@ public class DatasourceStructureSolutionCEImpl implements DatasourceStructureSol
|
|||
.switchIfEmpty(fetchAndStoreNewStructureMono)
|
||||
.defaultIfEmpty(new DatasourceStructure());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<ActionExecutionResult> getSchemaPreviewData(
|
||||
String datasourceId, String environmentId, Template queryTemplate) {
|
||||
return datasourceService
|
||||
.findById(datasourceId, datasourcePermission.getExecutePermission())
|
||||
.zipWhen(datasource -> datasourceService.getTrueEnvironmentId(
|
||||
datasource.getWorkspaceId(),
|
||||
environmentId,
|
||||
datasource.getPluginId(),
|
||||
environmentPermission.getExecutePermission()))
|
||||
.flatMap(tuple -> {
|
||||
Datasource datasource = tuple.getT1();
|
||||
String trueEnvironmentId = tuple.getT2();
|
||||
return datasourceStorageService.findByDatasourceAndEnvironmentIdForExecution(
|
||||
datasource, trueEnvironmentId);
|
||||
})
|
||||
.flatMap(datasourceStorage -> getSchemaPreviewData(datasourceStorage, queryTemplate))
|
||||
.onErrorMap(e -> {
|
||||
if (!(e instanceof AppsmithPluginException)) {
|
||||
return new AppsmithPluginException(
|
||||
AppsmithPluginError.PLUGIN_GET_PREVIEW_DATA_ERROR, e.getMessage());
|
||||
}
|
||||
|
||||
return e;
|
||||
})
|
||||
.onErrorResume(error -> {
|
||||
ActionExecutionResult result = new ActionExecutionResult();
|
||||
result.setErrorInfo(error);
|
||||
return Mono.just(result);
|
||||
});
|
||||
}
|
||||
|
||||
private Mono<ActionExecutionResult> getSchemaPreviewData(
|
||||
DatasourceStorage datasourceStorage, Template queryTemplate) {
|
||||
if (Boolean.FALSE.equals(datasourceStorage.getIsValid())) {
|
||||
return Mono.error(new AppsmithException(AppsmithError.INVALID_DATASOURCE));
|
||||
}
|
||||
|
||||
return pluginExecutorHelper
|
||||
.getPluginExecutor(pluginService.findById(datasourceStorage.getPluginId()))
|
||||
.switchIfEmpty(Mono.error(new AppsmithException(
|
||||
AppsmithError.NO_RESOURCE_FOUND, FieldName.PLUGIN, datasourceStorage.getPluginId())))
|
||||
.flatMap(pluginExecutor -> {
|
||||
ActionConfiguration actionConfig =
|
||||
((PluginExecutor<Object>) pluginExecutor).getSchemaPreviewActionConfig(queryTemplate);
|
||||
// actionConfig will be null for plugins which do not have this functionality yet
|
||||
// Currently its only implemented for PostgreSQL, to be added subsequently for MySQL as well
|
||||
if (actionConfig != null) {
|
||||
return datasourceContextService.retryOnce(
|
||||
datasourceStorage, resourceContext -> ((PluginExecutor<Object>) pluginExecutor)
|
||||
.executeParameterized(
|
||||
resourceContext.getConnection(),
|
||||
null,
|
||||
datasourceStorage.getDatasourceConfiguration(),
|
||||
actionConfig));
|
||||
} else {
|
||||
return Mono.error(
|
||||
new AppsmithPluginException(AppsmithPluginError.PLUGIN_UNSUPPORTED_OPERATION));
|
||||
}
|
||||
})
|
||||
.onErrorMap(
|
||||
StaleConnectionException.class,
|
||||
error -> new AppsmithPluginException(
|
||||
AppsmithPluginError.PLUGIN_ERROR,
|
||||
"Appsmith server found a secondary stale connection. Please reach out to appsmith "
|
||||
+ "customer support to resolve this."))
|
||||
.onErrorMap(e -> {
|
||||
log.error("In the datasourceStorage fetching preview data error mode.", e);
|
||||
if (!(e instanceof AppsmithPluginException)) {
|
||||
return new AppsmithPluginException(
|
||||
AppsmithPluginError.PLUGIN_GET_PREVIEW_DATA_ERROR, e.getMessage());
|
||||
}
|
||||
return e;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user