From 8559d29b309b966be54567838517e414443d345e Mon Sep 17 00:00:00 2001 From: Nilesh Sarupriya Date: Mon, 23 Dec 2024 13:59:33 +0530 Subject: [PATCH] chore: refactor the appsmith-ai plugin trigger (#38303) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description > [!IMPORTANT] > Refactor the Appsmith AI Plugin trigger method. 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" ### :mag: Cypress test results > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: > Commit: 5dc9f81dfc39a8f5357f2202615ebdb92ac59d15 > Cypress dashboard. > Tags: `@tag.Sanity` > Spec: >
Mon, 23 Dec 2024 07:30:58 UTC ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No ## Summary by CodeRabbit ## Summary by CodeRabbit - **New Features** - Introduced a new service for managing file upload and listing operations. - Added structured handling of triggers for file-related actions. - **Bug Fixes** - Enhanced error management for file operations to improve logging and response handling. --------- Co-authored-by: Nilesh Sarupriya <20905988+nsarupr@users.noreply.github.com> --- .../external/plugins/AppsmithAiPlugin.java | 59 +---------- .../plugins/services/TriggerService.java | 12 +++ .../services/TriggerServiceCEImpl.java | 100 ++++++++++++++++++ .../plugins/services/TriggerServiceImpl.java | 21 ++++ 4 files changed, 138 insertions(+), 54 deletions(-) create mode 100644 app/server/appsmith-plugins/appsmithAiPlugin/src/main/java/com/external/plugins/services/TriggerService.java create mode 100644 app/server/appsmith-plugins/appsmithAiPlugin/src/main/java/com/external/plugins/services/TriggerServiceCEImpl.java create mode 100644 app/server/appsmith-plugins/appsmithAiPlugin/src/main/java/com/external/plugins/services/TriggerServiceImpl.java diff --git a/app/server/appsmith-plugins/appsmithAiPlugin/src/main/java/com/external/plugins/AppsmithAiPlugin.java b/app/server/appsmith-plugins/appsmithAiPlugin/src/main/java/com/external/plugins/AppsmithAiPlugin.java index 7fd4776a8f..e756bb7f88 100644 --- a/app/server/appsmith-plugins/appsmithAiPlugin/src/main/java/com/external/plugins/AppsmithAiPlugin.java +++ b/app/server/appsmith-plugins/appsmithAiPlugin/src/main/java/com/external/plugins/AppsmithAiPlugin.java @@ -26,6 +26,8 @@ import com.external.plugins.services.AiFeatureService; import com.external.plugins.services.AiFeatureServiceFactory; import com.external.plugins.services.AiServerService; import com.external.plugins.services.AiServerServiceImpl; +import com.external.plugins.services.TriggerService; +import com.external.plugins.services.TriggerServiceImpl; import com.external.plugins.utils.RequestUtils; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -34,16 +36,10 @@ import org.pf4j.PluginWrapper; import reactor.core.publisher.Mono; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; -import static com.appsmith.external.constants.CommonFieldName.VALUE; -import static com.external.plugins.constants.AppsmithAiConstants.DISABLED; -import static com.external.plugins.constants.AppsmithAiConstants.LABEL; -import static com.external.plugins.constants.AppsmithAiConstants.LIST_FILES; -import static com.external.plugins.constants.AppsmithAiConstants.UPLOAD_FILES; import static com.external.plugins.constants.AppsmithAiConstants.USECASE; import static com.external.plugins.utils.FileUtils.getFileIds; import static com.external.plugins.utils.FileUtils.hasFiles; @@ -57,6 +53,8 @@ public class AppsmithAiPlugin extends BasePlugin { public static class AppsmithAiPluginExecutor extends BaseRestApiPluginExecutor { private static final AiServerService aiServerService = new AiServerServiceImpl(); + + private static final TriggerService triggerService = new TriggerServiceImpl(aiServerService, objectMapper); private static final Gson gson = new GsonBuilder().create(); public AppsmithAiPluginExecutor(SharedConfig config) { @@ -80,54 +78,7 @@ public class AppsmithAiPlugin extends BasePlugin { public Mono trigger( APIConnection connection, DatasourceConfiguration datasourceConfiguration, TriggerRequestDTO request) { log.debug(Thread.currentThread().getName() + ": trigger() called for AppsmithAI plugin."); - SourceDetails sourceDetails = SourceDetails.createSourceDetails(request); - String requestType = request.getRequestType(); - if (UPLOAD_FILES.equals(requestType)) { - return aiServerService - .uploadFiles(request.getFiles(), sourceDetails) - .flatMap(response -> { - TriggerResultDTO triggerResultDTO = new TriggerResultDTO(); - triggerResultDTO.setTrigger(response); - return Mono.just(triggerResultDTO); - }) - .onErrorResume( - error -> handleError("An error has occurred while trying to upload files", error)); - } else if (LIST_FILES.equals(requestType)) { - List fileIds = getFileIds(datasourceConfiguration); - if (fileIds.isEmpty()) { - TriggerResultDTO triggerResultDTO = new TriggerResultDTO(); - triggerResultDTO.setTrigger(List.of(Map.of( - DISABLED, - true, - LABEL, - "No files available in the datasource", - VALUE, - "NO_FILES_AVAILABLE"))); - return Mono.just(triggerResultDTO); - } - return aiServerService - .getFilesStatus(fileIds, sourceDetails) - .flatMap(fileStatusDTO -> { - List> response = new ArrayList<>(); - fileStatusDTO.getFiles().forEach(file -> { - Map dropdownOption = new HashMap<>(); - if (!file.isProcessed()) { - dropdownOption.put(LABEL, "(Processing...) " + file.getName()); - } else { - dropdownOption.put(LABEL, file.getName()); - } - dropdownOption.put(VALUE, file.getId()); - dropdownOption.put(DISABLED, !file.isProcessed()); - response.add(dropdownOption); - }); - TriggerResultDTO triggerResultDTO = new TriggerResultDTO(); - triggerResultDTO.setTrigger(response); - return Mono.just(triggerResultDTO); - }) - .onErrorResume(error -> - handleError("An error has occurred while trying to list uploaded files", error)); - } - return super.trigger(connection, datasourceConfiguration, request); + return triggerService.executeTrigger(connection, datasourceConfiguration, request); } private Mono handleError(String message, Throwable error) { diff --git a/app/server/appsmith-plugins/appsmithAiPlugin/src/main/java/com/external/plugins/services/TriggerService.java b/app/server/appsmith-plugins/appsmithAiPlugin/src/main/java/com/external/plugins/services/TriggerService.java new file mode 100644 index 0000000000..cf3619a3b5 --- /dev/null +++ b/app/server/appsmith-plugins/appsmithAiPlugin/src/main/java/com/external/plugins/services/TriggerService.java @@ -0,0 +1,12 @@ +package com.external.plugins.services; + +import com.appsmith.external.helpers.restApiUtils.connections.APIConnection; +import com.appsmith.external.models.DatasourceConfiguration; +import com.appsmith.external.models.TriggerRequestDTO; +import com.appsmith.external.models.TriggerResultDTO; +import reactor.core.publisher.Mono; + +public interface TriggerService { + Mono executeTrigger( + APIConnection connection, DatasourceConfiguration datasourceConfiguration, TriggerRequestDTO request); +} diff --git a/app/server/appsmith-plugins/appsmithAiPlugin/src/main/java/com/external/plugins/services/TriggerServiceCEImpl.java b/app/server/appsmith-plugins/appsmithAiPlugin/src/main/java/com/external/plugins/services/TriggerServiceCEImpl.java new file mode 100644 index 0000000000..6f3e18ed28 --- /dev/null +++ b/app/server/appsmith-plugins/appsmithAiPlugin/src/main/java/com/external/plugins/services/TriggerServiceCEImpl.java @@ -0,0 +1,100 @@ +package com.external.plugins.services; + +import com.appsmith.external.exceptions.pluginExceptions.AppsmithPluginError; +import com.appsmith.external.exceptions.pluginExceptions.AppsmithPluginException; +import com.appsmith.external.helpers.restApiUtils.connections.APIConnection; +import com.appsmith.external.models.DatasourceConfiguration; +import com.appsmith.external.models.TriggerRequestDTO; +import com.appsmith.external.models.TriggerResultDTO; +import com.external.plugins.dtos.SourceDetails; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import reactor.core.publisher.Mono; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static com.appsmith.external.constants.CommonFieldName.VALUE; +import static com.external.plugins.constants.AppsmithAiConstants.DISABLED; +import static com.external.plugins.constants.AppsmithAiConstants.LABEL; +import static com.external.plugins.constants.AppsmithAiConstants.LIST_FILES; +import static com.external.plugins.constants.AppsmithAiConstants.UPLOAD_FILES; +import static com.external.plugins.utils.FileUtils.getFileIds; + +@Slf4j +public class TriggerServiceCEImpl implements TriggerService { + + private final AiServerService aiServerService; + private final ObjectMapper objectMapper; + + public TriggerServiceCEImpl(AiServerService aiServerService, ObjectMapper objectMapper) { + this.aiServerService = aiServerService; + this.objectMapper = objectMapper; + } + + @Override + public Mono executeTrigger( + APIConnection connection, DatasourceConfiguration datasourceConfiguration, TriggerRequestDTO request) { + String requestType = request.getRequestType(); + return switch (requestType) { + case UPLOAD_FILES -> this.uploadFiles(request); + case LIST_FILES -> this.listFiles(datasourceConfiguration, request); + default -> Mono.empty(); + }; + } + + private Mono uploadFiles(TriggerRequestDTO request) { + SourceDetails sourceDetails = SourceDetails.createSourceDetails(request); + return aiServerService + .uploadFiles(request.getFiles(), sourceDetails) + .flatMap(response -> { + TriggerResultDTO triggerResultDTO = new TriggerResultDTO(); + triggerResultDTO.setTrigger(response); + return Mono.just(triggerResultDTO); + }) + .onErrorResume(error -> handleError("An error has occurred while trying to upload files", error)); + } + + private Mono listFiles( + DatasourceConfiguration datasourceConfiguration, TriggerRequestDTO request) { + SourceDetails sourceDetails = SourceDetails.createSourceDetails(request); + List fileIds = getFileIds(datasourceConfiguration); + if (fileIds.isEmpty()) { + TriggerResultDTO triggerResultDTO = new TriggerResultDTO(); + triggerResultDTO.setTrigger(List.of(Map.of( + DISABLED, true, LABEL, "No files available in the datasource", VALUE, "NO_FILES_AVAILABLE"))); + return Mono.just(triggerResultDTO); + } + return aiServerService + .getFilesStatus(fileIds, sourceDetails) + .flatMap(fileStatusDTO -> { + List> response = new ArrayList<>(); + fileStatusDTO.getFiles().forEach(file -> { + Map dropdownOption = new HashMap<>(); + if (!file.isProcessed()) { + dropdownOption.put(LABEL, "(Processing...) " + file.getName()); + } else { + dropdownOption.put(LABEL, file.getName()); + } + dropdownOption.put(VALUE, file.getId()); + dropdownOption.put(DISABLED, !file.isProcessed()); + response.add(dropdownOption); + }); + TriggerResultDTO triggerResultDTO = new TriggerResultDTO(); + triggerResultDTO.setTrigger(response); + return Mono.just(triggerResultDTO); + }) + .onErrorResume( + error -> handleError("An error has occurred while trying to list uploaded files", error)); + } + + protected Mono handleError(String message, Throwable error) { + log.error("{}. Error: {}", message, error.getMessage()); + if (!(error instanceof AppsmithPluginException)) { + error = new AppsmithPluginException(AppsmithPluginError.PLUGIN_ERROR, error.getMessage(), error); + } + return Mono.error(error); + } +} diff --git a/app/server/appsmith-plugins/appsmithAiPlugin/src/main/java/com/external/plugins/services/TriggerServiceImpl.java b/app/server/appsmith-plugins/appsmithAiPlugin/src/main/java/com/external/plugins/services/TriggerServiceImpl.java new file mode 100644 index 0000000000..e4bd7e3734 --- /dev/null +++ b/app/server/appsmith-plugins/appsmithAiPlugin/src/main/java/com/external/plugins/services/TriggerServiceImpl.java @@ -0,0 +1,21 @@ +package com.external.plugins.services; + +import com.appsmith.external.helpers.restApiUtils.connections.APIConnection; +import com.appsmith.external.models.DatasourceConfiguration; +import com.appsmith.external.models.TriggerRequestDTO; +import com.appsmith.external.models.TriggerResultDTO; +import com.fasterxml.jackson.databind.ObjectMapper; +import reactor.core.publisher.Mono; + +public class TriggerServiceImpl extends TriggerServiceCEImpl { + + public TriggerServiceImpl(AiServerService aiServerService, ObjectMapper objectMapper) { + super(aiServerService, objectMapper); + } + + @Override + public Mono executeTrigger( + APIConnection connection, DatasourceConfiguration datasourceConfiguration, TriggerRequestDTO request) { + return super.executeTrigger(connection, datasourceConfiguration, request); + } +}