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
|
* @param pathToCheck the path to check
|
||||||
*/
|
*/
|
||||||
public static void throwIfDoesNotExist(ConfigDataResource resource, Path pathToCheck) {
|
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
|
* @param fileToCheck the file to check
|
||||||
*/
|
*/
|
||||||
public static void throwIfDoesNotExist(ConfigDataResource resource, File fileToCheck) {
|
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
|
* @param resourceToCheck the resource to check
|
||||||
*/
|
*/
|
||||||
public static void throwIfDoesNotExist(ConfigDataResource resource, Resource resourceToCheck) {
|
public static void throwIfDoesNotExist(ConfigDataResource resource, Resource resourceToCheck) {
|
||||||
throwIfDoesNotExist(resource, resourceToCheck.exists());
|
throwIfNot(resource, resourceToCheck.exists());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void throwIfDoesNotExist(ConfigDataResource resource, boolean exists) {
|
private static void throwIfNot(ConfigDataResource resource, boolean check) {
|
||||||
if (!exists) {
|
if (!check) {
|
||||||
throw new ConfigDataResourceNotFoundException(resource);
|
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.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
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 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 static final String NO_PROFILE = null;
|
||||||
|
|
||||||
private final Log logger;
|
private final Log logger;
|
||||||
|
@ -238,17 +235,16 @@ public class StandardConfigDataLocationResolver
|
||||||
|
|
||||||
private Set<StandardConfigDataReference> getReferencesForFile(ConfigDataLocation configDataLocation, String file,
|
private Set<StandardConfigDataReference> getReferencesForFile(ConfigDataLocation configDataLocation, String file,
|
||||||
String profile) {
|
String profile) {
|
||||||
Matcher extensionHintMatcher = EXTENSION_HINT_PATTERN.matcher(file);
|
FileExtensionHint fileExtensionHint = FileExtensionHint.from(file);
|
||||||
boolean extensionHintLocation = extensionHintMatcher.matches();
|
if (fileExtensionHint.isPresent()) {
|
||||||
if (extensionHintLocation) {
|
file = FileExtensionHint.removeFrom(file) + fileExtensionHint;
|
||||||
file = extensionHintMatcher.group(1) + extensionHintMatcher.group(2);
|
|
||||||
}
|
}
|
||||||
for (PropertySourceLoader propertySourceLoader : this.propertySourceLoaders) {
|
for (PropertySourceLoader propertySourceLoader : this.propertySourceLoaders) {
|
||||||
String extension = getLoadableFileExtension(propertySourceLoader, file);
|
String fileExtension = getLoadableFileExtension(propertySourceLoader, file);
|
||||||
if (extension != null) {
|
if (fileExtension != null) {
|
||||||
String root = file.substring(0, file.length() - extension.length() - 1);
|
String root = file.substring(0, file.length() - fileExtension.length() - 1);
|
||||||
StandardConfigDataReference reference = new StandardConfigDataReference(configDataLocation, null, root,
|
StandardConfigDataReference reference = new StandardConfigDataReference(configDataLocation, null, root,
|
||||||
profile, (!extensionHintLocation) ? extension : null, propertySourceLoader);
|
profile, (!fileExtensionHint.isPresent()) ? fileExtension : null, propertySourceLoader);
|
||||||
return Collections.singleton(reference);
|
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.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import org.springframework.boot.env.PropertySourceLoader;
|
import org.springframework.boot.env.PropertySourceLoader;
|
||||||
import org.springframework.core.io.support.SpringFactoriesLoader;
|
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.
|
* {@link ConfigDataLocationResolver} to resolve {@code env:} locations.
|
||||||
*
|
*
|
||||||
* @author Moritz Halbritter
|
* @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 String PREFIX = "env:";
|
||||||
|
|
||||||
private static final Pattern EXTENSION_HINT_PATTERN = Pattern.compile("^(.*)\\[(\\.\\w+)](?!\\[)$");
|
|
||||||
|
|
||||||
private static final String DEFAULT_EXTENSION = ".properties";
|
private static final String DEFAULT_EXTENSION = ".properties";
|
||||||
|
|
||||||
private final List<PropertySourceLoader> loaders;
|
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.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.loaders = loaders;
|
||||||
this.readEnvVariable = readEnvVariable;
|
this.environment = environment;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -58,15 +57,15 @@ class EnvConfigDataLocationResolver implements ConfigDataLocationResolver<EnvCon
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<EnvConfigDataResource> resolve(ConfigDataLocationResolverContext context, ConfigDataLocation location)
|
public List<SystemEnvironmentConfigDataResource> resolve(ConfigDataLocationResolverContext context,
|
||||||
|
ConfigDataLocation location)
|
||||||
throws ConfigDataLocationNotFoundException, ConfigDataResourceNotFoundException {
|
throws ConfigDataLocationNotFoundException, ConfigDataResourceNotFoundException {
|
||||||
String value = location.getNonPrefixedValue(PREFIX);
|
String value = location.getNonPrefixedValue(PREFIX);
|
||||||
Matcher matcher = EXTENSION_HINT_PATTERN.matcher(value);
|
FileExtensionHint fileExtensionHint = FileExtensionHint.from(value);
|
||||||
String extension = getExtension(matcher);
|
String variableName = FileExtensionHint.removeFrom(value);
|
||||||
String variableName = getVariableName(matcher, value);
|
PropertySourceLoader loader = getLoader(fileExtensionHint.orElse(DEFAULT_EXTENSION));
|
||||||
PropertySourceLoader loader = getLoader(extension);
|
|
||||||
if (hasEnvVariable(variableName)) {
|
if (hasEnvVariable(variableName)) {
|
||||||
return List.of(new EnvConfigDataResource(location, variableName, loader));
|
return List.of(new SystemEnvironmentConfigDataResource(variableName, loader, this.environment));
|
||||||
}
|
}
|
||||||
if (location.isOptional()) {
|
if (location.isOptional()) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
|
@ -76,12 +75,7 @@ class EnvConfigDataLocationResolver implements ConfigDataLocationResolver<EnvCon
|
||||||
}
|
}
|
||||||
|
|
||||||
private PropertySourceLoader getLoader(String extension) {
|
private PropertySourceLoader getLoader(String extension) {
|
||||||
if (extension == null) {
|
extension = (!extension.startsWith(".")) ? extension : extension.substring(1);
|
||||||
extension = DEFAULT_EXTENSION;
|
|
||||||
}
|
|
||||||
if (extension.startsWith(".")) {
|
|
||||||
extension = extension.substring(1);
|
|
||||||
}
|
|
||||||
for (PropertySourceLoader loader : this.loaders) {
|
for (PropertySourceLoader loader : this.loaders) {
|
||||||
for (String supportedExtension : loader.getFileExtensions()) {
|
for (String supportedExtension : loader.getFileExtensions()) {
|
||||||
if (supportedExtension.equalsIgnoreCase(extension)) {
|
if (supportedExtension.equalsIgnoreCase(extension)) {
|
||||||
|
@ -94,21 +88,7 @@ class EnvConfigDataLocationResolver implements ConfigDataLocationResolver<EnvCon
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasEnvVariable(String variableName) {
|
private boolean hasEnvVariable(String variableName) {
|
||||||
return this.readEnvVariable.apply(variableName) != null;
|
return this.environment.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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -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
|
# ConfigData Location Resolvers
|
||||||
org.springframework.boot.context.config.ConfigDataLocationResolver=\
|
org.springframework.boot.context.config.ConfigDataLocationResolver=\
|
||||||
org.springframework.boot.context.config.ConfigTreeConfigDataLocationResolver,\
|
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
|
# ConfigData Loaders
|
||||||
org.springframework.boot.context.config.ConfigDataLoader=\
|
org.springframework.boot.context.config.ConfigDataLoader=\
|
||||||
org.springframework.boot.context.config.ConfigTreeConfigDataLoader,\
|
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
|
# Application Context Factories
|
||||||
org.springframework.boot.ApplicationContextFactory=\
|
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;
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link EnvConfigDataLoader}.
|
* Tests for {@link SystemEnvironmentConfigDataLoader}.
|
||||||
*
|
*
|
||||||
* @author Moritz Halbritter
|
* @author Moritz Halbritter
|
||||||
*/
|
*/
|
||||||
class EnvConfigDataLoaderTests {
|
class SystemEnvironmentConfigDataLoaderTests {
|
||||||
|
|
||||||
private ConfigDataLoaderContext context;
|
private ConfigDataLoaderContext context;
|
||||||
|
|
||||||
private Map<String, String> envVariables;
|
private Map<String, String> environment;
|
||||||
|
|
||||||
private EnvConfigDataLoader loader;
|
private SystemEnvironmentConfigDataLoader loader;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setUp() {
|
void setUp() {
|
||||||
this.context = mock(ConfigDataLoaderContext.class);
|
this.context = mock(ConfigDataLoaderContext.class);
|
||||||
this.envVariables = new HashMap<>();
|
this.environment = new HashMap<>();
|
||||||
this.loader = new EnvConfigDataLoader(this.envVariables::get);
|
this.loader = new SystemEnvironmentConfigDataLoader();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldLoadFromVariable() throws IOException {
|
void loadLoadsConfigData() throws IOException {
|
||||||
this.envVariables.put("VAR1", "key1=value1");
|
this.environment.put("VAR1", "key1=value1");
|
||||||
ConfigData data = this.loader.load(this.context, createResource("VAR1"));
|
ConfigData data = this.loader.load(this.context, createResource("VAR1"));
|
||||||
assertThat(data.getPropertySources()).hasSize(1);
|
assertThat(data.getPropertySources()).hasSize(1);
|
||||||
PropertySource<?> propertySource = data.getPropertySources().get(0);
|
PropertySource<?> propertySource = data.getPropertySources().get(0);
|
||||||
|
@ -60,15 +60,16 @@ class EnvConfigDataLoaderTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldFailIfVariableIsNotSet() {
|
void loadWhenNoContentThrowsException() {
|
||||||
assertThatExceptionOfType(ConfigDataResourceNotFoundException.class)
|
assertThatExceptionOfType(ConfigDataResourceNotFoundException.class)
|
||||||
.isThrownBy(() -> this.loader.load(this.context, createResource("VAR1")))
|
.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) {
|
private SystemEnvironmentConfigDataResource createResource(String variableName) {
|
||||||
return new EnvConfigDataResource(ConfigDataLocation.of("env:" + variableName), variableName,
|
return new SystemEnvironmentConfigDataResource(variableName, new PropertiesPropertySourceLoader(),
|
||||||
new PropertiesPropertySourceLoader());
|
this.environment::get);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -32,24 +32,24 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link EnvConfigDataLocationResolver}.
|
* Tests for {@link SystemEnvironmentConfigDataLocationResolver}.
|
||||||
*
|
*
|
||||||
* @author Moritz Halbritter
|
* @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;
|
private ConfigDataLocationResolverContext context;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setUp() {
|
void setUp() {
|
||||||
this.context = mock(ConfigDataLocationResolverContext.class);
|
this.context = mock(ConfigDataLocationResolverContext.class);
|
||||||
this.envVariables = new HashMap<>();
|
this.environment = new HashMap<>();
|
||||||
this.resolver = new EnvConfigDataLocationResolver(
|
this.resolver = new SystemEnvironmentConfigDataLocationResolver(
|
||||||
List.of(new PropertiesPropertySourceLoader(), new YamlPropertySourceLoader()), this.envVariables::get);
|
List.of(new PropertiesPropertySourceLoader(), new YamlPropertySourceLoader()), this.environment::get);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -60,69 +60,65 @@ class EnvConfigDataLocationResolverTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldResolve() {
|
void resolveResolves() {
|
||||||
this.envVariables.put("VAR1", "VALUE1");
|
this.environment.put("VAR1", "VALUE1");
|
||||||
ConfigDataLocation location = ConfigDataLocation.of("env:VAR1");
|
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);
|
assertThat(resolved).hasSize(1);
|
||||||
EnvConfigDataResource resource = resolved.get(0);
|
SystemEnvironmentConfigDataResource resource = resolved.get(0);
|
||||||
assertThat(resource.getLocation()).isEqualTo(location);
|
|
||||||
assertThat(resource.getVariableName()).isEqualTo("VAR1");
|
assertThat(resource.getVariableName()).isEqualTo("VAR1");
|
||||||
assertThat(resource.getLoader()).isInstanceOf(PropertiesPropertySourceLoader.class);
|
assertThat(resource.getLoader()).isInstanceOf(PropertiesPropertySourceLoader.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldResolveOptional() {
|
void resolveWhenHasNoVariableThrowsException() {
|
||||||
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() {
|
|
||||||
assertThatExceptionOfType(ConfigDataLocationNotFoundException.class)
|
assertThatExceptionOfType(ConfigDataLocationNotFoundException.class)
|
||||||
.isThrownBy(() -> this.resolver.resolve(this.context, ConfigDataLocation.of("env:VAR1")))
|
.isThrownBy(() -> this.resolver.resolve(this.context, ConfigDataLocation.of("env:VAR1")))
|
||||||
.withMessage("Environment variable 'VAR1' is not set");
|
.withMessage("Environment variable 'VAR1' is not set");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@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()
|
assertThatIllegalStateException()
|
||||||
.isThrownBy(() -> this.resolver.resolve(this.context, ConfigDataLocation.of("env:VAR1[.dummy]")))
|
.isThrownBy(() -> this.resolver.resolve(this.context, ConfigDataLocation.of("env:VAR1[.dummy]")))
|
||||||
.withMessage("File extension 'dummy' is not known to any PropertySourceLoader");
|
.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