Polish `EnvConfigData`
Rename classes to align with existing `SystemEnvironment...` classes and extract common `FileExtensionHint` logic. See gh-41609
This commit is contained in:
parent
aaaeb1ec12
commit
e207e7ca83
|
@ -116,7 +116,7 @@ public class ConfigDataResourceNotFoundException extends ConfigDataNotFoundExcep
|
|||
* @param pathToCheck the path to check
|
||||
*/
|
||||
public static void throwIfDoesNotExist(ConfigDataResource resource, Path pathToCheck) {
|
||||
throwIfDoesNotExist(resource, Files.exists(pathToCheck));
|
||||
throwIfNot(resource, Files.exists(pathToCheck));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -126,7 +126,7 @@ public class ConfigDataResourceNotFoundException extends ConfigDataNotFoundExcep
|
|||
* @param fileToCheck the file to check
|
||||
*/
|
||||
public static void throwIfDoesNotExist(ConfigDataResource resource, File fileToCheck) {
|
||||
throwIfDoesNotExist(resource, fileToCheck.exists());
|
||||
throwIfNot(resource, fileToCheck.exists());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -136,11 +136,11 @@ public class ConfigDataResourceNotFoundException extends ConfigDataNotFoundExcep
|
|||
* @param resourceToCheck the resource to check
|
||||
*/
|
||||
public static void throwIfDoesNotExist(ConfigDataResource resource, Resource resourceToCheck) {
|
||||
throwIfDoesNotExist(resource, resourceToCheck.exists());
|
||||
throwIfNot(resource, resourceToCheck.exists());
|
||||
}
|
||||
|
||||
private static void throwIfDoesNotExist(ConfigDataResource resource, boolean exists) {
|
||||
if (!exists) {
|
||||
private static void throwIfNot(ConfigDataResource resource, boolean check) {
|
||||
if (!check) {
|
||||
throw new ConfigDataResourceNotFoundException(resource);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.context.config;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
|
||||
/**
|
||||
* {@link ConfigDataLoader} to load data from environment variables.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
class EnvConfigDataLoader implements ConfigDataLoader<EnvConfigDataResource> {
|
||||
|
||||
private final Function<String, String> readEnvVariable;
|
||||
|
||||
EnvConfigDataLoader() {
|
||||
this.readEnvVariable = System::getenv;
|
||||
}
|
||||
|
||||
EnvConfigDataLoader(Function<String, String> readEnvVariable) {
|
||||
this.readEnvVariable = readEnvVariable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigData load(ConfigDataLoaderContext context, EnvConfigDataResource resource)
|
||||
throws IOException, ConfigDataResourceNotFoundException {
|
||||
String content = this.readEnvVariable.apply(resource.getVariableName());
|
||||
if (content == null) {
|
||||
throw new ConfigDataResourceNotFoundException(resource);
|
||||
}
|
||||
String name = String.format("Environment variable '%s' via location '%s'", resource.getVariableName(),
|
||||
resource.getLocation());
|
||||
return new ConfigData(resource.getLoader().load(name, createResource(content)));
|
||||
}
|
||||
|
||||
private ByteArrayResource createResource(String content) {
|
||||
return new ByteArrayResource(content.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.context.config;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.springframework.boot.env.PropertySourceLoader;
|
||||
|
||||
/**
|
||||
* {@link ConfigDataResource} used by {@link EnvConfigDataLoader}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
class EnvConfigDataResource extends ConfigDataResource {
|
||||
|
||||
private final ConfigDataLocation location;
|
||||
|
||||
private final String variableName;
|
||||
|
||||
private final PropertySourceLoader loader;
|
||||
|
||||
EnvConfigDataResource(ConfigDataLocation location, String variableName, PropertySourceLoader loader) {
|
||||
super(location.isOptional());
|
||||
this.location = location;
|
||||
this.variableName = variableName;
|
||||
this.loader = loader;
|
||||
}
|
||||
|
||||
ConfigDataLocation getLocation() {
|
||||
return this.location;
|
||||
}
|
||||
|
||||
String getVariableName() {
|
||||
return this.variableName;
|
||||
}
|
||||
|
||||
PropertySourceLoader getLoader() {
|
||||
return this.loader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
EnvConfigDataResource that = (EnvConfigDataResource) o;
|
||||
return Objects.equals(this.location, that.location) && Objects.equals(this.variableName, that.variableName)
|
||||
&& Objects.equals(this.loader, that.loader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.location, this.variableName, this.loader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "env variable [" + this.variableName + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.context.config;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* User provided hint for an otherwise missing file extension.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
final class FileExtensionHint {
|
||||
|
||||
private static final Pattern PATTERN = Pattern.compile("^(.*)\\[(\\.\\w+)](?!\\[)$");
|
||||
|
||||
private static final FileExtensionHint NONE = new FileExtensionHint(null);
|
||||
|
||||
private final Matcher matcher;
|
||||
|
||||
private FileExtensionHint(Matcher matcher) {
|
||||
this.matcher = matcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code true} if the hint is present.
|
||||
* @return if the hint is present
|
||||
*/
|
||||
boolean isPresent() {
|
||||
return this.matcher != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the extension from the hint or return the parameter if the hint is not
|
||||
* {@link #isPresent() present}.
|
||||
* @param extension the fallback extension
|
||||
* @return the extension either from the hint or fallback
|
||||
*/
|
||||
String orElse(String extension) {
|
||||
return (this.matcher != null) ? toString() : extension;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return (this.matcher != null) ? this.matcher.group(2) : "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@link FileExtensionHint} from the given value.
|
||||
* @param value the source value
|
||||
* @return the {@link FileExtensionHint} (never {@code null})
|
||||
*/
|
||||
static FileExtensionHint from(String value) {
|
||||
Matcher matcher = PATTERN.matcher(value);
|
||||
return (matcher.matches()) ? new FileExtensionHint(matcher) : NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove any hint from the given value.
|
||||
* @param value the source value
|
||||
* @return the value without any hint
|
||||
*/
|
||||
static String removeFrom(String value) {
|
||||
Matcher matcher = PATTERN.matcher(value);
|
||||
return (matcher.matches()) ? matcher.group(1) : value;
|
||||
}
|
||||
|
||||
}
|
|
@ -26,7 +26,6 @@ import java.util.Deque;
|
|||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -68,8 +67,6 @@ public class StandardConfigDataLocationResolver
|
|||
|
||||
private static final Pattern URL_PREFIX = Pattern.compile("^([a-zA-Z][a-zA-Z0-9*]*?:)(.*$)");
|
||||
|
||||
private static final Pattern EXTENSION_HINT_PATTERN = Pattern.compile("^(.*)\\[(\\.\\w+)](?!\\[)$");
|
||||
|
||||
private static final String NO_PROFILE = null;
|
||||
|
||||
private final Log logger;
|
||||
|
@ -238,17 +235,16 @@ public class StandardConfigDataLocationResolver
|
|||
|
||||
private Set<StandardConfigDataReference> getReferencesForFile(ConfigDataLocation configDataLocation, String file,
|
||||
String profile) {
|
||||
Matcher extensionHintMatcher = EXTENSION_HINT_PATTERN.matcher(file);
|
||||
boolean extensionHintLocation = extensionHintMatcher.matches();
|
||||
if (extensionHintLocation) {
|
||||
file = extensionHintMatcher.group(1) + extensionHintMatcher.group(2);
|
||||
FileExtensionHint fileExtensionHint = FileExtensionHint.from(file);
|
||||
if (fileExtensionHint.isPresent()) {
|
||||
file = FileExtensionHint.removeFrom(file) + fileExtensionHint;
|
||||
}
|
||||
for (PropertySourceLoader propertySourceLoader : this.propertySourceLoaders) {
|
||||
String extension = getLoadableFileExtension(propertySourceLoader, file);
|
||||
if (extension != null) {
|
||||
String root = file.substring(0, file.length() - extension.length() - 1);
|
||||
String fileExtension = getLoadableFileExtension(propertySourceLoader, file);
|
||||
if (fileExtension != null) {
|
||||
String root = file.substring(0, file.length() - fileExtension.length() - 1);
|
||||
StandardConfigDataReference reference = new StandardConfigDataReference(configDataLocation, null, root,
|
||||
profile, (!extensionHintLocation) ? extension : null, propertySourceLoader);
|
||||
profile, (!fileExtensionHint.isPresent()) ? fileExtension : null, propertySourceLoader);
|
||||
return Collections.singleton(reference);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.context.config;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.core.env.PropertySource;
|
||||
|
||||
/**
|
||||
* {@link ConfigDataLoader} to load data from system environment variables.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
class SystemEnvironmentConfigDataLoader implements ConfigDataLoader<SystemEnvironmentConfigDataResource> {
|
||||
|
||||
@Override
|
||||
public ConfigData load(ConfigDataLoaderContext context, SystemEnvironmentConfigDataResource resource)
|
||||
throws IOException, ConfigDataResourceNotFoundException {
|
||||
List<PropertySource<?>> loaded = resource.load();
|
||||
if (loaded == null) {
|
||||
throw new ConfigDataResourceNotFoundException(resource);
|
||||
}
|
||||
return new ConfigData(loaded);
|
||||
}
|
||||
|
||||
}
|
|
@ -19,8 +19,6 @@ package org.springframework.boot.context.config;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.springframework.boot.env.PropertySourceLoader;
|
||||
import org.springframework.core.io.support.SpringFactoriesLoader;
|
||||
|
@ -29,27 +27,28 @@ import org.springframework.core.io.support.SpringFactoriesLoader;
|
|||
* {@link ConfigDataLocationResolver} to resolve {@code env:} locations.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class EnvConfigDataLocationResolver implements ConfigDataLocationResolver<EnvConfigDataResource> {
|
||||
class SystemEnvironmentConfigDataLocationResolver
|
||||
implements ConfigDataLocationResolver<SystemEnvironmentConfigDataResource> {
|
||||
|
||||
private static final String PREFIX = "env:";
|
||||
|
||||
private static final Pattern EXTENSION_HINT_PATTERN = Pattern.compile("^(.*)\\[(\\.\\w+)](?!\\[)$");
|
||||
|
||||
private static final String DEFAULT_EXTENSION = ".properties";
|
||||
|
||||
private final List<PropertySourceLoader> loaders;
|
||||
|
||||
private final Function<String, String> readEnvVariable;
|
||||
private final Function<String, String> environment;
|
||||
|
||||
EnvConfigDataLocationResolver() {
|
||||
SystemEnvironmentConfigDataLocationResolver() {
|
||||
this.loaders = SpringFactoriesLoader.loadFactories(PropertySourceLoader.class, getClass().getClassLoader());
|
||||
this.readEnvVariable = System::getenv;
|
||||
this.environment = System::getenv;
|
||||
}
|
||||
|
||||
EnvConfigDataLocationResolver(List<PropertySourceLoader> loaders, Function<String, String> readEnvVariable) {
|
||||
SystemEnvironmentConfigDataLocationResolver(List<PropertySourceLoader> loaders,
|
||||
Function<String, String> environment) {
|
||||
this.loaders = loaders;
|
||||
this.readEnvVariable = readEnvVariable;
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -58,15 +57,15 @@ class EnvConfigDataLocationResolver implements ConfigDataLocationResolver<EnvCon
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<EnvConfigDataResource> resolve(ConfigDataLocationResolverContext context, ConfigDataLocation location)
|
||||
public List<SystemEnvironmentConfigDataResource> resolve(ConfigDataLocationResolverContext context,
|
||||
ConfigDataLocation location)
|
||||
throws ConfigDataLocationNotFoundException, ConfigDataResourceNotFoundException {
|
||||
String value = location.getNonPrefixedValue(PREFIX);
|
||||
Matcher matcher = EXTENSION_HINT_PATTERN.matcher(value);
|
||||
String extension = getExtension(matcher);
|
||||
String variableName = getVariableName(matcher, value);
|
||||
PropertySourceLoader loader = getLoader(extension);
|
||||
FileExtensionHint fileExtensionHint = FileExtensionHint.from(value);
|
||||
String variableName = FileExtensionHint.removeFrom(value);
|
||||
PropertySourceLoader loader = getLoader(fileExtensionHint.orElse(DEFAULT_EXTENSION));
|
||||
if (hasEnvVariable(variableName)) {
|
||||
return List.of(new EnvConfigDataResource(location, variableName, loader));
|
||||
return List.of(new SystemEnvironmentConfigDataResource(variableName, loader, this.environment));
|
||||
}
|
||||
if (location.isOptional()) {
|
||||
return Collections.emptyList();
|
||||
|
@ -76,12 +75,7 @@ class EnvConfigDataLocationResolver implements ConfigDataLocationResolver<EnvCon
|
|||
}
|
||||
|
||||
private PropertySourceLoader getLoader(String extension) {
|
||||
if (extension == null) {
|
||||
extension = DEFAULT_EXTENSION;
|
||||
}
|
||||
if (extension.startsWith(".")) {
|
||||
extension = extension.substring(1);
|
||||
}
|
||||
extension = (!extension.startsWith(".")) ? extension : extension.substring(1);
|
||||
for (PropertySourceLoader loader : this.loaders) {
|
||||
for (String supportedExtension : loader.getFileExtensions()) {
|
||||
if (supportedExtension.equalsIgnoreCase(extension)) {
|
||||
|
@ -94,21 +88,7 @@ class EnvConfigDataLocationResolver implements ConfigDataLocationResolver<EnvCon
|
|||
}
|
||||
|
||||
private boolean hasEnvVariable(String variableName) {
|
||||
return this.readEnvVariable.apply(variableName) != null;
|
||||
}
|
||||
|
||||
private String getVariableName(Matcher matcher, String value) {
|
||||
if (matcher.matches()) {
|
||||
return matcher.group(1);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private String getExtension(Matcher matcher) {
|
||||
if (matcher.matches()) {
|
||||
return matcher.group(2);
|
||||
}
|
||||
return null;
|
||||
return this.environment.apply(variableName) != null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.context.config;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.springframework.boot.env.PropertySourceLoader;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@link ConfigDataResource} used by {@link SystemEnvironmentConfigDataLoader}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
class SystemEnvironmentConfigDataResource extends ConfigDataResource {
|
||||
|
||||
private final String variableName;
|
||||
|
||||
private final PropertySourceLoader loader;
|
||||
|
||||
private final Function<String, String> environment;
|
||||
|
||||
SystemEnvironmentConfigDataResource(String variableName, PropertySourceLoader loader,
|
||||
Function<String, String> environment) {
|
||||
this.variableName = variableName;
|
||||
this.loader = loader;
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
String getVariableName() {
|
||||
return this.variableName;
|
||||
}
|
||||
|
||||
PropertySourceLoader getLoader() {
|
||||
return this.loader;
|
||||
}
|
||||
|
||||
List<PropertySource<?>> load() throws IOException {
|
||||
String content = this.environment.apply(this.variableName);
|
||||
return (content != null) ? this.loader.load(StringUtils.capitalize(toString()), asResource(content)) : null;
|
||||
}
|
||||
|
||||
private ByteArrayResource asResource(String content) {
|
||||
return new ByteArrayResource(content.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null || getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
SystemEnvironmentConfigDataResource other = (SystemEnvironmentConfigDataResource) obj;
|
||||
return Objects.equals(this.loader.getClass(), other.loader.getClass())
|
||||
&& Objects.equals(this.variableName, other.variableName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.variableName, this.loader.getClass());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "system envionement variable [" + this.variableName + "] content loaded using "
|
||||
+ ClassUtils.getShortName(this.loader.getClass());
|
||||
}
|
||||
|
||||
}
|
|
@ -12,14 +12,14 @@ org.springframework.boot.env.YamlPropertySourceLoader
|
|||
# ConfigData Location Resolvers
|
||||
org.springframework.boot.context.config.ConfigDataLocationResolver=\
|
||||
org.springframework.boot.context.config.ConfigTreeConfigDataLocationResolver,\
|
||||
org.springframework.boot.context.config.EnvConfigDataLocationResolver,\
|
||||
org.springframework.boot.context.config.StandardConfigDataLocationResolver
|
||||
org.springframework.boot.context.config.StandardConfigDataLocationResolver,\
|
||||
org.springframework.boot.context.config.SystemEnvironmentConfigDataLocationResolver
|
||||
|
||||
# ConfigData Loaders
|
||||
org.springframework.boot.context.config.ConfigDataLoader=\
|
||||
org.springframework.boot.context.config.ConfigTreeConfigDataLoader,\
|
||||
org.springframework.boot.context.config.EnvConfigDataLoader,\
|
||||
org.springframework.boot.context.config.StandardConfigDataLoader
|
||||
org.springframework.boot.context.config.StandardConfigDataLoader,\
|
||||
org.springframework.boot.context.config.SystemEnvironmentConfigDataLoader
|
||||
|
||||
# Application Context Factories
|
||||
org.springframework.boot.ApplicationContextFactory=\
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.context.config;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.env.PropertiesPropertySourceLoader;
|
||||
import org.springframework.boot.env.PropertySourceLoader;
|
||||
import org.springframework.boot.env.YamlPropertySourceLoader;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link EnvConfigDataResource}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
class EnvConfigDataResourceTests {
|
||||
|
||||
private final YamlPropertySourceLoader yamlPropertySourceLoader = new YamlPropertySourceLoader();
|
||||
|
||||
private final PropertiesPropertySourceLoader propertiesPropertySourceLoader = new PropertiesPropertySourceLoader();
|
||||
|
||||
@Test
|
||||
void shouldHaveEqualsAndHashcode() {
|
||||
EnvConfigDataResource var1 = createResource("VAR1");
|
||||
EnvConfigDataResource var2 = createResource("VAR2");
|
||||
EnvConfigDataResource var3 = createResource("VAR1", this.yamlPropertySourceLoader);
|
||||
EnvConfigDataResource var4 = createResource("VAR1");
|
||||
assertThat(var1).isNotEqualTo(var2);
|
||||
assertThat(var1).isNotEqualTo(var3);
|
||||
assertThat(var1).isEqualTo(var4);
|
||||
assertThat(var1).hasSameHashCodeAs(var4);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldHaveToString() {
|
||||
EnvConfigDataResource resource = createResource("VAR1");
|
||||
assertThat(resource).hasToString("env variable [VAR1]");
|
||||
}
|
||||
|
||||
private EnvConfigDataResource createResource(String variableName) {
|
||||
return createResource(variableName, this.propertiesPropertySourceLoader);
|
||||
}
|
||||
|
||||
private EnvConfigDataResource createResource(String variableName, PropertySourceLoader propertySourceLoader) {
|
||||
return new EnvConfigDataResource(ConfigDataLocation.of("env:" + variableName), variableName,
|
||||
propertySourceLoader);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.context.config;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link FileExtensionHint}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class FileExtensionHintTests {
|
||||
|
||||
@Test
|
||||
void isPresentWhenHasHint() {
|
||||
assertThat(FileExtensionHint.from("foo[.bar]").isPresent()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isPresentWhenHasNoHint() {
|
||||
assertThat(FileExtensionHint.from("foo").isPresent()).isFalse();
|
||||
assertThat(FileExtensionHint.from("foo[bar]").isPresent()).isFalse();
|
||||
assertThat(FileExtensionHint.from("foo[.b[ar]").isPresent()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void orElseWhenHasHint() {
|
||||
assertThat(FileExtensionHint.from("foo[.bar]").orElse(".txt")).isEqualTo(".bar");
|
||||
}
|
||||
|
||||
@Test
|
||||
void orElseWhenHasNoHint() {
|
||||
assertThat(FileExtensionHint.from("foo").orElse(".txt")).isEqualTo(".txt");
|
||||
}
|
||||
|
||||
@Test
|
||||
void toStringWhenHasHintReturnsDotExtension() {
|
||||
assertThat(FileExtensionHint.from("foo[.bar]")).hasToString(".bar");
|
||||
}
|
||||
|
||||
@Test
|
||||
void toStringWhenHasNoHintReturnsEmpty() {
|
||||
assertThat(FileExtensionHint.from("foo")).hasToString("");
|
||||
}
|
||||
|
||||
@Test
|
||||
void removeFromWhenHasHint() {
|
||||
assertThat(FileExtensionHint.removeFrom("foo[.bar]")).isEqualTo("foo");
|
||||
}
|
||||
|
||||
@Test
|
||||
void removeFromWhenHasNoHint() {
|
||||
assertThat(FileExtensionHint.removeFrom("foo[bar]")).isEqualTo("foo[bar]");
|
||||
}
|
||||
|
||||
}
|
|
@ -31,28 +31,28 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
|||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link EnvConfigDataLoader}.
|
||||
* Tests for {@link SystemEnvironmentConfigDataLoader}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
class EnvConfigDataLoaderTests {
|
||||
class SystemEnvironmentConfigDataLoaderTests {
|
||||
|
||||
private ConfigDataLoaderContext context;
|
||||
|
||||
private Map<String, String> envVariables;
|
||||
private Map<String, String> environment;
|
||||
|
||||
private EnvConfigDataLoader loader;
|
||||
private SystemEnvironmentConfigDataLoader loader;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
this.context = mock(ConfigDataLoaderContext.class);
|
||||
this.envVariables = new HashMap<>();
|
||||
this.loader = new EnvConfigDataLoader(this.envVariables::get);
|
||||
this.environment = new HashMap<>();
|
||||
this.loader = new SystemEnvironmentConfigDataLoader();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldLoadFromVariable() throws IOException {
|
||||
this.envVariables.put("VAR1", "key1=value1");
|
||||
void loadLoadsConfigData() throws IOException {
|
||||
this.environment.put("VAR1", "key1=value1");
|
||||
ConfigData data = this.loader.load(this.context, createResource("VAR1"));
|
||||
assertThat(data.getPropertySources()).hasSize(1);
|
||||
PropertySource<?> propertySource = data.getPropertySources().get(0);
|
||||
|
@ -60,15 +60,16 @@ class EnvConfigDataLoaderTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void shouldFailIfVariableIsNotSet() {
|
||||
void loadWhenNoContentThrowsException() {
|
||||
assertThatExceptionOfType(ConfigDataResourceNotFoundException.class)
|
||||
.isThrownBy(() -> this.loader.load(this.context, createResource("VAR1")))
|
||||
.withMessage("Config data resource 'env variable [VAR1]' cannot be found");
|
||||
.withMessage("Config data resource 'system envionement variable [VAR1] content "
|
||||
+ "loaded using PropertiesPropertySourceLoader' cannot be found");
|
||||
}
|
||||
|
||||
private static EnvConfigDataResource createResource(String variableName) {
|
||||
return new EnvConfigDataResource(ConfigDataLocation.of("env:" + variableName), variableName,
|
||||
new PropertiesPropertySourceLoader());
|
||||
private SystemEnvironmentConfigDataResource createResource(String variableName) {
|
||||
return new SystemEnvironmentConfigDataResource(variableName, new PropertiesPropertySourceLoader(),
|
||||
this.environment::get);
|
||||
}
|
||||
|
||||
}
|
|
@ -32,24 +32,24 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
|||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link EnvConfigDataLocationResolver}.
|
||||
* Tests for {@link SystemEnvironmentConfigDataLocationResolver}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
class EnvConfigDataLocationResolverTests {
|
||||
class SystemEnvironmentConfigDataLocationResolverTests {
|
||||
|
||||
private EnvConfigDataLocationResolver resolver;
|
||||
private SystemEnvironmentConfigDataLocationResolver resolver;
|
||||
|
||||
private Map<String, String> envVariables;
|
||||
private Map<String, String> environment;
|
||||
|
||||
private ConfigDataLocationResolverContext context;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
this.context = mock(ConfigDataLocationResolverContext.class);
|
||||
this.envVariables = new HashMap<>();
|
||||
this.resolver = new EnvConfigDataLocationResolver(
|
||||
List.of(new PropertiesPropertySourceLoader(), new YamlPropertySourceLoader()), this.envVariables::get);
|
||||
this.environment = new HashMap<>();
|
||||
this.resolver = new SystemEnvironmentConfigDataLocationResolver(
|
||||
List.of(new PropertiesPropertySourceLoader(), new YamlPropertySourceLoader()), this.environment::get);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -60,69 +60,65 @@ class EnvConfigDataLocationResolverTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void shouldResolve() {
|
||||
this.envVariables.put("VAR1", "VALUE1");
|
||||
void resolveResolves() {
|
||||
this.environment.put("VAR1", "VALUE1");
|
||||
ConfigDataLocation location = ConfigDataLocation.of("env:VAR1");
|
||||
List<EnvConfigDataResource> resolved = this.resolver.resolve(this.context, location);
|
||||
List<SystemEnvironmentConfigDataResource> resolved = this.resolver.resolve(this.context, location);
|
||||
assertThat(resolved).hasSize(1);
|
||||
EnvConfigDataResource resource = resolved.get(0);
|
||||
assertThat(resource.getLocation()).isEqualTo(location);
|
||||
SystemEnvironmentConfigDataResource resource = resolved.get(0);
|
||||
assertThat(resource.getVariableName()).isEqualTo("VAR1");
|
||||
assertThat(resource.getLoader()).isInstanceOf(PropertiesPropertySourceLoader.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldResolveOptional() {
|
||||
this.envVariables.put("VAR1", "VALUE1");
|
||||
ConfigDataLocation location = ConfigDataLocation.of("optional:env:VAR1");
|
||||
List<EnvConfigDataResource> resolved = this.resolver.resolve(this.context, location);
|
||||
assertThat(resolved).hasSize(1);
|
||||
EnvConfigDataResource resource = resolved.get(0);
|
||||
assertThat(resource.getLocation()).isEqualTo(location);
|
||||
assertThat(resource.getVariableName()).isEqualTo("VAR1");
|
||||
assertThat(resource.getLoader()).isInstanceOf(PropertiesPropertySourceLoader.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldResolveOptionalIfVariableIsNotSet() {
|
||||
ConfigDataLocation location = ConfigDataLocation.of("optional:env:VAR1");
|
||||
List<EnvConfigDataResource> resolved = this.resolver.resolve(this.context, location);
|
||||
assertThat(resolved).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldResolveWithPropertiesExtension() {
|
||||
this.envVariables.put("VAR1", "VALUE1");
|
||||
ConfigDataLocation location = ConfigDataLocation.of("env:VAR1[.properties]");
|
||||
List<EnvConfigDataResource> resolved = this.resolver.resolve(this.context, location);
|
||||
assertThat(resolved).hasSize(1);
|
||||
EnvConfigDataResource resource = resolved.get(0);
|
||||
assertThat(resource.getLocation()).isEqualTo(location);
|
||||
assertThat(resource.getVariableName()).isEqualTo("VAR1");
|
||||
assertThat(resource.getLoader()).isInstanceOf(PropertiesPropertySourceLoader.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldResolveWithYamlExtension() {
|
||||
this.envVariables.put("VAR1", "VALUE1");
|
||||
ConfigDataLocation location = ConfigDataLocation.of("env:VAR1[.yaml]");
|
||||
List<EnvConfigDataResource> resolved = this.resolver.resolve(this.context, location);
|
||||
assertThat(resolved).hasSize(1);
|
||||
EnvConfigDataResource resource = resolved.get(0);
|
||||
assertThat(resource.getLocation()).isEqualTo(location);
|
||||
assertThat(resource.getVariableName()).isEqualTo("VAR1");
|
||||
assertThat(resource.getLoader()).isInstanceOf(YamlPropertySourceLoader.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldFailIfVariableIsNotSet() {
|
||||
void resolveWhenHasNoVariableThrowsException() {
|
||||
assertThatExceptionOfType(ConfigDataLocationNotFoundException.class)
|
||||
.isThrownBy(() -> this.resolver.resolve(this.context, ConfigDataLocation.of("env:VAR1")))
|
||||
.withMessage("Environment variable 'VAR1' is not set");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldFailIfUnknownExtensionIsGiven() {
|
||||
void resolveWhenOptionalAndHasVariableResolves() {
|
||||
this.environment.put("VAR1", "VALUE1");
|
||||
ConfigDataLocation location = ConfigDataLocation.of("optional:env:VAR1");
|
||||
List<SystemEnvironmentConfigDataResource> resolved = this.resolver.resolve(this.context, location);
|
||||
assertThat(resolved).hasSize(1);
|
||||
SystemEnvironmentConfigDataResource resource = resolved.get(0);
|
||||
assertThat(resource.getVariableName()).isEqualTo("VAR1");
|
||||
assertThat(resource.getLoader()).isInstanceOf(PropertiesPropertySourceLoader.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolveWhenOptionalAndHasNoVariableResolvesEmpty() {
|
||||
ConfigDataLocation location = ConfigDataLocation.of("optional:env:VAR1");
|
||||
List<SystemEnvironmentConfigDataResource> resolved = this.resolver.resolve(this.context, location);
|
||||
assertThat(resolved).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolveWhenHasPropertiesExtensionHintResolves() {
|
||||
this.environment.put("VAR1", "VALUE1");
|
||||
ConfigDataLocation location = ConfigDataLocation.of("env:VAR1[.properties]");
|
||||
List<SystemEnvironmentConfigDataResource> resolved = this.resolver.resolve(this.context, location);
|
||||
assertThat(resolved).hasSize(1);
|
||||
SystemEnvironmentConfigDataResource resource = resolved.get(0);
|
||||
assertThat(resource.getVariableName()).isEqualTo("VAR1");
|
||||
assertThat(resource.getLoader()).isInstanceOf(PropertiesPropertySourceLoader.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolveWhenHasYamlExtensionHintResolves() {
|
||||
this.environment.put("VAR1", "VALUE1");
|
||||
ConfigDataLocation location = ConfigDataLocation.of("env:VAR1[.yaml]");
|
||||
List<SystemEnvironmentConfigDataResource> resolved = this.resolver.resolve(this.context, location);
|
||||
assertThat(resolved).hasSize(1);
|
||||
SystemEnvironmentConfigDataResource resource = resolved.get(0);
|
||||
assertThat(resource.getVariableName()).isEqualTo("VAR1");
|
||||
assertThat(resource.getLoader()).isInstanceOf(YamlPropertySourceLoader.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolveWhenHasUnknownExtensionHintThrowsException() {
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> this.resolver.resolve(this.context, ConfigDataLocation.of("env:VAR1[.dummy]")))
|
||||
.withMessage("File extension 'dummy' is not known to any PropertySourceLoader");
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright 2012-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.context.config;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.env.PropertiesPropertySourceLoader;
|
||||
import org.springframework.boot.env.PropertySourceLoader;
|
||||
import org.springframework.boot.env.YamlPropertySourceLoader;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link SystemEnvironmentConfigDataResource}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
class SystemEnvironmentConfigDataResourceTests {
|
||||
|
||||
private Map<String, String> environment = new HashMap<>();
|
||||
|
||||
private final YamlPropertySourceLoader yamlLoader = new YamlPropertySourceLoader();
|
||||
|
||||
private final PropertiesPropertySourceLoader propertiesLoader = new PropertiesPropertySourceLoader();
|
||||
|
||||
@Test
|
||||
void loadLoadsPropertySources() throws IOException {
|
||||
this.environment.put("VAR1", "key1=value1");
|
||||
List<PropertySource<?>> loaded = createResource("VAR1").load();
|
||||
assertThat(loaded).hasSize(1);
|
||||
assertThat(loaded.get(0).getProperty("key1")).isEqualTo("value1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadWhenNoContentReturnsNull() throws IOException {
|
||||
List<PropertySource<?>> loaded = createResource("VAR1").load();
|
||||
assertThat(loaded).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void equalsAndHashcode() {
|
||||
SystemEnvironmentConfigDataResource var1 = createResource("VAR1");
|
||||
SystemEnvironmentConfigDataResource var2 = createResource("VAR2");
|
||||
SystemEnvironmentConfigDataResource var3 = createResource("VAR1", this.yamlLoader);
|
||||
SystemEnvironmentConfigDataResource var4 = createResource("VAR1");
|
||||
assertThat(var1).isNotEqualTo(var2);
|
||||
assertThat(var1).isNotEqualTo(var3);
|
||||
assertThat(var1).isEqualTo(var4);
|
||||
assertThat(var1).hasSameHashCodeAs(var4);
|
||||
}
|
||||
|
||||
@Test
|
||||
void toStringReturnsString() {
|
||||
SystemEnvironmentConfigDataResource resource = createResource("VAR1");
|
||||
assertThat(resource)
|
||||
.hasToString("system envionement variable [VAR1] content loaded using PropertiesPropertySourceLoader");
|
||||
}
|
||||
|
||||
private SystemEnvironmentConfigDataResource createResource(String variableName) {
|
||||
return createResource(variableName, this.propertiesLoader);
|
||||
}
|
||||
|
||||
private SystemEnvironmentConfigDataResource createResource(String variableName,
|
||||
PropertySourceLoader propertySourceLoader) {
|
||||
return new SystemEnvironmentConfigDataResource(variableName, propertySourceLoader, this.environment::get);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue