Commit fef62f78 authored by Phillip Webb's avatar Phillip Webb

Import profile specific files in correct order

Update `StandardConfigDataLoader` to mark profile specific files with
`Option.PROFILE` so that they are added in the correct order. This is
a variation of the same issue described in commit 5774ea3f.

Closes gh-26400
Co-authored-by: 's avatarScott Frederick <sfrederick@vmware.com>
Co-authored-by: 's avatarMadhura Bhave <mbhave@vmware.com>
parent 922517c0
...@@ -118,6 +118,13 @@ public final class ConfigData { ...@@ -118,6 +118,13 @@ public final class ConfigData {
@FunctionalInterface @FunctionalInterface
public interface PropertySourceOptions { public interface PropertySourceOptions {
/**
* {@link PropertySourceOptions} instance that always returns
* {@link Options#NONE}.
* @since 2.4.6
*/
PropertySourceOptions ALWAYS_NONE = new AlwaysPropertySourceOptions(Options.NONE);
/** /**
* Return the options that should apply for the given property source. * Return the options that should apply for the given property source.
* @param propertySource the property source * @param propertySource the property source
...@@ -142,6 +149,9 @@ public final class ConfigData { ...@@ -142,6 +149,9 @@ public final class ConfigData {
* @return a new {@link PropertySourceOptions} instance * @return a new {@link PropertySourceOptions} instance
*/ */
static PropertySourceOptions always(Options options) { static PropertySourceOptions always(Options options) {
if (options == Options.NONE) {
return ALWAYS_NONE;
}
return new AlwaysPropertySourceOptions(options); return new AlwaysPropertySourceOptions(options);
} }
...@@ -175,7 +185,7 @@ public final class ConfigData { ...@@ -175,7 +185,7 @@ public final class ConfigData {
/** /**
* No options. * No options.
*/ */
public static final Options NONE = Options.of(); public static final Options NONE = new Options(Collections.emptySet());
private final Set<Option> options; private final Set<Option> options;
...@@ -238,8 +248,10 @@ public final class ConfigData { ...@@ -238,8 +248,10 @@ public final class ConfigData {
*/ */
public static Options of(Option... options) { public static Options of(Option... options) {
Assert.notNull(options, "Options must not be null"); Assert.notNull(options, "Options must not be null");
return new Options( if (options.length == 0) {
(options.length != 0) ? EnumSet.copyOf(Arrays.asList(options)) : EnumSet.noneOf(Option.class)); return NONE;
}
return new Options(EnumSet.copyOf(Arrays.asList(options)));
} }
} }
......
...@@ -19,6 +19,8 @@ package org.springframework.boot.context.config; ...@@ -19,6 +19,8 @@ package org.springframework.boot.context.config;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import org.springframework.boot.context.config.ConfigData.Option;
import org.springframework.boot.context.config.ConfigData.PropertySourceOptions;
import org.springframework.boot.origin.Origin; import org.springframework.boot.origin.Origin;
import org.springframework.boot.origin.OriginTrackedResource; import org.springframework.boot.origin.OriginTrackedResource;
import org.springframework.core.env.PropertySource; import org.springframework.core.env.PropertySource;
...@@ -33,6 +35,10 @@ import org.springframework.core.io.Resource; ...@@ -33,6 +35,10 @@ import org.springframework.core.io.Resource;
*/ */
public class StandardConfigDataLoader implements ConfigDataLoader<StandardConfigDataResource> { public class StandardConfigDataLoader implements ConfigDataLoader<StandardConfigDataResource> {
private static final PropertySourceOptions PROFILE_SPECIFIC = PropertySourceOptions.always(Option.PROFILE_SPECIFIC);
private static final PropertySourceOptions NON_PROFILE_SPECIFIC = PropertySourceOptions.ALWAYS_NONE;
@Override @Override
public ConfigData load(ConfigDataLoaderContext context, StandardConfigDataResource resource) public ConfigData load(ConfigDataLoaderContext context, StandardConfigDataResource resource)
throws IOException, ConfigDataNotFoundException { throws IOException, ConfigDataNotFoundException {
...@@ -46,7 +52,8 @@ public class StandardConfigDataLoader implements ConfigDataLoader<StandardConfig ...@@ -46,7 +52,8 @@ public class StandardConfigDataLoader implements ConfigDataLoader<StandardConfig
String name = String.format("Config resource '%s' via location '%s'", resource, String name = String.format("Config resource '%s' via location '%s'", resource,
reference.getConfigDataLocation()); reference.getConfigDataLocation());
List<PropertySource<?>> propertySources = reference.getPropertySourceLoader().load(name, originTrackedResource); List<PropertySource<?>> propertySources = reference.getPropertySourceLoader().load(name, originTrackedResource);
return new ConfigData(propertySources); PropertySourceOptions options = (resource.getProfile() != null) ? PROFILE_SPECIFIC : NON_PROFILE_SPECIFIC;
return new ConfigData(propertySources, options);
} }
} }
...@@ -596,6 +596,14 @@ class ConfigDataEnvironmentPostProcessorIntegrationTests { ...@@ -596,6 +596,14 @@ class ConfigDataEnvironmentPostProcessorIntegrationTests {
assertThat(context.getEnvironment().getProperty("my.value")).isEqualTo("iwasimported"); assertThat(context.getEnvironment().getProperty("my.value")).isEqualTo("iwasimported");
} }
@Test
void runWhenImportWithProfileVariantOrdersPropertySourcesCorrectly() {
this.application.setAdditionalProfiles("dev");
ConfigurableApplicationContext context = this.application
.run("--spring.config.location=classpath:application-import-with-profile-variant.properties");
assertThat(context.getEnvironment().getProperty("my.value")).isEqualTo("iwasimported-dev");
}
@Test @Test
void runWhenHasPropertyInProfileDocumentThrowsException() { void runWhenHasPropertyInProfileDocumentThrowsException() {
assertThatExceptionOfType(BindException.class).isThrownBy(() -> this.application.run( assertThatExceptionOfType(BindException.class).isThrownBy(() -> this.application.run(
......
spring.config.import=classpath:application-import-with-profile-variant-imported.properties
my.value=notimported
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment