commit
0808091c99
|
@ -206,6 +206,11 @@
|
||||||
<artifactId>thymeleaf-spring5</artifactId>
|
<artifactId>thymeleaf-spring5</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.yaml</groupId>
|
||||||
|
<artifactId>snakeyaml</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>nz.net.ultraq.thymeleaf</groupId>
|
<groupId>nz.net.ultraq.thymeleaf</groupId>
|
||||||
<artifactId>thymeleaf-layout-dialect</artifactId>
|
<artifactId>thymeleaf-layout-dialect</artifactId>
|
||||||
|
|
|
@ -19,18 +19,23 @@ package org.springframework.boot.devtools.env;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.devtools.system.DevToolsEnablementDeducer;
|
import org.springframework.boot.devtools.system.DevToolsEnablementDeducer;
|
||||||
import org.springframework.boot.env.EnvironmentPostProcessor;
|
import org.springframework.boot.env.EnvironmentPostProcessor;
|
||||||
|
import org.springframework.boot.env.PropertiesPropertySourceLoader;
|
||||||
|
import org.springframework.boot.env.PropertySourceLoader;
|
||||||
|
import org.springframework.boot.env.YamlPropertySourceLoader;
|
||||||
import org.springframework.core.env.ConfigurableEnvironment;
|
import org.springframework.core.env.ConfigurableEnvironment;
|
||||||
import org.springframework.core.env.PropertiesPropertySource;
|
|
||||||
import org.springframework.core.env.PropertySource;
|
import org.springframework.core.env.PropertySource;
|
||||||
import org.springframework.core.io.FileSystemResource;
|
import org.springframework.core.io.FileSystemResource;
|
||||||
import org.springframework.core.io.support.PropertiesLoaderUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -52,6 +57,17 @@ public class DevToolsHomePropertiesPostProcessor implements EnvironmentPostProce
|
||||||
|
|
||||||
private static final String CONFIG_PATH = "/.config/spring-boot/";
|
private static final String CONFIG_PATH = "/.config/spring-boot/";
|
||||||
|
|
||||||
|
private static final Set<PropertySourceLoader> PROPERTY_SOURCE_LOADERS;
|
||||||
|
|
||||||
|
static {
|
||||||
|
Set<PropertySourceLoader> propertySourceLoaders = new HashSet<>();
|
||||||
|
propertySourceLoaders.add(new PropertiesPropertySourceLoader());
|
||||||
|
if (ClassUtils.isPresent("org.yaml.snakeyaml.Yaml", null)) {
|
||||||
|
propertySourceLoaders.add(new YamlPropertySourceLoader());
|
||||||
|
}
|
||||||
|
PROPERTY_SOURCE_LOADERS = Collections.unmodifiableSet(propertySourceLoaders);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
|
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
|
||||||
if (DevToolsEnablementDeducer.shouldEnable(Thread.currentThread())) {
|
if (DevToolsEnablementDeducer.shouldEnable(Thread.currentThread())) {
|
||||||
|
@ -88,15 +104,23 @@ public class DevToolsHomePropertiesPostProcessor implements EnvironmentPostProce
|
||||||
private void addPropertySource(List<PropertySource<?>> propertySources, FileSystemResource resource,
|
private void addPropertySource(List<PropertySource<?>> propertySources, FileSystemResource resource,
|
||||||
Function<File, String> propertySourceNamer) {
|
Function<File, String> propertySourceNamer) {
|
||||||
try {
|
try {
|
||||||
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
|
|
||||||
String name = propertySourceNamer.apply(resource.getFile());
|
String name = propertySourceNamer.apply(resource.getFile());
|
||||||
propertySources.add(new PropertiesPropertySource(name, properties));
|
for (PropertySourceLoader loader : PROPERTY_SOURCE_LOADERS) {
|
||||||
|
if (canLoadFileExtension(loader, resource.getFilename())) {
|
||||||
|
propertySources.addAll(loader.load(name, resource));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (IOException ex) {
|
catch (IOException ex) {
|
||||||
throw new IllegalStateException("Unable to load " + resource.getFilename(), ex);
|
throw new IllegalStateException("Unable to load " + resource.getFilename(), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean canLoadFileExtension(PropertySourceLoader loader, String name) {
|
||||||
|
return Arrays.stream(loader.getFileExtensions())
|
||||||
|
.anyMatch((fileExtension) -> StringUtils.endsWithIgnoreCase(name, fileExtension));
|
||||||
|
}
|
||||||
|
|
||||||
protected File getHomeFolder() {
|
protected File getHomeFolder() {
|
||||||
String home = System.getProperty("user.home");
|
String home = System.getProperty("user.home");
|
||||||
if (StringUtils.hasLength(home)) {
|
if (StringUtils.hasLength(home)) {
|
||||||
|
|
|
@ -20,6 +20,7 @@ import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
@ -27,6 +28,7 @@ import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.io.TempDir;
|
import org.junit.jupiter.api.io.TempDir;
|
||||||
|
|
||||||
import org.springframework.core.env.ConfigurableEnvironment;
|
import org.springframework.core.env.ConfigurableEnvironment;
|
||||||
|
import org.springframework.core.io.ClassPathResource;
|
||||||
import org.springframework.mock.env.MockEnvironment;
|
import org.springframework.mock.env.MockEnvironment;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
@ -74,42 +76,41 @@ class DevToolsHomePropertiesPostProcessorTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void loadsPropertiesFromConfigFolderUsingYml() throws Exception {
|
void loadsPropertiesFromConfigFolderUsingYml() throws Exception {
|
||||||
Properties properties = new Properties();
|
|
||||||
properties.put("abc", "def");
|
|
||||||
OutputStream out = new FileOutputStream(new File(this.configDir, "spring-boot-devtools.yml"));
|
OutputStream out = new FileOutputStream(new File(this.configDir, "spring-boot-devtools.yml"));
|
||||||
properties.store(out, null);
|
File file = new ClassPathResource("spring-devtools.yaml", getClass()).getFile();
|
||||||
|
byte[] content = Files.readAllBytes(file.toPath());
|
||||||
|
out.write(content);
|
||||||
out.close();
|
out.close();
|
||||||
ConfigurableEnvironment environment = getPostProcessedEnvironment();
|
ConfigurableEnvironment environment = getPostProcessedEnvironment();
|
||||||
assertThat(environment.getProperty("abc")).isEqualTo("def");
|
assertThat(environment.getProperty("abc.xyz")).isEqualTo("def");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void loadsPropertiesFromConfigFolderUsingYaml() throws Exception {
|
void loadsPropertiesFromConfigFolderUsingYaml() throws Exception {
|
||||||
Properties properties = new Properties();
|
|
||||||
properties.put("abc", "def");
|
|
||||||
OutputStream out = new FileOutputStream(new File(this.configDir, "spring-boot-devtools.yaml"));
|
OutputStream out = new FileOutputStream(new File(this.configDir, "spring-boot-devtools.yaml"));
|
||||||
properties.store(out, null);
|
File file = new ClassPathResource("spring-devtools.yaml", getClass()).getFile();
|
||||||
|
byte[] content = Files.readAllBytes(file.toPath());
|
||||||
|
out.write(content);
|
||||||
out.close();
|
out.close();
|
||||||
ConfigurableEnvironment environment = getPostProcessedEnvironment();
|
ConfigurableEnvironment environment = getPostProcessedEnvironment();
|
||||||
assertThat(environment.getProperty("abc")).isEqualTo("def");
|
assertThat(environment.getProperty("abc.xyz")).isEqualTo("def");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void loadFromConfigFolderWithPropertiesTakingPrecedence() throws Exception {
|
void loadFromConfigFolderWithPropertiesTakingPrecedence() throws Exception {
|
||||||
Properties properties = new Properties();
|
|
||||||
properties.put("abc", "def");
|
|
||||||
properties.put("bar", "baz");
|
|
||||||
OutputStream out = new FileOutputStream(new File(this.configDir, "spring-boot-devtools.yaml"));
|
OutputStream out = new FileOutputStream(new File(this.configDir, "spring-boot-devtools.yaml"));
|
||||||
properties.store(out, null);
|
File file = new ClassPathResource("spring-devtools.yaml", getClass()).getFile();
|
||||||
|
byte[] content = Files.readAllBytes(file.toPath());
|
||||||
|
out.write(content);
|
||||||
out.close();
|
out.close();
|
||||||
Properties properties2 = new Properties();
|
Properties properties2 = new Properties();
|
||||||
properties2.put("abc", "jkl");
|
properties2.put("abc.xyz", "jkl");
|
||||||
OutputStream out2 = new FileOutputStream(new File(this.configDir, "spring-boot-devtools.properties"));
|
OutputStream out2 = new FileOutputStream(new File(this.configDir, "spring-boot-devtools.properties"));
|
||||||
properties2.store(out2, null);
|
properties2.store(out2, null);
|
||||||
out2.close();
|
out2.close();
|
||||||
ConfigurableEnvironment environment = getPostProcessedEnvironment();
|
ConfigurableEnvironment environment = getPostProcessedEnvironment();
|
||||||
assertThat(environment.getProperty("abc")).isEqualTo("jkl");
|
assertThat(environment.getProperty("abc.xyz")).isEqualTo("jkl");
|
||||||
assertThat(environment.getProperty("bar")).isEqualTo("baz");
|
assertThat(environment.getProperty("bing")).isEqualTo("blip");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -131,16 +132,16 @@ class DevToolsHomePropertiesPostProcessorTests {
|
||||||
@Test
|
@Test
|
||||||
void loadFromConfigFolderWithYamlTakesPrecedenceOverHomeFolder() throws Exception {
|
void loadFromConfigFolderWithYamlTakesPrecedenceOverHomeFolder() throws Exception {
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
properties.put("abc", "def");
|
properties.put("abc.xyz", "jkl");
|
||||||
properties.put("bar", "baz");
|
properties.put("bar", "baz");
|
||||||
writeFile(properties, ".spring-boot-devtools.properties");
|
writeFile(properties, ".spring-boot-devtools.properties");
|
||||||
Properties properties2 = new Properties();
|
|
||||||
properties2.put("abc", "jkl");
|
|
||||||
OutputStream out2 = new FileOutputStream(new File(this.configDir, "spring-boot-devtools.yml"));
|
OutputStream out2 = new FileOutputStream(new File(this.configDir, "spring-boot-devtools.yml"));
|
||||||
properties2.store(out2, null);
|
File file = new ClassPathResource("spring-devtools.yaml", getClass()).getFile();
|
||||||
|
byte[] content = Files.readAllBytes(file.toPath());
|
||||||
|
out2.write(content);
|
||||||
out2.close();
|
out2.close();
|
||||||
ConfigurableEnvironment environment = getPostProcessedEnvironment();
|
ConfigurableEnvironment environment = getPostProcessedEnvironment();
|
||||||
assertThat(environment.getProperty("abc")).isEqualTo("jkl");
|
assertThat(environment.getProperty("abc.xyz")).isEqualTo("def");
|
||||||
assertThat(environment.getProperty("bar")).isEqualTo(null);
|
assertThat(environment.getProperty("bar")).isEqualTo(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
abc:
|
||||||
|
xyz: def
|
||||||
|
bing: blip
|
Loading…
Reference in New Issue