1. Added datasource validator function in the plugin interface which simply returns true for all the current plugins.
2. Added static method getPluginExecutor as a util function which removes duplicate code from across different files.
This commit is contained in:
parent
98662714dc
commit
31cf94f08e
|
|
@ -31,4 +31,6 @@ public interface PluginExecutor extends ExtensionPoint {
|
||||||
* @param connection
|
* @param connection
|
||||||
*/
|
*/
|
||||||
void datasourceDestroy(Object connection);
|
void datasourceDestroy(Object connection);
|
||||||
|
|
||||||
|
Boolean isDatasourceValid(DatasourceConfiguration datasourceConfiguration);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -125,6 +125,11 @@ public class MongoPlugin extends BasePlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean isDatasourceValid(DatasourceConfiguration datasourceConfiguration) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,11 @@ public class PostgresPlugin extends BasePlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean isDatasourceValid(DatasourceConfiguration datasourceConfiguration) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,10 @@ import org.springframework.web.util.UriComponentsBuilder;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.URL;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class RestApiPlugin extends BasePlugin {
|
public class RestApiPlugin extends BasePlugin {
|
||||||
|
|
@ -112,6 +114,22 @@ public class RestApiPlugin extends BasePlugin {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean isDatasourceValid(DatasourceConfiguration datasourceConfiguration) {
|
||||||
|
if (datasourceConfiguration.getUrl() == null) {
|
||||||
|
System.out.println("URL is null. Data validation failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Check for URL validity
|
||||||
|
try {
|
||||||
|
new URL(datasourceConfiguration.getUrl()).toURI();
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("URL is invalid. Data validation failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void addHeadersToRequest(WebClient.Builder webClientBuilder, List<Property> headers) {
|
private void addHeadersToRequest(WebClient.Builder webClientBuilder, List<Property> headers) {
|
||||||
for (Property header : headers) {
|
for (Property header : headers) {
|
||||||
if (header.getKey() != null && !header.getKey().isEmpty()) {
|
if (header.getKey() != null && !header.getKey().isEmpty()) {
|
||||||
|
|
|
||||||
|
|
@ -168,6 +168,10 @@
|
||||||
<artifactId>rollbar-java</artifactId>
|
<artifactId>rollbar-java</artifactId>
|
||||||
<version>1.5.2</version>
|
<version>1.5.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mockito</groupId>
|
||||||
|
<artifactId>mockito-core</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
|
||||||
|
|
@ -7,5 +7,6 @@ public class FieldName {
|
||||||
public static String PAGEID = "pageId";
|
public static String PAGEID = "pageId";
|
||||||
public static String LAYOUTID = "layoutId";
|
public static String LAYOUTID = "layoutId";
|
||||||
public static String APPLICATIONID = "applicationId";
|
public static String APPLICATIONID = "applicationId";
|
||||||
|
public static String DATASOURCE = "datasource";
|
||||||
public static String CONFIG = "config";
|
public static String CONFIG = "config";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ public enum AppsmithError {
|
||||||
UNAUTHORIZED_DOMAIN(401, 4012, "Invalid email domain provided. Please sign in with a valid work email ID"),
|
UNAUTHORIZED_DOMAIN(401, 4012, "Invalid email domain provided. Please sign in with a valid work email ID"),
|
||||||
UNAUTHORIZED_ACCESS(401, 4013, "Unauthorized access"),
|
UNAUTHORIZED_ACCESS(401, 4013, "Unauthorized access"),
|
||||||
INVALID_ACTION_NAME(401, 4014, "Action name is invalid. Please input syntactically correct name"),
|
INVALID_ACTION_NAME(401, 4014, "Action name is invalid. Please input syntactically correct name"),
|
||||||
|
INVALID_DATASOURCE_CONFIGURATION(400, 4015, "Datasource configuration is invalid"),
|
||||||
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"),
|
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"),
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
package com.appsmith.server.helpers;
|
||||||
|
|
||||||
|
import com.appsmith.external.plugins.PluginExecutor;
|
||||||
|
import com.appsmith.server.domains.Plugin;
|
||||||
|
import com.appsmith.server.exceptions.AppsmithError;
|
||||||
|
import com.appsmith.server.exceptions.AppsmithException;
|
||||||
|
import org.pf4j.PluginManager;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class PluginExecutorHelper {
|
||||||
|
|
||||||
|
private PluginManager pluginManager;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public PluginExecutorHelper(PluginManager pluginManager) {
|
||||||
|
this.pluginManager = pluginManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mono<PluginExecutor> getPluginExecutor(Mono<Plugin> pluginMono) {
|
||||||
|
return pluginMono.flatMap(plugin -> {
|
||||||
|
List<PluginExecutor> executorList = pluginManager.getExtensions(PluginExecutor.class, plugin.getExecutorClass());
|
||||||
|
if (executorList.isEmpty()) {
|
||||||
|
return Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, "plugin", plugin.getExecutorClass()));
|
||||||
|
}
|
||||||
|
return Mono.just(executorList.get(0));
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,14 +7,11 @@ import com.appsmith.external.models.Param;
|
||||||
import com.appsmith.external.plugins.PluginExecutor;
|
import com.appsmith.external.plugins.PluginExecutor;
|
||||||
import com.appsmith.server.constants.AnalyticsEvents;
|
import com.appsmith.server.constants.AnalyticsEvents;
|
||||||
import com.appsmith.server.constants.FieldName;
|
import com.appsmith.server.constants.FieldName;
|
||||||
import com.appsmith.server.domains.Action;
|
import com.appsmith.server.domains.*;
|
||||||
import com.appsmith.server.domains.Datasource;
|
|
||||||
import com.appsmith.server.domains.Page;
|
|
||||||
import com.appsmith.server.domains.PageAction;
|
|
||||||
import com.appsmith.server.domains.Plugin;
|
|
||||||
import com.appsmith.server.dtos.ExecuteActionDTO;
|
import com.appsmith.server.dtos.ExecuteActionDTO;
|
||||||
import com.appsmith.server.exceptions.AppsmithError;
|
import com.appsmith.server.exceptions.AppsmithError;
|
||||||
import com.appsmith.server.exceptions.AppsmithException;
|
import com.appsmith.server.exceptions.AppsmithException;
|
||||||
|
import com.appsmith.server.helpers.PluginExecutorHelper;
|
||||||
import com.appsmith.server.repositories.ActionRepository;
|
import com.appsmith.server.repositories.ActionRepository;
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
@ -22,7 +19,6 @@ import com.github.mustachejava.DefaultMustacheFactory;
|
||||||
import com.github.mustachejava.Mustache;
|
import com.github.mustachejava.Mustache;
|
||||||
import com.github.mustachejava.MustacheFactory;
|
import com.github.mustachejava.MustacheFactory;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.pf4j.PluginManager;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
|
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
|
||||||
import org.springframework.data.mongodb.core.convert.MongoConverter;
|
import org.springframework.data.mongodb.core.convert.MongoConverter;
|
||||||
|
|
@ -37,11 +33,7 @@ import javax.validation.constraints.NotNull;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static com.appsmith.server.helpers.BeanCopyUtils.copyNewFieldValuesIntoOldObject;
|
import static com.appsmith.server.helpers.BeanCopyUtils.copyNewFieldValuesIntoOldObject;
|
||||||
|
|
@ -56,9 +48,9 @@ public class ActionServiceImpl extends BaseService<ActionRepository, Action, Str
|
||||||
private final DatasourceService datasourceService;
|
private final DatasourceService datasourceService;
|
||||||
private final PluginService pluginService;
|
private final PluginService pluginService;
|
||||||
private final PageService pageService;
|
private final PageService pageService;
|
||||||
private final PluginManager pluginManager;
|
|
||||||
private final ObjectMapper objectMapper;
|
private final ObjectMapper objectMapper;
|
||||||
private final DatasourceContextService datasourceContextService;
|
private final DatasourceContextService datasourceContextService;
|
||||||
|
private final PluginExecutorHelper pluginExecutorHelper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public ActionServiceImpl(Scheduler scheduler,
|
public ActionServiceImpl(Scheduler scheduler,
|
||||||
|
|
@ -69,18 +61,18 @@ public class ActionServiceImpl extends BaseService<ActionRepository, Action, Str
|
||||||
DatasourceService datasourceService,
|
DatasourceService datasourceService,
|
||||||
PluginService pluginService,
|
PluginService pluginService,
|
||||||
PageService pageService,
|
PageService pageService,
|
||||||
PluginManager pluginManager,
|
|
||||||
AnalyticsService analyticsService,
|
AnalyticsService analyticsService,
|
||||||
ObjectMapper objectMapper,
|
ObjectMapper objectMapper,
|
||||||
DatasourceContextService datasourceContextService) {
|
DatasourceContextService datasourceContextService,
|
||||||
|
PluginExecutorHelper pluginExecutorHelper) {
|
||||||
super(scheduler, validator, mongoConverter, reactiveMongoTemplate, repository, analyticsService);
|
super(scheduler, validator, mongoConverter, reactiveMongoTemplate, repository, analyticsService);
|
||||||
this.repository = repository;
|
this.repository = repository;
|
||||||
this.datasourceService = datasourceService;
|
this.datasourceService = datasourceService;
|
||||||
this.pluginService = pluginService;
|
this.pluginService = pluginService;
|
||||||
this.pageService = pageService;
|
this.pageService = pageService;
|
||||||
this.pluginManager = pluginManager;
|
|
||||||
this.objectMapper = objectMapper;
|
this.objectMapper = objectMapper;
|
||||||
this.datasourceContextService = datasourceContextService;
|
this.datasourceContextService = datasourceContextService;
|
||||||
|
this.pluginExecutorHelper = pluginExecutorHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -320,14 +312,7 @@ public class ActionServiceImpl extends BaseService<ActionRepository, Action, Str
|
||||||
.flatMap(datasource -> pluginService.findById(datasource.getPluginId()))
|
.flatMap(datasource -> pluginService.findById(datasource.getPluginId()))
|
||||||
.switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, "plugin")));
|
.switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, "plugin")));
|
||||||
|
|
||||||
Mono<PluginExecutor> pluginExecutorMono = pluginMono.flatMap(plugin -> {
|
Mono<PluginExecutor> pluginExecutorMono = pluginExecutorHelper.getPluginExecutor(pluginMono);
|
||||||
List<PluginExecutor> executorList = pluginManager.getExtensions(PluginExecutor.class, plugin.getExecutorClass());
|
|
||||||
if (executorList.isEmpty()) {
|
|
||||||
return Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, "plugin", plugin.getExecutorClass()));
|
|
||||||
}
|
|
||||||
return Mono.just(executorList.get(0));
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// 4. Execute the query
|
// 4. Execute the query
|
||||||
return actionMono
|
return actionMono
|
||||||
|
|
|
||||||
|
|
@ -2,18 +2,15 @@ package com.appsmith.server.services;
|
||||||
|
|
||||||
import com.appsmith.external.plugins.PluginExecutor;
|
import com.appsmith.external.plugins.PluginExecutor;
|
||||||
import com.appsmith.server.domains.Datasource;
|
import com.appsmith.server.domains.Datasource;
|
||||||
import com.appsmith.server.domains.DatasourceContext;
|
|
||||||
import com.appsmith.server.domains.Plugin;
|
import com.appsmith.server.domains.Plugin;
|
||||||
import com.appsmith.server.exceptions.AppsmithError;
|
import com.appsmith.server.domains.DatasourceContext;
|
||||||
import com.appsmith.server.exceptions.AppsmithException;
|
import com.appsmith.server.helpers.PluginExecutorHelper;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.pf4j.PluginManager;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
|
@ -23,14 +20,16 @@ public class DatasourceContextServiceImpl implements DatasourceContextService {
|
||||||
//This is DatasourceId mapped to the DatasourceContext
|
//This is DatasourceId mapped to the DatasourceContext
|
||||||
Map<String, DatasourceContext> datasourceContextMap;
|
Map<String, DatasourceContext> datasourceContextMap;
|
||||||
private final DatasourceService datasourceService;
|
private final DatasourceService datasourceService;
|
||||||
private final PluginManager pluginManager;
|
|
||||||
private final PluginService pluginService;
|
private final PluginService pluginService;
|
||||||
|
private final PluginExecutorHelper pluginExecutorHelper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public DatasourceContextServiceImpl(DatasourceService datasourceService, PluginManager pluginManager, PluginService pluginService) {
|
public DatasourceContextServiceImpl(DatasourceService datasourceService,
|
||||||
|
PluginService pluginService,
|
||||||
|
PluginExecutorHelper pluginExecutorHelper) {
|
||||||
this.datasourceService = datasourceService;
|
this.datasourceService = datasourceService;
|
||||||
this.pluginManager = pluginManager;
|
|
||||||
this.pluginService = pluginService;
|
this.pluginService = pluginService;
|
||||||
|
this.pluginExecutorHelper = pluginExecutorHelper;
|
||||||
this.datasourceContextMap = new HashMap<>();
|
this.datasourceContextMap = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -57,14 +56,7 @@ public class DatasourceContextServiceImpl implements DatasourceContextService {
|
||||||
.flatMap(resource -> pluginService.findById(resource.getPluginId()));
|
.flatMap(resource -> pluginService.findById(resource.getPluginId()));
|
||||||
|
|
||||||
//Datasource Context has not been created for this resource on this machine. Create one now.
|
//Datasource Context has not been created for this resource on this machine. Create one now.
|
||||||
Mono<PluginExecutor> pluginExecutorMono = pluginMono.flatMap(plugin -> {
|
Mono<PluginExecutor> pluginExecutorMono = pluginExecutorHelper.getPluginExecutor(pluginMono);
|
||||||
List<PluginExecutor> executorList = pluginManager.getExtensions(PluginExecutor.class, plugin.getExecutorClass());
|
|
||||||
if (executorList.isEmpty()) {
|
|
||||||
return Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, "plugin", plugin.getExecutorClass()));
|
|
||||||
}
|
|
||||||
return Mono.just(executorList.get(0));
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
return Mono.zip(datasourceMono, pluginExecutorMono, ((datasource1, pluginExecutor) -> {
|
return Mono.zip(datasourceMono, pluginExecutorMono, ((datasource1, pluginExecutor) -> {
|
||||||
Object connection = pluginExecutor.datasourceCreate(datasource1.getDatasourceConfiguration());
|
Object connection = pluginExecutor.datasourceCreate(datasource1.getDatasourceConfiguration());
|
||||||
|
|
@ -92,14 +84,7 @@ public class DatasourceContextServiceImpl implements DatasourceContextService {
|
||||||
.flatMap(datasource -> pluginService.findById(datasource.getPluginId()));
|
.flatMap(datasource -> pluginService.findById(datasource.getPluginId()));
|
||||||
|
|
||||||
//Datasource Context has not been created for this resource on this machine. Create one now.
|
//Datasource Context has not been created for this resource on this machine. Create one now.
|
||||||
Mono<PluginExecutor> pluginExecutorMono = pluginMono.flatMap(plugin -> {
|
Mono<PluginExecutor> pluginExecutorMono = pluginExecutorHelper.getPluginExecutor(pluginMono);
|
||||||
List<PluginExecutor> executorList = pluginManager.getExtensions(PluginExecutor.class, plugin.getExecutorClass());
|
|
||||||
if (executorList.isEmpty()) {
|
|
||||||
return Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, "plugin", plugin.getExecutorClass()));
|
|
||||||
}
|
|
||||||
return Mono.just(executorList.get(0));
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
return Mono.zip(datasourceMono, pluginExecutorMono, ((datasource, pluginExecutor) -> {
|
return Mono.zip(datasourceMono, pluginExecutorMono, ((datasource, pluginExecutor) -> {
|
||||||
pluginExecutor.datasourceDestroy(datasourceContext.getConnection());
|
pluginExecutor.datasourceDestroy(datasourceContext.getConnection());
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
package com.appsmith.server.services;
|
package com.appsmith.server.services;
|
||||||
|
|
||||||
|
import com.appsmith.external.plugins.PluginExecutor;
|
||||||
import com.appsmith.server.constants.FieldName;
|
import com.appsmith.server.constants.FieldName;
|
||||||
import com.appsmith.server.domains.Datasource;
|
import com.appsmith.server.domains.Datasource;
|
||||||
import com.appsmith.server.domains.Organization;
|
import com.appsmith.server.domains.Organization;
|
||||||
import com.appsmith.server.domains.User;
|
import com.appsmith.server.domains.User;
|
||||||
import com.appsmith.server.exceptions.AppsmithError;
|
import com.appsmith.server.exceptions.AppsmithError;
|
||||||
import com.appsmith.server.exceptions.AppsmithException;
|
import com.appsmith.server.exceptions.AppsmithException;
|
||||||
|
import com.appsmith.server.helpers.PluginExecutorHelper;
|
||||||
import com.appsmith.server.repositories.DatasourceRepository;
|
import com.appsmith.server.repositories.DatasourceRepository;
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
@ -32,6 +34,8 @@ public class DatasourceServiceImpl extends BaseService<DatasourceRepository, Dat
|
||||||
private final OrganizationService organizationService;
|
private final OrganizationService organizationService;
|
||||||
private final SessionUserService sessionUserService;
|
private final SessionUserService sessionUserService;
|
||||||
private final ObjectMapper objectMapper;
|
private final ObjectMapper objectMapper;
|
||||||
|
private final PluginService pluginService;
|
||||||
|
private final PluginExecutorHelper pluginExecutorHelper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public DatasourceServiceImpl(Scheduler scheduler,
|
public DatasourceServiceImpl(Scheduler scheduler,
|
||||||
|
|
@ -42,12 +46,16 @@ public class DatasourceServiceImpl extends BaseService<DatasourceRepository, Dat
|
||||||
OrganizationService organizationService,
|
OrganizationService organizationService,
|
||||||
AnalyticsService analyticsService,
|
AnalyticsService analyticsService,
|
||||||
SessionUserService sessionUserService,
|
SessionUserService sessionUserService,
|
||||||
ObjectMapper objectMapper) {
|
ObjectMapper objectMapper,
|
||||||
|
PluginService pluginService,
|
||||||
|
PluginExecutorHelper pluginExecutorHelper) {
|
||||||
super(scheduler, validator, mongoConverter, reactiveMongoTemplate, repository, analyticsService);
|
super(scheduler, validator, mongoConverter, reactiveMongoTemplate, repository, analyticsService);
|
||||||
this.repository = repository;
|
this.repository = repository;
|
||||||
this.organizationService = organizationService;
|
this.organizationService = organizationService;
|
||||||
this.sessionUserService = sessionUserService;
|
this.sessionUserService = sessionUserService;
|
||||||
this.objectMapper = objectMapper;
|
this.objectMapper = objectMapper;
|
||||||
|
this.pluginService = pluginService;
|
||||||
|
this.pluginExecutorHelper = pluginExecutorHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -61,10 +69,13 @@ public class DatasourceServiceImpl extends BaseService<DatasourceRepository, Dat
|
||||||
if (datasource.getDatasourceConfiguration() == null) {
|
if (datasource.getDatasourceConfiguration() == null) {
|
||||||
return Mono.error(new AppsmithException(AppsmithError.NO_CONFIGURATION_FOUND_IN_DATASOURCE));
|
return Mono.error(new AppsmithException(AppsmithError.NO_CONFIGURATION_FOUND_IN_DATASOURCE));
|
||||||
}
|
}
|
||||||
|
Mono<PluginExecutor> pluginExecutorMono = pluginExecutorHelper.getPluginExecutor(pluginService.findById(datasource.getPluginId()));
|
||||||
|
|
||||||
Mono<User> userMono = sessionUserService.getCurrentUser();
|
Mono<User> userMono = sessionUserService.getCurrentUser();
|
||||||
|
|
||||||
Mono<Organization> organizationMono = userMono.flatMap(user -> organizationService.findByIdAndPluginsPluginId(user.getCurrentOrganizationId(), datasource.getPluginId()));
|
Mono<Organization> organizationMono = userMono
|
||||||
|
.flatMap(user -> organizationService.findByIdAndPluginsPluginId(user.getCurrentOrganizationId(), datasource.getPluginId()))
|
||||||
|
.switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.PLUGIN_NOT_INSTALLED, datasource.getPluginId())));
|
||||||
|
|
||||||
//Add organization id to the datasource.
|
//Add organization id to the datasource.
|
||||||
Mono<Datasource> updatedDatasourceMono = organizationMono
|
Mono<Datasource> updatedDatasourceMono = organizationMono
|
||||||
|
|
@ -73,12 +84,42 @@ public class DatasourceServiceImpl extends BaseService<DatasourceRepository, Dat
|
||||||
return datasource;
|
return datasource;
|
||||||
});
|
});
|
||||||
|
|
||||||
return organizationMono
|
return Mono.zip(updatedDatasourceMono, pluginExecutorMono)
|
||||||
.switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.PLUGIN_NOT_INSTALLED, datasource.getPluginId())))
|
.flatMap(tuple -> {
|
||||||
.then(updatedDatasourceMono)
|
Datasource datasource1 = tuple.getT1();
|
||||||
|
PluginExecutor pluginExecutor = tuple.getT2();
|
||||||
|
Boolean isValid = pluginExecutor.isDatasourceValid(datasource1.getDatasourceConfiguration());
|
||||||
|
if (isValid) {
|
||||||
|
return Mono.just(datasource1);
|
||||||
|
}
|
||||||
|
return Mono.error(new AppsmithException(AppsmithError.INVALID_DATASOURCE_CONFIGURATION));
|
||||||
|
})
|
||||||
.flatMap(super::create);
|
.flatMap(super::create);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Mono<Datasource> update(String id, Datasource datasource) {
|
||||||
|
if (datasource.getDatasourceConfiguration() != null) {
|
||||||
|
|
||||||
|
Mono<Datasource> datasourceMono = repository.findById(id)
|
||||||
|
.switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.DATASOURCE, id)));
|
||||||
|
|
||||||
|
Mono<PluginExecutor> pluginExecutorMono = datasourceMono
|
||||||
|
.flatMap(datasource1 -> pluginExecutorHelper.getPluginExecutor(pluginService.findById(datasource1.getPluginId())));
|
||||||
|
|
||||||
|
return pluginExecutorMono
|
||||||
|
.flatMap(pluginExecutor -> {
|
||||||
|
Boolean isValid = pluginExecutor.isDatasourceValid(datasource.getDatasourceConfiguration());
|
||||||
|
if (!isValid) {
|
||||||
|
return Mono.error(new AppsmithException(AppsmithError.INVALID_DATASOURCE_CONFIGURATION));
|
||||||
|
}
|
||||||
|
return Mono.just(datasource);
|
||||||
|
})
|
||||||
|
.flatMap(datasource1 -> super.update(id, datasource1));
|
||||||
|
}
|
||||||
|
return super.update(id, datasource);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mono<Datasource> findByName(String name) {
|
public Mono<Datasource> findByName(String name) {
|
||||||
return repository.findByName(name);
|
return repository.findByName(name);
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,7 @@ public class SeedMongoData {
|
||||||
})
|
})
|
||||||
.flatMap(pageRepository::save)
|
.flatMap(pageRepository::save)
|
||||||
)
|
)
|
||||||
.subscribe(obj -> log.info("Last Saved Object: " + obj));
|
.blockLast();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import org.junit.runner.RunWith;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.security.test.context.support.WithMockUser;
|
import org.springframework.security.test.context.support.WithMockUser;
|
||||||
|
import org.springframework.test.annotation.DirtiesContext;
|
||||||
import org.springframework.test.context.junit4.SpringRunner;
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
import reactor.test.StepVerifier;
|
import reactor.test.StepVerifier;
|
||||||
|
|
@ -19,6 +20,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
@SpringBootTest
|
@SpringBootTest
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@DirtiesContext
|
||||||
public class ApplicationServiceTest {
|
public class ApplicationServiceTest {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,26 @@
|
||||||
package com.appsmith.server.services;
|
package com.appsmith.server.services;
|
||||||
|
|
||||||
|
import com.appsmith.external.models.ActionConfiguration;
|
||||||
|
import com.appsmith.external.models.ActionExecutionResult;
|
||||||
import com.appsmith.external.models.DatasourceConfiguration;
|
import com.appsmith.external.models.DatasourceConfiguration;
|
||||||
|
import com.appsmith.external.plugins.PluginExecutor;
|
||||||
import com.appsmith.server.constants.FieldName;
|
import com.appsmith.server.constants.FieldName;
|
||||||
import com.appsmith.server.domains.Datasource;
|
import com.appsmith.server.domains.Datasource;
|
||||||
import com.appsmith.server.domains.Plugin;
|
import com.appsmith.server.domains.Plugin;
|
||||||
import com.appsmith.server.exceptions.AppsmithError;
|
import com.appsmith.server.exceptions.AppsmithError;
|
||||||
import com.appsmith.server.exceptions.AppsmithException;
|
import com.appsmith.server.exceptions.AppsmithException;
|
||||||
|
import com.appsmith.server.helpers.PluginExecutorHelper;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mockito;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||||
import org.springframework.security.test.context.support.WithMockUser;
|
import org.springframework.security.test.context.support.WithMockUser;
|
||||||
|
import org.springframework.test.annotation.DirtiesContext;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
import org.springframework.test.context.junit4.SpringRunner;
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
import reactor.test.StepVerifier;
|
import reactor.test.StepVerifier;
|
||||||
|
|
@ -22,6 +30,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
@SpringBootTest
|
@SpringBootTest
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@DirtiesContext
|
||||||
public class DatasourceServiceTest {
|
public class DatasourceServiceTest {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
@ -30,12 +39,43 @@ public class DatasourceServiceTest {
|
||||||
@Autowired
|
@Autowired
|
||||||
PluginService pluginService;
|
PluginService pluginService;
|
||||||
|
|
||||||
|
@MockBean
|
||||||
|
PluginExecutorHelper pluginExecutorHelper;
|
||||||
|
|
||||||
|
class TestPluginExecutor implements PluginExecutor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Mono<ActionExecutionResult> execute(Object connection, DatasourceConfiguration datasourceConfiguration, ActionConfiguration actionConfiguration) {
|
||||||
|
System.out.println("In the execute");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object datasourceCreate(DatasourceConfiguration datasourceConfiguration) {
|
||||||
|
System.out.println("In the datasourceCreate");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void datasourceDestroy(Object connection) {
|
||||||
|
System.out.println("In the datasourceDestroy");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean isDatasourceValid(DatasourceConfiguration datasourceConfiguration) {
|
||||||
|
System.out.println("In the datasourceValidate");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@WithMockUser(username = "api_user")
|
@WithMockUser(username = "api_user", roles = "USER")
|
||||||
public void createDatasourceWithNullPluginId() {
|
public void createDatasourceWithNullPluginId() {
|
||||||
Datasource datasource = new Datasource();
|
Datasource datasource = new Datasource();
|
||||||
Mono<Datasource> datasourceMono = Mono.just(datasource)
|
Mono<Datasource> datasourceMono = Mono.just(datasource)
|
||||||
|
|
@ -48,7 +88,7 @@ public class DatasourceServiceTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@WithMockUser(username = "api_user")
|
@WithMockUser(username = "api_user", roles = "USER")
|
||||||
public void createDatasourceWithId() {
|
public void createDatasourceWithId() {
|
||||||
Datasource datasource = new Datasource();
|
Datasource datasource = new Datasource();
|
||||||
datasource.setId("randomId");
|
datasource.setId("randomId");
|
||||||
|
|
@ -62,12 +102,14 @@ public class DatasourceServiceTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@WithMockUser(username = "api_user")
|
@WithMockUser(username = "api_user", roles = "USER")
|
||||||
public void createDatasourceNotInstalledPlugin() {
|
public void createDatasourceNotInstalledPlugin() {
|
||||||
|
Mockito.when(pluginExecutorHelper.getPluginExecutor(Mockito.any())).thenReturn(Mono.just(new TestPluginExecutor()));
|
||||||
|
|
||||||
Mono<Plugin> pluginMono = pluginService.findByName("Not Installed Plugin Name");
|
Mono<Plugin> pluginMono = pluginService.findByName("Not Installed Plugin Name");
|
||||||
Datasource datasource = new Datasource();
|
Datasource datasource = new Datasource();
|
||||||
DatasourceConfiguration datasourceConfiguration = new DatasourceConfiguration();
|
DatasourceConfiguration datasourceConfiguration = new DatasourceConfiguration();
|
||||||
datasourceConfiguration.setDatabaseName("randomDbname");
|
datasourceConfiguration.setUrl("http://test.com");
|
||||||
datasource.setDatasourceConfiguration(datasourceConfiguration);
|
datasource.setDatasourceConfiguration(datasourceConfiguration);
|
||||||
|
|
||||||
Mono<Datasource> datasourceMono = pluginMono.map(plugin -> {
|
Mono<Datasource> datasourceMono = pluginMono.map(plugin -> {
|
||||||
|
|
@ -83,13 +125,16 @@ public class DatasourceServiceTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@WithMockUser(username = "api_user")
|
@WithMockUser(username = "api_user", roles = "USER")
|
||||||
public void createDatasourceValid() {
|
public void createDatasourceValid() {
|
||||||
|
|
||||||
|
Mockito.when(pluginExecutorHelper.getPluginExecutor(Mockito.any())).thenReturn(Mono.just(new TestPluginExecutor()));
|
||||||
|
|
||||||
Mono<Plugin> pluginMono = pluginService.findByName("Installed Plugin Name");
|
Mono<Plugin> pluginMono = pluginService.findByName("Installed Plugin Name");
|
||||||
Datasource datasource = new Datasource();
|
Datasource datasource = new Datasource();
|
||||||
datasource.setName("test datasource name");
|
datasource.setName("test datasource name");
|
||||||
DatasourceConfiguration datasourceConfiguration = new DatasourceConfiguration();
|
DatasourceConfiguration datasourceConfiguration = new DatasourceConfiguration();
|
||||||
datasourceConfiguration.setDatabaseName("randomDbname");
|
datasourceConfiguration.setUrl("http://test.com");
|
||||||
datasource.setDatasourceConfiguration(datasourceConfiguration);
|
datasource.setDatasourceConfiguration(datasourceConfiguration);
|
||||||
Mono<Datasource> datasourceMono = pluginMono.map(plugin -> {
|
Mono<Datasource> datasourceMono = pluginMono.map(plugin -> {
|
||||||
datasource.setPluginId(plugin.getId());
|
datasource.setPluginId(plugin.getId());
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import org.junit.runner.RunWith;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.security.test.context.support.WithMockUser;
|
import org.springframework.security.test.context.support.WithMockUser;
|
||||||
|
import org.springframework.test.annotation.DirtiesContext;
|
||||||
import org.springframework.test.context.junit4.SpringRunner;
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
import reactor.test.StepVerifier;
|
import reactor.test.StepVerifier;
|
||||||
|
|
@ -26,6 +27,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
@SpringBootTest
|
@SpringBootTest
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@DirtiesContext
|
||||||
public class LayoutServiceTest {
|
public class LayoutServiceTest {
|
||||||
@Autowired
|
@Autowired
|
||||||
LayoutService layoutService;
|
LayoutService layoutService;
|
||||||
|
|
|
||||||
|
|
@ -10,14 +10,17 @@ import org.junit.runner.RunWith;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.security.test.context.support.WithMockUser;
|
import org.springframework.security.test.context.support.WithMockUser;
|
||||||
|
import org.springframework.test.annotation.DirtiesContext;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
import org.springframework.test.context.junit4.SpringRunner;
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
import reactor.test.StepVerifier;
|
import reactor.test.StepVerifier;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
@SpringBootTest
|
@SpringBootTest
|
||||||
|
@DirtiesContext
|
||||||
public class OrganizationServiceTest {
|
public class OrganizationServiceTest {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
||||||
|
|
@ -13,15 +13,18 @@ import org.junit.runner.RunWith;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.security.test.context.support.WithMockUser;
|
import org.springframework.security.test.context.support.WithMockUser;
|
||||||
|
import org.springframework.test.annotation.DirtiesContext;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
import org.springframework.test.context.junit4.SpringRunner;
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
import reactor.test.StepVerifier;
|
import reactor.test.StepVerifier;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
@SpringBootTest
|
@SpringBootTest
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@DirtiesContext
|
||||||
public class PageServiceTest {
|
public class PageServiceTest {
|
||||||
@Autowired
|
@Autowired
|
||||||
PageService pageService;
|
PageService pageService;
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.test.annotation.DirtiesContext;
|
||||||
import org.springframework.test.context.junit4.SpringRunner;
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
import reactor.test.StepVerifier;
|
import reactor.test.StepVerifier;
|
||||||
|
|
@ -17,6 +18,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
@SpringBootTest
|
@SpringBootTest
|
||||||
|
@DirtiesContext
|
||||||
public class UserServiceTest {
|
public class UserServiceTest {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user