On install, the plugins are loaded and started again. This ensures that we don't have to restart the server every time a new plugin is installed. Earlier the plugins were loaded and started only during the boot
This commit is contained in:
parent
ee3a2a8b8b
commit
59752254b4
|
|
@ -116,6 +116,11 @@
|
||||||
<artifactId>guava</artifactId>
|
<artifactId>guava</artifactId>
|
||||||
<version>28.1-jre</version>
|
<version>28.1-jre</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-io</groupId>
|
||||||
|
<artifactId>commons-io</artifactId>
|
||||||
|
<version>2.6</version>
|
||||||
|
</dependency>
|
||||||
<!-- Plugin dependencies -->
|
<!-- Plugin dependencies -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.pf4j</groupId>
|
<groupId>org.pf4j</groupId>
|
||||||
|
|
|
||||||
|
|
@ -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."),
|
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"),
|
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"),
|
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 httpErrorCode;
|
||||||
private Integer appErrorCode;
|
private Integer appErrorCode;
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@ import com.appsmith.server.exceptions.AppsmithException;
|
||||||
import com.appsmith.server.repositories.PluginRepository;
|
import com.appsmith.server.repositories.PluginRepository;
|
||||||
import com.segment.analytics.Analytics;
|
import com.segment.analytics.Analytics;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
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.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
|
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
|
||||||
|
|
@ -21,6 +23,9 @@ import reactor.core.publisher.Mono;
|
||||||
import reactor.core.scheduler.Scheduler;
|
import reactor.core.scheduler.Scheduler;
|
||||||
|
|
||||||
import javax.validation.Validator;
|
import javax.validation.Validator;
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
@ -31,6 +36,10 @@ public class PluginServiceImpl extends BaseService<PluginRepository, Plugin, Str
|
||||||
private final PluginRepository pluginRepository;
|
private final PluginRepository pluginRepository;
|
||||||
private final ApplicationContext applicationContext;
|
private final ApplicationContext applicationContext;
|
||||||
private final OrganizationService organizationService;
|
private final OrganizationService organizationService;
|
||||||
|
private final PluginManager pluginManager;
|
||||||
|
|
||||||
|
private static final int CONNECTION_TIMEOUT = 1000;
|
||||||
|
private static final int READ_TIMEOUT = 1000;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public PluginServiceImpl(Scheduler scheduler,
|
public PluginServiceImpl(Scheduler scheduler,
|
||||||
|
|
@ -41,11 +50,12 @@ public class PluginServiceImpl extends BaseService<PluginRepository, Plugin, Str
|
||||||
ApplicationContext applicationContext,
|
ApplicationContext applicationContext,
|
||||||
OrganizationService organizationService,
|
OrganizationService organizationService,
|
||||||
Analytics analytics,
|
Analytics analytics,
|
||||||
SessionUserService sessionUserService) {
|
SessionUserService sessionUserService, PluginManager pluginManager) {
|
||||||
super(scheduler, validator, mongoConverter, reactiveMongoTemplate, repository, analytics, sessionUserService);
|
super(scheduler, validator, mongoConverter, reactiveMongoTemplate, repository, analytics, sessionUserService);
|
||||||
this.applicationContext = applicationContext;
|
this.applicationContext = applicationContext;
|
||||||
pluginRepository = repository;
|
pluginRepository = repository;
|
||||||
this.organizationService = organizationService;
|
this.organizationService = organizationService;
|
||||||
|
this.pluginManager = pluginManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OldPluginExecutor getPluginExecutor(PluginType pluginType, String className) {
|
public OldPluginExecutor getPluginExecutor(PluginType pluginType, String className) {
|
||||||
|
|
@ -113,17 +123,51 @@ public class PluginServiceImpl extends BaseService<PluginRepository, Plugin, Str
|
||||||
|
|
||||||
//Find the organization using id and plugin id -> This is to find if the organization already has the plugin installed
|
//Find the organization using id and plugin id -> This is to find if the organization already has the plugin installed
|
||||||
Mono<User> userMono = super.sessionUserService.getCurrentUser();
|
Mono<User> userMono = super.sessionUserService.getCurrentUser();
|
||||||
Mono<Organization> organizationMono = userMono.flatMap(user ->
|
Mono<Organization> pluginInOrganizationMono = userMono.flatMap(user ->
|
||||||
organizationService.findByIdAndPluginsPluginId(user.getOrganizationId(), pluginDTO.getPluginId()));
|
organizationService.findByIdAndPluginsPluginId(user.getOrganizationId(), pluginDTO.getPluginId()));
|
||||||
|
|
||||||
|
|
||||||
//If plugin is already present for the organization, just return the organization, else install and return organization
|
//If plugin is already present for the organization, just return the organization, else install and return organization
|
||||||
return organizationMono
|
return pluginInOrganizationMono
|
||||||
.switchIfEmpty(Mono.defer(() -> {
|
.switchIfEmpty(Mono.defer(() -> {
|
||||||
//If the plugin is not found in the organization, its not installed already. Install now.
|
//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()))
|
.flatMap(user -> organizationService.findById(user.getOrganizationId()))
|
||||||
.map(organization -> {
|
.map(organization -> {
|
||||||
|
|
||||||
List<OrganizationPlugin> organizationPluginList = organization.getPlugins();
|
List<OrganizationPlugin> organizationPluginList = organization.getPlugins();
|
||||||
if (organizationPluginList == null) {
|
if (organizationPluginList == null) {
|
||||||
organizationPluginList = new ArrayList<OrganizationPlugin>();
|
organizationPluginList = new ArrayList<OrganizationPlugin>();
|
||||||
|
|
@ -134,6 +178,8 @@ public class PluginServiceImpl extends BaseService<PluginRepository, Plugin, Str
|
||||||
organizationPlugin.setStatus(status);
|
organizationPlugin.setStatus(status);
|
||||||
organizationPluginList.add(organizationPlugin);
|
organizationPluginList.add(organizationPlugin);
|
||||||
organization.setPlugins(organizationPluginList);
|
organization.setPlugins(organizationPluginList);
|
||||||
|
|
||||||
|
//return the organization
|
||||||
return organization;
|
return organization;
|
||||||
})
|
})
|
||||||
.flatMap(organizationService::save);
|
.flatMap(organizationService::save);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user