chore: refactor the appsmith-ai plugin trigger (#38303)

## 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"

### 🔍 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/12462586013>
> Commit: 5dc9f81dfc39a8f5357f2202615ebdb92ac59d15
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=12462586013&attempt=2"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.Sanity`
> Spec:
> <hr>Mon, 23 Dec 2024 07:30:58 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

## 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.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Nilesh Sarupriya <20905988+nsarupr@users.noreply.github.com>
This commit is contained in:
Nilesh Sarupriya 2024-12-23 13:59:33 +05:30 committed by GitHub
parent 0785c556a3
commit 8559d29b30
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 138 additions and 54 deletions

View File

@ -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<TriggerResultDTO> 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<String> 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<Map<String, Object>> response = new ArrayList<>();
fileStatusDTO.getFiles().forEach(file -> {
Map<String, Object> 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<TriggerResultDTO> handleError(String message, Throwable error) {

View File

@ -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<TriggerResultDTO> executeTrigger(
APIConnection connection, DatasourceConfiguration datasourceConfiguration, TriggerRequestDTO request);
}

View File

@ -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<TriggerResultDTO> 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<TriggerResultDTO> 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<TriggerResultDTO> listFiles(
DatasourceConfiguration datasourceConfiguration, TriggerRequestDTO request) {
SourceDetails sourceDetails = SourceDetails.createSourceDetails(request);
List<String> 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<Map<String, Object>> response = new ArrayList<>();
fileStatusDTO.getFiles().forEach(file -> {
Map<String, Object> 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<TriggerResultDTO> 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);
}
}

View File

@ -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<TriggerResultDTO> executeTrigger(
APIConnection connection, DatasourceConfiguration datasourceConfiguration, TriggerRequestDTO request) {
return super.executeTrigger(connection, datasourceConfiguration, request);
}
}