diff --git a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/serversetting/service/ServerSettingServiceImpl.java b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/serversetting/service/ServerSettingServiceImpl.java index 8512772fb..64e1847ab 100644 --- a/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/serversetting/service/ServerSettingServiceImpl.java +++ b/server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/serversetting/service/ServerSettingServiceImpl.java @@ -1,21 +1,29 @@ package org.lowcoder.domain.serversetting.service; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.lowcoder.domain.serversetting.model.ServerSetting; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.*; import org.springframework.stereotype.Service; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import javax.annotation.PostConstruct; -import java.util.List; -import java.util.Map; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; +@RequiredArgsConstructor @Slf4j @Service public class ServerSettingServiceImpl implements ServerSettingService { + + private final Environment environment; private final ServerSettingRepository repository; + private final List EXCLUDED_KEYS = List.of("LOWCODER_MONGODB_EXPOSED", "LOWCODER_PUID", "LOWCODER_PGID", @@ -33,11 +41,6 @@ public class ServerSettingServiceImpl implements ServerSettingService { "LOWCODER_NODE_SERVICE_SECRET", "LOWCODER_NODE_SERVICE_SECRET_SALT"); - @Autowired - public ServerSettingServiceImpl(ServerSettingRepository repository) { - this.repository = repository; - } - @Override public Mono> getServerSettingsMap() { return repository.findAll().collectMap(ServerSetting::getKey, ServerSetting::getValue); @@ -45,9 +48,18 @@ public Mono> getServerSettingsMap() { @PostConstruct public void saveEnvironmentVariables() { - Map envVariables = System.getenv(); - Flux.fromIterable(envVariables.keySet()) - .filter(key -> key.startsWith("LOWCODER_")) + + Map defaults = getEnvironmentVariablesDefaults(); + + Map envVariables = new TreeMap<>(System.getenv().entrySet().stream() + .filter(entry -> StringUtils.startsWith(entry.getKey(), "LOWCODER_")) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))); + + Map merged = new TreeMap<>(defaults); + merged.keySet().removeAll(envVariables.keySet()); + merged.putAll(envVariables); + + Flux.fromIterable(merged.keySet()) .map(key -> { String value = envVariables.getOrDefault(key, ""); if(EXCLUDED_KEYS.contains(key)) { @@ -61,4 +73,30 @@ public void saveEnvironmentVariables() { .flatMap(repository::save) .subscribe(); } + + + private Map getEnvironmentVariablesDefaults() { + Map defaults = new HashMap<>(); + + MutablePropertySources propertySources = ((AbstractEnvironment) environment).getPropertySources(); + StreamSupport.stream(propertySources.spliterator(), false) + .filter(EnumerablePropertySource.class::isInstance) + .map(EnumerablePropertySource.class::cast) + .forEach(propertySource -> { + String[] names = propertySource.getPropertyNames(); + if (names.length > 0) { + Arrays.stream(names).forEach(name -> { + String rawValue = Objects.toString(propertySource.getProperty(name), ""); + if (rawValue != null && StringUtils.contains(rawValue, "${LOWCODER_")) { + String defaultValue = StringUtils.substringBetween(rawValue, "${", "}"); + String[] keyValue = StringUtils.split(defaultValue, ":"); + if (keyValue.length == 2 && !defaults.containsKey(keyValue[0])) { + defaults.put(keyValue[0], keyValue[1]); + } + } + }); + } + }); + return defaults; + } }