Merge branch 'feature/install-plugin' into 'master'

Install Plugin

See merge request theappsmith/internal-tools-server!33
This commit is contained in:
Trisha Anand 2019-10-04 04:27:11 +00:00
commit ccf2be5e6c
3 changed files with 57 additions and 5 deletions

View File

@ -116,6 +116,11 @@
<artifactId>guava</artifactId>
<version>28.1-jre</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<!-- Plugin dependencies -->
<dependency>
<groupId>org.pf4j</groupId>

View File

@ -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;

View File

@ -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<PluginRepository, Plugin, Str
private final PluginRepository pluginRepository;
private final ApplicationContext applicationContext;
private final OrganizationService organizationService;
private final PluginManager pluginManager;
private static final int CONNECTION_TIMEOUT = 1000;
private static final int READ_TIMEOUT = 1000;
@Autowired
public PluginServiceImpl(Scheduler scheduler,
@ -41,11 +50,12 @@ public class PluginServiceImpl extends BaseService<PluginRepository, Plugin, Str
ApplicationContext applicationContext,
OrganizationService organizationService,
Analytics analytics,
SessionUserService sessionUserService) {
SessionUserService sessionUserService, PluginManager pluginManager) {
super(scheduler, validator, mongoConverter, reactiveMongoTemplate, repository, analytics, sessionUserService);
this.applicationContext = applicationContext;
pluginRepository = repository;
this.organizationService = organizationService;
this.pluginManager = pluginManager;
}
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
Mono<User> userMono = super.sessionUserService.getCurrentUser();
Mono<Organization> organizationMono = userMono.flatMap(user ->
Mono<Organization> 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<OrganizationPlugin> organizationPluginList = organization.getPlugins();
if (organizationPluginList == null) {
organizationPluginList = new ArrayList<OrganizationPlugin>();
@ -134,6 +178,8 @@ public class PluginServiceImpl extends BaseService<PluginRepository, Plugin, Str
organizationPlugin.setStatus(status);
organizationPluginList.add(organizationPlugin);
organization.setPlugins(organizationPluginList);
//return the organization
return organization;
})
.flatMap(organizationService::save);