diff --git a/app/server/appsmith-server/pom.xml b/app/server/appsmith-server/pom.xml
index c2e3e22740..4564049424 100644
--- a/app/server/appsmith-server/pom.xml
+++ b/app/server/appsmith-server/pom.xml
@@ -116,6 +116,11 @@
guava
28.1-jre
+
+ commons-io
+ commons-io
+ 2.6
+
org.pf4j
diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/AppsmithError.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/AppsmithError.java
index 8c23f11f7c..72c52ebd86 100644
--- a/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/AppsmithError.java
+++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/AppsmithError.java
@@ -16,7 +16,8 @@ public enum AppsmithError {
PAGE_DOESNT_BELONG_TO_USER_ORGANIZATION(400, 4006, "Page {0} does not belong to the current user {1} organization."),
UNAUTHORIZED_DOMAIN(401, 4001, "Invalid email domain provided. Please sign in with a valid work email ID"),
INTERNAL_SERVER_ERROR(500, 5000, "Internal server error while processing request"),
- REPOSITORY_SAVE_FAILED(500, 5001, "Repository save failed.");
+ REPOSITORY_SAVE_FAILED(500, 5001, "Repository save failed."),
+ PLUGIN_INSTALLATION_FAILED_DOWNLOAD_ERROR(500, 5002, "Due to error in downloading the plugin from remote repository, plugin installation has failed. Check the jar location and try again.");
private Integer httpErrorCode;
private Integer appErrorCode;
diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/PluginServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/PluginServiceImpl.java
index 5f6bfa5aeb..bbd7148045 100644
--- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/PluginServiceImpl.java
+++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/PluginServiceImpl.java
@@ -12,6 +12,8 @@ import com.appsmith.server.exceptions.AppsmithException;
import com.appsmith.server.repositories.PluginRepository;
import com.segment.analytics.Analytics;
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.context.ApplicationContext;
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
@@ -21,6 +23,9 @@ import reactor.core.publisher.Mono;
import reactor.core.scheduler.Scheduler;
import javax.validation.Validator;
+import java.io.File;
+import java.net.URL;
+import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
@@ -31,6 +36,10 @@ public class PluginServiceImpl extends BaseService This is to find if the organization already has the plugin installed
Mono userMono = super.sessionUserService.getCurrentUser();
- Mono organizationMono = userMono.flatMap(user ->
+ Mono pluginInOrganizationMono = userMono.flatMap(user ->
organizationService.findByIdAndPluginsPluginId(user.getOrganizationId(), pluginDTO.getPluginId()));
//If plugin is already present for the organization, just return the organization, else install and return organization
- return organizationMono
+ return pluginInOrganizationMono
.switchIfEmpty(Mono.defer(() -> {
//If the plugin is not found in the organization, its not installed already. Install now.
- return userMono
+ return pluginRepository
+ .findById(pluginDTO.getPluginId())
+ .map(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
+ */
+ return plugin;
+ }
+
+ String baseUrl = "../dist/plugins/";
+ String pluginJar = plugin.getName() + ".jar";
+
+ // Else download the plugin jar to the local
+ 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));
+ pluginManager.startPlugins();
+
+ return plugin;
+ })
+ //Now that the plugin jar has been successfully downloaded, go on and add the plugin to the organization
+ .then(userMono)
.flatMap(user -> organizationService.findById(user.getOrganizationId()))
.map(organization -> {
+
List organizationPluginList = organization.getPlugins();
if (organizationPluginList == null) {
organizationPluginList = new ArrayList();
@@ -134,6 +178,8 @@ public class PluginServiceImpl extends BaseService