diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/PluginController.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/PluginController.java index 695e757a3c..3b9aab6f4c 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/PluginController.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/PluginController.java @@ -1,5 +1,6 @@ package com.appsmith.server.controllers; +import com.appsmith.server.configurations.CloudServicesConfig; import com.appsmith.server.constants.Url; import com.appsmith.server.controllers.ce.PluginControllerCE; import com.appsmith.server.plugins.base.PluginService; @@ -11,7 +12,10 @@ import org.springframework.web.bind.annotation.RestController; @RequestMapping(Url.PLUGIN_URL) public class PluginController extends PluginControllerCE { - public PluginController(PluginService service, PluginTriggerSolution pluginTriggerSolution) { - super(service, pluginTriggerSolution); + public PluginController( + PluginService service, + PluginTriggerSolution pluginTriggerSolution, + CloudServicesConfig cloudServicesConfig) { + super(service, pluginTriggerSolution, cloudServicesConfig); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/PluginControllerCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/PluginControllerCE.java index 3811860740..e08f08ffb9 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/PluginControllerCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/PluginControllerCE.java @@ -3,10 +3,12 @@ package com.appsmith.server.controllers.ce; import com.appsmith.external.models.TriggerRequestDTO; import com.appsmith.external.models.TriggerResultDTO; import com.appsmith.external.views.Views; +import com.appsmith.server.configurations.CloudServicesConfig; import com.appsmith.server.constants.FieldName; import com.appsmith.server.constants.Url; import com.appsmith.server.domains.Plugin; import com.appsmith.server.dtos.ResponseDTO; +import com.appsmith.server.exceptions.AppsmithException; import com.appsmith.server.plugins.base.PluginService; import com.appsmith.server.plugins.solutions.PluginTriggerSolution; import com.fasterxml.jackson.annotation.JsonView; @@ -28,6 +30,7 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import java.util.List; +import java.util.Map; @RequestMapping(Url.PLUGIN_URL) @RequiredArgsConstructor @@ -38,6 +41,8 @@ public class PluginControllerCE { private final PluginTriggerSolution pluginTriggerSolution; + private final CloudServicesConfig cloudServicesConfig; + @JsonView(Views.Public.class) @GetMapping public Mono>> getAll(@RequestParam String workspaceId) { @@ -96,4 +101,21 @@ public class PluginControllerCE { serverWebExchange.getRequest().getHeaders()) .map(triggerResultDTO -> new ResponseDTO<>(HttpStatus.OK, triggerResultDTO)); } + + @JsonView(Views.Public.class) + @GetMapping("/upcoming-integrations") + public Mono>>> getUpcomingIntegrations() { + log.debug("Fetching upcoming integrations from external API"); + return service.getUpcomingIntegrations() + .map(integrations -> new ResponseDTO<>(HttpStatus.OK, integrations)) + .onErrorResume(error -> { + if (error instanceof AppsmithException) { + log.warn("Cloud service error: {}", error.getMessage()); + return Mono.just(new ResponseDTO<>(HttpStatus.OK.value(), List.of(), error.getMessage())); + } + log.warn("Error retrieving upcoming integrations from external service: {}", error.getMessage()); + return Mono.just(new ResponseDTO<>( + HttpStatus.OK.value(), List.of(), "Unable to fetch upcoming integrations at this time")); + }); + } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/base/PluginServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/base/PluginServiceCE.java index d2e588247f..6a62cbed9d 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/base/PluginServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/base/PluginServiceCE.java @@ -53,4 +53,6 @@ public interface PluginServiceCE extends CrudService { Mono> findAllPluginsInWorkspace(String workspaceId); Flux getPluginsByType(PluginType pluginType); + + Mono>> getUpcomingIntegrations(); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/base/PluginServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/base/PluginServiceCEImpl.java index bdbfe12114..4af6b9d78a 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/base/PluginServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/base/PluginServiceCEImpl.java @@ -2,6 +2,7 @@ package com.appsmith.server.plugins.base; import com.appsmith.external.models.Datasource; import com.appsmith.external.models.PluginType; +import com.appsmith.server.configurations.CloudServicesConfig; import com.appsmith.server.constants.FieldName; import com.appsmith.server.domains.Plugin; import com.appsmith.server.domains.Workspace; @@ -15,7 +16,9 @@ import com.appsmith.server.helpers.LoadShifter; import com.appsmith.server.repositories.PluginRepository; import com.appsmith.server.services.AnalyticsService; import com.appsmith.server.services.BaseService; +import com.appsmith.server.services.ConfigService; import com.appsmith.server.services.WorkspaceService; +import com.appsmith.util.WebClientUtils; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; @@ -46,6 +49,7 @@ import java.io.InputStream; import java.net.URL; import java.nio.charset.Charset; import java.nio.file.Path; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -65,6 +69,7 @@ public class PluginServiceCEImpl extends BaseService reactiveTemplate; private final ChannelTopic topic; private final ObjectMapper objectMapper; + private final CloudServicesConfig cloudServicesConfig; private final Map>> formCache = new HashMap<>(); private final Map>> templateCache = new HashMap<>(); @@ -86,6 +91,8 @@ public class PluginServiceCEImpl extends BaseService reactiveTemplate, ChannelTopic topic, - ObjectMapper objectMapper) { + ObjectMapper objectMapper, + CloudServicesConfig cloudServicesConfig, + ConfigService configService) { super(validator, repository, analyticsService); this.workspaceService = workspaceService; this.pluginManager = pluginManager; this.reactiveTemplate = reactiveTemplate; this.topic = topic; this.objectMapper = objectMapper; + this.cloudServicesConfig = cloudServicesConfig; + this.configService = configService; } @Override @@ -660,6 +671,55 @@ public class PluginServiceCEImpl extends BaseService>> getUpcomingIntegrations() { + log.debug("Fetching upcoming integrations from external API"); + + return configService.getInstanceId().flatMap(instanceId -> { + String apiUrl = cloudServicesConfig.getBaseUrl() + + "/api/v1/config/external-saas/upcoming-integrations?instanceId=" + instanceId; + return WebClientUtils.create() + .get() + .uri(apiUrl) + .retrieve() + .bodyToMono(Map.class) + .flatMap(response -> { + // Extract the integrations list from the response + if (response.containsKey("data")) { + List> integrations = new ArrayList<>(); + List data = (List) response.get("data"); + for (Object item : data) { + if (item instanceof Map) { + integrations.add((Map) item); + } + } + return Mono.just(integrations); + } else if (response.containsKey("responseMeta")) { + Map responseMeta = (Map) response.get("responseMeta"); + if (responseMeta.containsKey("error")) { + Map error = (Map) responseMeta.get("error"); + if (error.containsKey("message")) { + String errorMessage = (String) error.get("message"); + return Mono.error(new AppsmithException( + AppsmithError.INSTANCE_REGISTRATION_FAILURE, errorMessage)); + } + } + return Mono.error(new RuntimeException("Unknown error in response metadata")); + } + return Mono.just(List.>of()); + }) + .onErrorResume(error -> { + if (error instanceof AppsmithException) { + return Mono.error(error); + } + log.warn( + "Error retrieving upcoming integrations from external service: {}", error.getMessage()); + return Mono.error( + new RuntimeException("Error retrieving upcoming integrations: " + error.getMessage())); + }); + }); + } + @Data static class PluginTemplatesMeta { List templates; diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/base/PluginServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/base/PluginServiceImpl.java index ba4cf06c1c..505e7f4f16 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/base/PluginServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/plugins/base/PluginServiceImpl.java @@ -1,7 +1,9 @@ package com.appsmith.server.plugins.base; +import com.appsmith.server.configurations.CloudServicesConfig; import com.appsmith.server.repositories.PluginRepository; import com.appsmith.server.services.AnalyticsService; +import com.appsmith.server.services.ConfigService; import com.appsmith.server.services.WorkspaceService; import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.validation.Validator; @@ -23,7 +25,9 @@ public class PluginServiceImpl extends PluginServiceCEImpl implements PluginServ PluginManager pluginManager, ReactiveRedisTemplate reactiveTemplate, ChannelTopic topic, - ObjectMapper objectMapper) { + ObjectMapper objectMapper, + CloudServicesConfig cloudServicesConfig, + ConfigService configService) { super( validator, @@ -33,6 +37,8 @@ public class PluginServiceImpl extends PluginServiceCEImpl implements PluginServ pluginManager, reactiveTemplate, topic, - objectMapper); + objectMapper, + cloudServicesConfig, + configService); } } diff --git a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/PluginServiceCEImplTest.java b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/PluginServiceCEImplTest.java index cb17b8cbf9..d7eb6147fa 100644 --- a/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/PluginServiceCEImplTest.java +++ b/app/server/appsmith-server/src/test/java/com/appsmith/server/services/ce/PluginServiceCEImplTest.java @@ -1,10 +1,12 @@ package com.appsmith.server.services.ce; +import com.appsmith.server.configurations.CloudServicesConfig; import com.appsmith.server.domains.Plugin; import com.appsmith.server.plugins.base.PluginServiceCE; import com.appsmith.server.plugins.base.PluginServiceCEImpl; import com.appsmith.server.repositories.PluginRepository; import com.appsmith.server.services.AnalyticsService; +import com.appsmith.server.services.ConfigService; import com.appsmith.server.services.WorkspaceService; import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.validation.Validator; @@ -56,6 +58,8 @@ public class PluginServiceCEImplTest { ObjectMapper objectMapper; PluginServiceCE pluginService; + CloudServicesConfig cloudServicesConfig; + ConfigService configService; @BeforeEach public void setUp() { @@ -68,7 +72,9 @@ public class PluginServiceCEImplTest { pluginManager, reactiveTemplate, topic, - objectMapper); + objectMapper, + cloudServicesConfig, + configService); } @Test