diff --git a/app/server/src/main/java/com/mobtools/server/constants/Url.java b/app/server/src/main/java/com/mobtools/server/constants/Url.java index ca718f898c..88c6af6116 100644 --- a/app/server/src/main/java/com/mobtools/server/constants/Url.java +++ b/app/server/src/main/java/com/mobtools/server/constants/Url.java @@ -8,4 +8,5 @@ public interface Url { String LAYOUT_URL = BASE_URL + VERSION + "/layouts"; String PLUGIN_URL = BASE_URL + VERSION + "/plugins"; String QUERY_URL = BASE_URL + VERSION + "/queries"; + String SETTING_URL = BASE_URL + VERSION + "/settings"; } diff --git a/app/server/src/main/java/com/mobtools/server/controllers/LayoutController.java b/app/server/src/main/java/com/mobtools/server/controllers/LayoutController.java index 8c25ede547..3f76d6eb33 100644 --- a/app/server/src/main/java/com/mobtools/server/controllers/LayoutController.java +++ b/app/server/src/main/java/com/mobtools/server/controllers/LayoutController.java @@ -9,7 +9,7 @@ import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping(Url.LAYOUT_URL) -public class LayoutController extends BaseController { +public class LayoutController extends BaseController { @Autowired public LayoutController(LayoutService service) { diff --git a/app/server/src/main/java/com/mobtools/server/controllers/SettingController.java b/app/server/src/main/java/com/mobtools/server/controllers/SettingController.java new file mode 100644 index 0000000000..0a86e280d5 --- /dev/null +++ b/app/server/src/main/java/com/mobtools/server/controllers/SettingController.java @@ -0,0 +1,18 @@ +package com.mobtools.server.controllers; + +import com.mobtools.server.constants.Url; +import com.mobtools.server.domains.Setting; +import com.mobtools.server.services.SettingService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping(Url.SETTING_URL) +public class SettingController extends BaseController { + + @Autowired + public SettingController(SettingService settingService) { + super(settingService); + } +} diff --git a/app/server/src/main/java/com/mobtools/server/domains/Setting.java b/app/server/src/main/java/com/mobtools/server/domains/Setting.java new file mode 100644 index 0000000000..af3ff34d22 --- /dev/null +++ b/app/server/src/main/java/com/mobtools/server/domains/Setting.java @@ -0,0 +1,24 @@ +package com.mobtools.server.domains; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; +import org.springframework.data.mongodb.core.index.Indexed; +import org.springframework.data.mongodb.core.mapping.Document; + +@Getter +@Setter +@ToString +@NoArgsConstructor +@Document +public class Setting extends BaseDomain { + + @Indexed(unique = true) + private String key; + + private String defaultValue; + + private Boolean isTenantSetting; + +} diff --git a/app/server/src/main/java/com/mobtools/server/domains/Tenant.java b/app/server/src/main/java/com/mobtools/server/domains/Tenant.java index 180b568ab0..af9cf54c13 100644 --- a/app/server/src/main/java/com/mobtools/server/domains/Tenant.java +++ b/app/server/src/main/java/com/mobtools/server/domains/Tenant.java @@ -6,6 +6,8 @@ import lombok.Setter; import lombok.ToString; import org.springframework.data.mongodb.core.mapping.Document; +import java.util.List; + @Getter @Setter @@ -20,4 +22,6 @@ public class Tenant extends BaseDomain { private String website; + private List tenantSettings; + } diff --git a/app/server/src/main/java/com/mobtools/server/domains/TenantSetting.java b/app/server/src/main/java/com/mobtools/server/domains/TenantSetting.java new file mode 100644 index 0000000000..12c45dcc65 --- /dev/null +++ b/app/server/src/main/java/com/mobtools/server/domains/TenantSetting.java @@ -0,0 +1,25 @@ +package com.mobtools.server.domains; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; +import org.springframework.data.mongodb.core.mapping.DBRef; + + +/* + * Only used to store the settings that are different from the default values already set in setting collection + */ + +@Getter +@Setter +@ToString +@NoArgsConstructor +public class TenantSetting extends BaseDomain { + + @DBRef + private Setting setting; + + private String settingValue; + +} diff --git a/app/server/src/main/java/com/mobtools/server/plugins/PostgresDBPluginExecutor.java b/app/server/src/main/java/com/mobtools/server/plugins/PostgresDBPluginExecutor.java index c37eed775e..365b54f1c3 100644 --- a/app/server/src/main/java/com/mobtools/server/plugins/PostgresDBPluginExecutor.java +++ b/app/server/src/main/java/com/mobtools/server/plugins/PostgresDBPluginExecutor.java @@ -34,8 +34,8 @@ public class PostgresDBPluginExecutor extends PluginExecutor { @Override public Flux execute(Query queryObj, CommandQueryParams params) { - if(conn == null) { - init(); + if (conn == null) { + init(); } ArrayList list = new ArrayList(50); try { @@ -45,9 +45,9 @@ public class PostgresDBPluginExecutor extends PluginExecutor { ResultSet resultSet = statement.executeQuery(queryTemplate); ResultSetMetaData metaData = resultSet.getMetaData(); Integer colCount = metaData.getColumnCount(); - while(resultSet.next()) { + while (resultSet.next()) { HashMap row = new HashMap(colCount); - for(int i = 1; i<=colCount; i++) { + for (int i = 1; i <= colCount; i++) { row.put(metaData.getColumnName(i), resultSet.getObject(i)); } list.add(row); diff --git a/app/server/src/main/java/com/mobtools/server/plugins/RestTemplatePluginExecutor.java b/app/server/src/main/java/com/mobtools/server/plugins/RestTemplatePluginExecutor.java index e31d4b8198..fc3126c900 100644 --- a/app/server/src/main/java/com/mobtools/server/plugins/RestTemplatePluginExecutor.java +++ b/app/server/src/main/java/com/mobtools/server/plugins/RestTemplatePluginExecutor.java @@ -31,8 +31,8 @@ public class RestTemplatePluginExecutor extends PluginExecutor { protected Flux execute(Query query, CommandQueryParams params) { String requestBody = query.getCommandTemplate(); Map propertyMap = query.getProperties() - .stream() - .collect(Collectors.toMap(Property::getKey, prop -> prop)); + .stream() + .collect(Collectors.toMap(Property::getKey, prop -> prop)); String url = propertyMap.get(PROP_URL).getValue(); String httpMethod = propertyMap.get(PROP_HTTP_METHOD).getValue(); @@ -43,7 +43,7 @@ public class RestTemplatePluginExecutor extends PluginExecutor { .build(); WebClient.RequestHeadersSpec request = webClient.method(HttpMethod.resolve(httpMethod)) - .body(BodyInserters.fromObject(requestBody)); + .body(BodyInserters.fromObject(requestBody)); Mono responseMono = request.exchange(); ClientResponse clientResponse = responseMono.block(); @@ -51,14 +51,14 @@ public class RestTemplatePluginExecutor extends PluginExecutor { List contentTypes = clientResponse.headers().header(HttpHeaders.CONTENT_TYPE); Class clazz = String.class; - if(contentTypes != null && contentTypes.size() > 0) { + if (contentTypes != null && contentTypes.size() > 0) { String contentType = contentTypes.get(0); boolean isJson = MediaType.APPLICATION_JSON_UTF8_VALUE.toLowerCase() .equals(contentType.toLowerCase() .replaceAll("\\s", "")) || MediaType.APPLICATION_JSON_VALUE.equals(contentType.toLowerCase()); - if(isJson) { + if (isJson) { clazz = JSONObject.class; } } diff --git a/app/server/src/main/java/com/mobtools/server/repositories/LayoutRepository.java b/app/server/src/main/java/com/mobtools/server/repositories/LayoutRepository.java index 5aa415b3e4..a20e37ef3a 100644 --- a/app/server/src/main/java/com/mobtools/server/repositories/LayoutRepository.java +++ b/app/server/src/main/java/com/mobtools/server/repositories/LayoutRepository.java @@ -4,5 +4,5 @@ import com.mobtools.server.domains.Layout; import org.springframework.stereotype.Repository; @Repository -public interface LayoutRepository extends BaseRepository{ +public interface LayoutRepository extends BaseRepository { } diff --git a/app/server/src/main/java/com/mobtools/server/repositories/SettingRepository.java b/app/server/src/main/java/com/mobtools/server/repositories/SettingRepository.java new file mode 100644 index 0000000000..bedc261d57 --- /dev/null +++ b/app/server/src/main/java/com/mobtools/server/repositories/SettingRepository.java @@ -0,0 +1,11 @@ +package com.mobtools.server.repositories; + +import com.mobtools.server.domains.Setting; +import org.springframework.stereotype.Repository; +import reactor.core.publisher.Mono; + +@Repository +public interface SettingRepository extends BaseRepository { + + Mono findByKey(String key); +} diff --git a/app/server/src/main/java/com/mobtools/server/services/BaseService.java b/app/server/src/main/java/com/mobtools/server/services/BaseService.java index 0ccb36e621..0604c1ad0f 100644 --- a/app/server/src/main/java/com/mobtools/server/services/BaseService.java +++ b/app/server/src/main/java/com/mobtools/server/services/BaseService.java @@ -65,8 +65,8 @@ public abstract class BaseService create(T widget) { - return repository.save(widget); + public Mono create(T object) { + return repository.save(object); } private DBObject getDbObject(Object o) { diff --git a/app/server/src/main/java/com/mobtools/server/services/PluginExecutor.java b/app/server/src/main/java/com/mobtools/server/services/PluginExecutor.java index 45e09fd913..ef5efd0219 100644 --- a/app/server/src/main/java/com/mobtools/server/services/PluginExecutor.java +++ b/app/server/src/main/java/com/mobtools/server/services/PluginExecutor.java @@ -42,7 +42,7 @@ public abstract class PluginExecutor { * This function replaces the variables in the query commandTemplate with the actual params * Executors can override this function to provide their own implementation if they wish to do something custom * - * @param query Query + * @param query Query * @param params CommandQueryParams */ protected Query replaceTemplate(Query query, CommandQueryParams params) { @@ -52,7 +52,7 @@ public abstract class PluginExecutor { Map queryMap = new HashMap<>(); Map headerMap = new HashMap<>(); - if(params.getQueryParams() != null) { + if (params.getQueryParams() != null) { queryMap = params .getQueryParams() .stream() @@ -61,7 +61,7 @@ public abstract class PluginExecutor { // Incase there's a conflict, we pick the older value (oldValue, newValue) -> oldValue)); } - if(params.getHeaderParams() != null) { + if (params.getHeaderParams() != null) { headerMap = params .getHeaderParams() .stream() diff --git a/app/server/src/main/java/com/mobtools/server/services/PluginService.java b/app/server/src/main/java/com/mobtools/server/services/PluginService.java index 630322c88f..2f4b12ae55 100644 --- a/app/server/src/main/java/com/mobtools/server/services/PluginService.java +++ b/app/server/src/main/java/com/mobtools/server/services/PluginService.java @@ -8,6 +8,7 @@ public interface PluginService extends CrudService { /** * Return an instance of PluginExecutor based on the classname available. * If the classname is not available, null is returned. + * * @param pluginType * @param className * @return PluginExecutor diff --git a/app/server/src/main/java/com/mobtools/server/services/SettingService.java b/app/server/src/main/java/com/mobtools/server/services/SettingService.java new file mode 100644 index 0000000000..b7575e9b60 --- /dev/null +++ b/app/server/src/main/java/com/mobtools/server/services/SettingService.java @@ -0,0 +1,9 @@ +package com.mobtools.server.services; + +import com.mobtools.server.domains.Setting; +import reactor.core.publisher.Mono; + +public interface SettingService extends CrudService { + + Mono getByKey(String key); +} diff --git a/app/server/src/main/java/com/mobtools/server/services/SettingServiceImpl.java b/app/server/src/main/java/com/mobtools/server/services/SettingServiceImpl.java new file mode 100644 index 0000000000..a06e2f27e3 --- /dev/null +++ b/app/server/src/main/java/com/mobtools/server/services/SettingServiceImpl.java @@ -0,0 +1,30 @@ +package com.mobtools.server.services; + +import com.mobtools.server.domains.Setting; +import com.mobtools.server.repositories.SettingRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.core.ReactiveMongoTemplate; +import org.springframework.data.mongodb.core.convert.MongoConverter; +import org.springframework.stereotype.Service; +import reactor.core.publisher.Mono; +import reactor.core.scheduler.Scheduler; + +@Service +public class SettingServiceImpl extends BaseService implements SettingService { + + private final SettingRepository repository; + + @Autowired + public SettingServiceImpl(Scheduler scheduler, + MongoConverter mongoConverter, + ReactiveMongoTemplate reactiveMongoTemplate, + SettingRepository repository) { + super(scheduler, mongoConverter, reactiveMongoTemplate, repository); + this.repository = repository; + } + + @Override + public Mono getByKey(String key) { + return repository.findByKey(key); + } +} diff --git a/app/server/src/main/java/com/mobtools/server/services/TenantService.java b/app/server/src/main/java/com/mobtools/server/services/TenantService.java index ebeeb80d04..e902941cc1 100644 --- a/app/server/src/main/java/com/mobtools/server/services/TenantService.java +++ b/app/server/src/main/java/com/mobtools/server/services/TenantService.java @@ -6,4 +6,6 @@ import reactor.core.publisher.Mono; public interface TenantService extends CrudService { Mono getByName(String name); + + Mono create(Tenant object); } diff --git a/app/server/src/main/java/com/mobtools/server/services/TenantServiceImpl.java b/app/server/src/main/java/com/mobtools/server/services/TenantServiceImpl.java index 5978e85eef..17589e91cd 100644 --- a/app/server/src/main/java/com/mobtools/server/services/TenantServiceImpl.java +++ b/app/server/src/main/java/com/mobtools/server/services/TenantServiceImpl.java @@ -1,30 +1,67 @@ package com.mobtools.server.services; +import com.mobtools.server.domains.Setting; import com.mobtools.server.domains.Tenant; +import com.mobtools.server.domains.TenantSetting; import com.mobtools.server.repositories.TenantRepository; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.ReactiveMongoTemplate; import org.springframework.data.mongodb.core.convert.MongoConverter; import org.springframework.stereotype.Service; +import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.core.scheduler.Scheduler; +import javax.validation.constraints.NotNull; +import java.util.stream.Stream; + +@Slf4j @Service public class TenantServiceImpl extends BaseService implements TenantService { private final TenantRepository repository; + private final SettingService settingService; @Autowired public TenantServiceImpl(Scheduler scheduler, MongoConverter mongoConverter, ReactiveMongoTemplate reactiveMongoTemplate, - TenantRepository repository) { + TenantRepository repository, + SettingService settingService) { super(scheduler, mongoConverter, reactiveMongoTemplate, repository); this.repository = repository; + this.settingService = settingService; } @Override public Mono getByName(String name) { return repository.findByName(name); } + + @Override + public Mono create(@NotNull Tenant tenant) { + + //Embed the setting object into tenantSetting. This is done only for settings for which the values deviate from the default. + //It is assumed that the tenant create API body would only contain the settings for which the default value and + //true value are different. + if (tenant.getTenantSettings() != null) { + + try (Stream stream = tenant.getTenantSettings().stream()) { + Flux tenantSettingFlux = Flux.fromStream(stream); + tenantSettingFlux.map(this::getAndStoreSettingObjectInTenantSetting).subscribe(); + } + } + + return repository.save(tenant); + + } + + private Object getAndStoreSettingObjectInTenantSetting(TenantSetting tenantSetting) { + String key = tenantSetting.getSetting().getKey(); + Mono setting = settingService.getByKey(key); + return setting.doOnNext(set -> tenantSetting.setSetting(set)) + .thenReturn(tenantSetting) + .subscribe(); + } }