diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/RedisConfig.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/RedisConfig.java index c341b99bf029..bd0bbcb96a57 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/RedisConfig.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/RedisConfig.java @@ -33,7 +33,6 @@ import org.springframework.data.redis.connection.lettuce.observability.MicrometerTracingAdapter; import org.springframework.data.redis.core.ReactiveRedisOperations; import org.springframework.data.redis.core.ReactiveRedisTemplate; -import org.springframework.data.redis.listener.ChannelTopic; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer; @@ -104,17 +103,6 @@ public void registerOwnHostWithSsrfFilter() { RestrictedHostFilter.registerOwnHost(System.getenv("HOSTNAME")); } - /** - * This is the topic to which we will publish & subscribe to. We can have multiple topics based on the messages - * that we wish to broadcast. Starting with a single one for now. - * - * @return - */ - @Bean - ChannelTopic topic() { - return new ChannelTopic("appsmith:queue"); - } - @Bean @Primary public ReactiveRedisConnectionFactory reactiveRedisConnectionFactory() { diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/RedisListenerConfig.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/RedisListenerConfig.java deleted file mode 100644 index 36ee880993d6..000000000000 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/RedisListenerConfig.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.appsmith.server.configurations; - -import com.appsmith.server.dtos.InstallPluginRedisDTO; -import com.appsmith.server.plugins.base.PluginService; -import com.fasterxml.jackson.databind.ObjectMapper; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.redis.connection.ReactiveRedisConnectionFactory; -import org.springframework.data.redis.listener.ChannelTopic; -import org.springframework.data.redis.listener.ReactiveRedisMessageListenerContainer; -import reactor.core.publisher.Mono; - -import java.util.concurrent.CancellationException; - -@Configuration -@Slf4j -public class RedisListenerConfig { - - private final ObjectMapper objectMapper; - private final PluginService pluginService; - private final ChannelTopic topic; - - @Autowired - public RedisListenerConfig(ObjectMapper objectMapper, PluginService pluginService, ChannelTopic topic) { - this.objectMapper = objectMapper; - this.pluginService = pluginService; - this.topic = topic; - } - - /** - * This is the listener that will receive all the messages from the Redis channel topic configured in topic(). - * Currently the only topic we are listening to is for install plugin requests. - * - * @param factory - * @return - */ - @Bean - public ReactiveRedisMessageListenerContainer container(ReactiveRedisConnectionFactory factory) { - ReactiveRedisMessageListenerContainer container = new ReactiveRedisMessageListenerContainer(factory); - container - // The receive function can subscribe to multiple topics as well. Can also subscribe via regex pattern - // to multiple channels - .receive(topic) - // Extract the message from the incoming object. By default it's String serialization. The receive() fxn - // can also configure different serialization classes based on requirements - .map(p -> p.getMessage()) - .map(msg -> { - try { - InstallPluginRedisDTO installPluginRedisDTO = - objectMapper.readValue(msg, InstallPluginRedisDTO.class); - return installPluginRedisDTO; - } catch (Exception e) { - log.error("", e); - return Mono.error(e); - } - }) - // Actual processing of the message. - .map(redisPluginObj -> pluginService.redisInstallPlugin((InstallPluginRedisDTO) redisPluginObj)) - // Handle this error because it prevents the Redis connection from shutting down when the server is shut - // down - // TODO: Verify if this is invoked in normal redis pubsub execution as well - .doOnError(throwable -> { - if (!(throwable instanceof CancellationException)) { - // The Reactive RedisListener doesn't shut down properly. Hence, only printing errors for - // ones that are not of type CancellationException - log.error("Error occurred in RedisListenerConfig: ", throwable); - } - }) - // Required to subscribe else this chain is never invoked - .subscribe(); - return container; - } -} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/IndexController.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/IndexController.java index 8781bd966993..a2c1283f76bd 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/IndexController.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/IndexController.java @@ -3,8 +3,6 @@ import com.appsmith.server.controllers.ce.IndexControllerCE; import com.appsmith.server.services.SessionUserService; import lombok.extern.slf4j.Slf4j; -import org.springframework.data.redis.core.ReactiveRedisTemplate; -import org.springframework.data.redis.listener.ChannelTopic; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -13,9 +11,7 @@ @RequestMapping("") public class IndexController extends IndexControllerCE { - public IndexController( - SessionUserService service, ReactiveRedisTemplate reactiveTemplate, ChannelTopic topic) { - - super(service, reactiveTemplate, topic); + public IndexController(SessionUserService service) { + super(service); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/IndexControllerCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/IndexControllerCE.java index 90f49d556ba4..89169ec60d81 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/IndexControllerCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ce/IndexControllerCE.java @@ -6,8 +6,6 @@ import com.fasterxml.jackson.annotation.JsonView; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.data.redis.core.ReactiveRedisTemplate; -import org.springframework.data.redis.listener.ChannelTopic; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import reactor.core.publisher.Mono; @@ -20,8 +18,6 @@ public class IndexControllerCE { private final SessionUserService service; - private final ReactiveRedisTemplate reactiveTemplate; - private final ChannelTopic topic; @JsonView(Views.Public.class) @GetMapping @@ -29,14 +25,4 @@ public Mono index(Mono principal) { Mono userMono = service.getCurrentUser(); return userMono.map(obj -> obj.getUsername()).map(name -> String.format("Hello %s", name)); } - - /* - * This function is primarily for testing if we can publish to Redis successfully. If yes, the response should be - * non-zero value number of subscribers who've successfully gotten the published message - */ - @JsonView(Views.Public.class) - @GetMapping("/redisPub") - public Mono pubRedisMessage() { - return reactiveTemplate.convertAndSend(topic.getTopic(), "This is a test message"); - } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/InstallPluginRedisDTO.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/InstallPluginRedisDTO.java deleted file mode 100644 index ccce06916c48..000000000000 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/dtos/InstallPluginRedisDTO.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.appsmith.server.dtos; - -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -public class InstallPluginRedisDTO { - String workspaceId; - PluginWorkspaceDTO pluginWorkspaceDTO; -} 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 6a62cbed9ddb..cbcb528eb6f7 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 @@ -4,7 +4,6 @@ import com.appsmith.external.models.PluginType; import com.appsmith.server.domains.Plugin; import com.appsmith.server.domains.Workspace; -import com.appsmith.server.dtos.InstallPluginRedisDTO; import com.appsmith.server.dtos.PluginWorkspaceDTO; import com.appsmith.server.services.CrudService; import reactor.core.publisher.Flux; @@ -34,8 +33,6 @@ public interface PluginServiceCE extends CrudService { Mono getPluginName(Mono datasourceMono); - Plugin redisInstallPlugin(InstallPluginRedisDTO installPluginRedisDTO); - Mono> getFormConfig(String pluginId); Flux getAllRemotePlugins(); 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 8953ce0de619..edc96bb9189c 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 @@ -7,7 +7,6 @@ import com.appsmith.server.domains.Plugin; import com.appsmith.server.domains.Workspace; import com.appsmith.server.domains.WorkspacePlugin; -import com.appsmith.server.dtos.InstallPluginRedisDTO; import com.appsmith.server.dtos.PluginWorkspaceDTO; import com.appsmith.server.dtos.WorkspacePluginStatus; import com.appsmith.server.exceptions.AppsmithError; @@ -20,7 +19,6 @@ 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; import com.fasterxml.jackson.databind.ObjectMapper; @@ -30,26 +28,20 @@ import lombok.Data; import lombok.NonNull; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.io.FileUtils; import org.pf4j.PluginManager; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; -import org.springframework.data.redis.core.ReactiveRedisTemplate; -import org.springframework.data.redis.listener.ChannelTopic; import org.springframework.util.StreamUtils; import org.springframework.util.StringUtils; import reactor.core.Exceptions; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; -import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; 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; @@ -67,8 +59,6 @@ public class PluginServiceCEImpl extends BaseService reactiveTemplate; - private final ChannelTopic topic; private final ObjectMapper objectMapper; private final CloudServicesConfig cloudServicesConfig; @@ -78,9 +68,6 @@ public class PluginServiceCEImpl extends BaseService>> templateCache = new HashMap<>(); private final Map> labelCache = new HashMap<>(); - private static final int CONNECTION_TIMEOUT = 10000; - private static final int READ_TIMEOUT = 10000; - private static final String UQI_QUERY_EDITOR_BASE_FOLDER = "editor"; private static final String UQI_QUERY_EDITOR_ROOT_FILE = "root.json"; @@ -103,8 +90,6 @@ public PluginServiceCEImpl( AnalyticsService analyticsService, WorkspaceService workspaceService, PluginManager pluginManager, - ReactiveRedisTemplate reactiveTemplate, - ChannelTopic topic, ObjectMapper objectMapper, CloudServicesConfig cloudServicesConfig, ConfigService configService, @@ -112,8 +97,6 @@ public PluginServiceCEImpl( 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; @@ -196,45 +179,23 @@ private Mono storeWorkspacePlugin(PluginWorkspaceDTO pluginDTO, Works return pluginInWorkspaceMono.switchIfEmpty(Mono.defer(() -> { log.debug("Plugin {} not already installed. Installing now", pluginDTO.getPluginId()); // If the plugin is not found in the workspace, its not installed already. Install now. - return repository - .findById(pluginDTO.getPluginId()) - .map(plugin -> { - log.debug("Before publishing to the redis queue"); - // Publish the event to the pub/sub queue - InstallPluginRedisDTO installPluginRedisDTO = new InstallPluginRedisDTO(); - installPluginRedisDTO.setWorkspaceId(pluginDTO.getWorkspaceId()); - installPluginRedisDTO.setPluginWorkspaceDTO(pluginDTO); - String jsonString; - try { - jsonString = objectMapper.writeValueAsString(installPluginRedisDTO); - } catch (JsonProcessingException e) { - log.error("", e); - return Mono.error(e); - } - return reactiveTemplate - .convertAndSend(topic.getTopic(), jsonString) - .subscribe(); - }) - // Now that the plugin jar has been successfully downloaded, go on and add the plugin to the - // workspace - .then(workspaceService.getById(pluginDTO.getWorkspaceId())) - .flatMap(workspace -> { - Set workspacePluginList = workspace.getPlugins(); - if (workspacePluginList == null) { - workspacePluginList = new HashSet<>(); - } + return workspaceService.getById(pluginDTO.getWorkspaceId()).flatMap(workspace -> { + Set workspacePluginList = workspace.getPlugins(); + if (workspacePluginList == null) { + workspacePluginList = new HashSet<>(); + } - WorkspacePlugin workspacePlugin = new WorkspacePlugin(); - workspacePlugin.setPluginId(pluginDTO.getPluginId()); - workspacePlugin.setStatus(status); - workspacePluginList.add(workspacePlugin); - workspace.setPlugins(workspacePluginList); + WorkspacePlugin workspacePlugin = new WorkspacePlugin(); + workspacePlugin.setPluginId(pluginDTO.getPluginId()); + workspacePlugin.setStatus(status); + workspacePluginList.add(workspacePlugin); + workspace.setPlugins(workspacePluginList); - log.debug( - "Going to save the workspace with install plugin. This means that installation has been successful"); + log.debug( + "Going to save the workspace with install plugin. This means that installation has been successful"); - return workspaceService.save(workspace); - }); + return workspaceService.save(workspace); + }); })); } @@ -257,51 +218,6 @@ public Mono getPluginName(Mono datasourceMono) { .map(plugin -> plugin.getPluginName() == null ? plugin.getPackageName() : plugin.getPluginName())); } - @Override - public Plugin redisInstallPlugin(InstallPluginRedisDTO installPluginRedisDTO) { - Mono pluginMono = repository.findById( - installPluginRedisDTO.getPluginWorkspaceDTO().getPluginId()); - return pluginMono - .flatMap(plugin -> downloadAndStartPlugin(installPluginRedisDTO.getWorkspaceId(), plugin)) - .switchIfEmpty(Mono.defer(() -> { - log.debug( - "During redisInstallPlugin, no plugin with plugin id {} found. Returning without download and install", - installPluginRedisDTO.getPluginWorkspaceDTO().getPluginId()); - return Mono.just(new Plugin()); - })) - .block(); - } - - private Mono downloadAndStartPlugin(String workspaceId, Plugin plugin) { - if (plugin.getJarLocation() == null) { - // Plugin jar location not set. Must be local - /** TODO - * In future throw an error if jar location is not set - */ - log.debug("plugin jarLocation is null. Not downloading and starting. Returning now"); - return Mono.just(plugin); - } - - String baseUrl = "../dist/plugins/"; - String pluginJar = plugin.getName() + "-" + workspaceId + ".jar"; - log.debug("Going to download plugin jar with name : {}", baseUrl + pluginJar); - - try { - FileUtils.copyURLToFile( - new URL(plugin.getJarLocation()), new File(baseUrl, pluginJar), CONNECTION_TIMEOUT, READ_TIMEOUT); - } catch (Exception e) { - log.error("", e); - return Mono.error(new AppsmithException(AppsmithError.PLUGIN_INSTALLATION_FAILED_DOWNLOAD_ERROR)); - } - - // Now that the plugin has been downloaded, load and restart the plugin - pluginManager.loadPlugin(Path.of(baseUrl + pluginJar)); - // The following only starts plugins which have been loaded but hasn't been started yet. - pluginManager.startPlugins(); - - return Mono.just(plugin); - } - @Override public Mono> getFormConfig(String pluginId) { if (!formCache.containsKey(pluginId)) { 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 85e2ff545b03..f140bb60373d 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 @@ -10,8 +10,6 @@ import jakarta.validation.Validator; import lombok.extern.slf4j.Slf4j; import org.pf4j.PluginManager; -import org.springframework.data.redis.core.ReactiveRedisTemplate; -import org.springframework.data.redis.listener.ChannelTopic; import org.springframework.stereotype.Service; @Slf4j @@ -24,8 +22,6 @@ public PluginServiceImpl( AnalyticsService analyticsService, WorkspaceService workspaceService, PluginManager pluginManager, - ReactiveRedisTemplate reactiveTemplate, - ChannelTopic topic, ObjectMapper objectMapper, CloudServicesConfig cloudServicesConfig, ConfigService configService, @@ -37,8 +33,6 @@ public PluginServiceImpl( analyticsService, workspaceService, pluginManager, - reactiveTemplate, - topic, 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 2af47070ff63..c7a695457c6e 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 @@ -19,8 +19,6 @@ import org.pf4j.PluginWrapper; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.core.io.ClassPathResource; -import org.springframework.data.redis.core.ReactiveRedisTemplate; -import org.springframework.data.redis.listener.ChannelTopic; import org.springframework.test.context.junit.jupiter.SpringExtension; import java.io.IOException; @@ -50,12 +48,6 @@ public class PluginServiceCEImplTest { @MockBean PluginManager pluginManager; - @MockBean - ReactiveRedisTemplate reactiveTemplate; - - @MockBean - ChannelTopic topic; - @MockBean PluginTransformationSolution pluginTransformationSolution; @@ -74,8 +66,6 @@ public void setUp() { analyticsService, workspaceService, pluginManager, - reactiveTemplate, - topic, objectMapper, cloudServicesConfig, configService,