Browse Source

Polish 'Fix inconsistent ordering of config imports'

See gh-49324
pull/49591/head
Phillip Webb 4 weeks ago
parent
commit
646db448ae
  1. 26
      spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataEnvironment.java
  2. 33
      spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataEnvironmentContributor.java
  3. 27
      spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentContributorTests.java
  4. 28
      spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentContributorsTests.java
  5. 2
      spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentTests.java

26
spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataEnvironment.java

@ -17,7 +17,6 @@
package org.springframework.boot.context.config; package org.springframework.boot.context.config;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
@ -199,8 +198,7 @@ class ConfigDataEnvironment {
private List<ConfigDataEnvironmentContributor> getInitialImportContributors(Binder binder) { private List<ConfigDataEnvironmentContributor> getInitialImportContributors(Binder binder) {
List<ConfigDataEnvironmentContributor> initialContributors = new ArrayList<>(); List<ConfigDataEnvironmentContributor> initialContributors = new ArrayList<>();
addInitialImportPropertyContributors(initialContributors, addInitialImportContributors(initialContributors, bindLocations(binder, IMPORT_PROPERTY, EMPTY_LOCATIONS));
bindLocations(binder, IMPORT_PROPERTY, EMPTY_LOCATIONS));
addInitialImportContributors(initialContributors, addInitialImportContributors(initialContributors,
bindLocations(binder, ADDITIONAL_LOCATION_PROPERTY, EMPTY_LOCATIONS)); bindLocations(binder, ADDITIONAL_LOCATION_PROPERTY, EMPTY_LOCATIONS));
addInitialImportContributors(initialContributors, addInitialImportContributors(initialContributors,
@ -212,27 +210,21 @@ class ConfigDataEnvironment {
return binder.bind(propertyName, CONFIG_DATA_LOCATION_ARRAY).orElse(other); return binder.bind(propertyName, CONFIG_DATA_LOCATION_ARRAY).orElse(other);
} }
private void addInitialImportPropertyContributors(List<ConfigDataEnvironmentContributor> initialContributors, private void addInitialImportContributors(List<ConfigDataEnvironmentContributor> initialContributors,
ConfigDataLocation[] locations) { ConfigDataLocation[] locations) {
List<ConfigDataEnvironmentContributor> initialPropertiesContributors = new ArrayList<>(); addInitialImportContributors(initialContributors, List.of(locations));
addInitialImportContributors(initialPropertiesContributors, locations);
initialContributors.add(ConfigDataEnvironmentContributor.ofInitialImportProperty(
initialPropertiesContributors, this.environment.getConversionService(), Arrays.asList(locations))
);
} }
private void addInitialImportContributors(List<ConfigDataEnvironmentContributor> initialContributors, private void addInitialImportContributors(List<ConfigDataEnvironmentContributor> initialContributors,
ConfigDataLocation[] locations) { List<ConfigDataLocation> locations) {
for (int i = locations.length - 1; i >= 0; i--) { if (!locations.isEmpty()) {
initialContributors.add(createInitialImportContributor(locations[i])); this.logger.trace(LogMessage.format("Adding initial config data import from locations %s", locations));
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImports(locations,
this.environment.getConversionService());
initialContributors.add(contributor);
} }
} }
private ConfigDataEnvironmentContributor createInitialImportContributor(ConfigDataLocation location) {
this.logger.trace(LogMessage.format("Adding initial config data import from location '%s'", location));
return ConfigDataEnvironmentContributor.ofInitialImport(location, this.environment.getConversionService());
}
/** /**
* Process all contributions and apply any newly imported property sources to the * Process all contributions and apply any newly imported property sources to the
* {@link Environment}. * {@link Environment}.

33
spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataEnvironmentContributor.java

@ -393,39 +393,17 @@ class ConfigDataEnvironmentContributor implements Iterable<ConfigDataEnvironment
* Factory method to create a {@link Kind#INITIAL_IMPORT initial import} contributor. * Factory method to create a {@link Kind#INITIAL_IMPORT initial import} contributor.
* This contributor is used to trigger initial imports of additional contributors. It * This contributor is used to trigger initial imports of additional contributors. It
* does not contribute any properties itself. * does not contribute any properties itself.
* @param initialImport the initial import location (with placeholders resolved) * @param initialImports the initial import locations (with placeholders resolved)
* @param conversionService the conversion service to use * @param conversionService the conversion service to use
* @return a new {@link ConfigDataEnvironmentContributor} instance * @return a new {@link ConfigDataEnvironmentContributor} instance
*/ */
static ConfigDataEnvironmentContributor ofInitialImport(ConfigDataLocation initialImport, static ConfigDataEnvironmentContributor ofInitialImports(List<ConfigDataLocation> initialImports,
ConversionService conversionService) { ConversionService conversionService) {
List<ConfigDataLocation> imports = Collections.singletonList(initialImport); ConfigDataProperties properties = new ConfigDataProperties(initialImports, null);
ConfigDataProperties properties = new ConfigDataProperties(imports, null);
return new ConfigDataEnvironmentContributor(Kind.INITIAL_IMPORT, null, null, false, null, null, properties, return new ConfigDataEnvironmentContributor(Kind.INITIAL_IMPORT, null, null, false, null, null, properties,
null, null, conversionService); null, null, conversionService);
} }
/**
* Factory method to create a {@link Kind#INITIAL_IMPORT_PROPERTY initial import property}
* contributor. This contributor is a container that wraps initial imports from
* {@code spring.config.import} property, allowing profile-specific imports to take
* precedence over the imported locations.
* @param contributors the contributors created from the import locations
* @param conversionService the conversion service to use
* @param locations the original import locations from the property
* @return a new {@link ConfigDataEnvironmentContributor} instance
*/
static ConfigDataEnvironmentContributor ofInitialImportProperty(
List<ConfigDataEnvironmentContributor> contributors,
ConversionService conversionService,
List<ConfigDataLocation> locations) {
Map<ImportPhase, List<ConfigDataEnvironmentContributor>> children = new LinkedHashMap<>();
ConfigDataProperties properties = new ConfigDataProperties(locations, null);
children.put(ImportPhase.BEFORE_PROFILE_ACTIVATION, Collections.unmodifiableList(contributors));
return new ConfigDataEnvironmentContributor(Kind.INITIAL_IMPORT_PROPERTY, null, null, false, null, null, properties, null, children,
conversionService);
}
/** /**
* Factory method to create a contributor that wraps an {@link Kind#EXISTING existing} * Factory method to create a contributor that wraps an {@link Kind#EXISTING existing}
* property source. The contributor provides access to existing properties, but * property source. The contributor provides access to existing properties, but
@ -499,11 +477,6 @@ class ConfigDataEnvironmentContributor implements Iterable<ConfigDataEnvironment
*/ */
INITIAL_IMPORT, INITIAL_IMPORT,
/**
* A container contributor that wraps initial imports from spring.config.import property.
*/
INITIAL_IMPORT_PROPERTY,
/** /**
* An existing property source that contributes properties but no imports. * An existing property source that contributes properties but no imports.
*/ */

27
spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentContributorTests.java

@ -50,6 +50,8 @@ class ConfigDataEnvironmentContributorTests {
private static final ConfigDataLocation TEST_LOCATION = ConfigDataLocation.of("test"); private static final ConfigDataLocation TEST_LOCATION = ConfigDataLocation.of("test");
private static final List<ConfigDataLocation> TEST_LOCATIONS = List.of(TEST_LOCATION);
private final ConfigDataActivationContext activationContext = new ConfigDataActivationContext( private final ConfigDataActivationContext activationContext = new ConfigDataActivationContext(
CloudPlatform.KUBERNETES, null); CloudPlatform.KUBERNETES, null);
@ -57,14 +59,14 @@ class ConfigDataEnvironmentContributorTests {
@Test @Test
void getKindReturnsKind() { void getKindReturnsKind() {
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(TEST_LOCATION, ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImports(TEST_LOCATIONS,
this.conversionService); this.conversionService);
assertThat(contributor.getKind()).isEqualTo(Kind.INITIAL_IMPORT); assertThat(contributor.getKind()).isEqualTo(Kind.INITIAL_IMPORT);
} }
@Test @Test
void isActiveWhenPropertiesIsNullReturnsTrue() { void isActiveWhenPropertiesIsNullReturnsTrue() {
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(TEST_LOCATION, ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImports(TEST_LOCATIONS,
this.conversionService); this.conversionService);
assertThat(contributor.isActive(null)).isTrue(); assertThat(contributor.isActive(null)).isTrue();
} }
@ -287,33 +289,18 @@ class ConfigDataEnvironmentContributorTests {
} }
@Test @Test
void ofInitialImportCreatedInitialImportContributor() { void ofInitialImportsCreatedInitialImportContributor() {
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(TEST_LOCATION, ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImports(TEST_LOCATIONS,
this.conversionService); this.conversionService);
assertThat(contributor.getKind()).isEqualTo(Kind.INITIAL_IMPORT); assertThat(contributor.getKind()).isEqualTo(Kind.INITIAL_IMPORT);
assertThat(contributor.getResource()).isNull(); assertThat(contributor.getResource()).isNull();
assertThat(contributor.getImports()).containsExactly(TEST_LOCATION); assertThat(contributor.getImports()).isEqualTo(TEST_LOCATIONS);
assertThat(contributor.isActive(this.activationContext)).isTrue(); assertThat(contributor.isActive(this.activationContext)).isTrue();
assertThat(contributor.getPropertySource()).isNull(); assertThat(contributor.getPropertySource()).isNull();
assertThat(contributor.getConfigurationPropertySource()).isNull(); assertThat(contributor.getConfigurationPropertySource()).isNull();
assertThat(contributor.getChildren(ImportPhase.BEFORE_PROFILE_ACTIVATION)).isEmpty(); assertThat(contributor.getChildren(ImportPhase.BEFORE_PROFILE_ACTIVATION)).isEmpty();
} }
@Test
void ofInitialImportPropertyCreatedInitialImportPropertyContributor() {
ConfigDataEnvironmentContributor innerContributor = ConfigDataEnvironmentContributor.ofInitialImport(TEST_LOCATION,
this.conversionService);
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImportProperty(
Collections.singletonList(innerContributor), this.conversionService, Arrays.asList(TEST_LOCATION));
assertThat(contributor.getKind()).isEqualTo(Kind.INITIAL_IMPORT_PROPERTY);
assertThat(contributor.getResource()).isNull();
assertThat(contributor.getImports()).containsExactly(TEST_LOCATION);
assertThat(contributor.isActive(this.activationContext)).isTrue();
assertThat(contributor.getPropertySource()).isNull();
assertThat(contributor.getConfigurationPropertySource()).isNull();
assertThat(contributor.getChildren(ImportPhase.BEFORE_PROFILE_ACTIVATION)).containsExactly(innerContributor);
}
@Test @Test
void ofExistingCreatesExistingContributor() { void ofExistingCreatesExistingContributor() {
MockPropertySource propertySource = new MockPropertySource(); MockPropertySource propertySource = new MockPropertySource();

28
spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentContributorsTests.java

@ -91,8 +91,8 @@ class ConfigDataEnvironmentContributorsTests {
@Test @Test
void createCreatesWithInitialContributors() { void createCreatesWithInitialContributors() {
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(LOCATION_1, ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor
this.conversionService); .ofInitialImports(List.of(LOCATION_1), this.conversionService);
ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory, ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory,
this.bootstrapContext, List.of(contributor), this.conversionService, this.bootstrapContext, List.of(contributor), this.conversionService,
ConfigDataEnvironmentUpdateListener.NONE); ConfigDataEnvironmentUpdateListener.NONE);
@ -123,8 +123,8 @@ class ConfigDataEnvironmentContributorsTests {
new ConfigData(List.of(propertySource))); new ConfigData(List.of(propertySource)));
given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(locations))) given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(locations)))
.willReturn(imported); .willReturn(imported);
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(LOCATION_1, ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor
this.conversionService); .ofInitialImports(List.of(LOCATION_1), this.conversionService);
ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory, ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory,
this.bootstrapContext, List.of(contributor), this.conversionService, this.bootstrapContext, List.of(contributor), this.conversionService,
ConfigDataEnvironmentUpdateListener.NONE); ConfigDataEnvironmentUpdateListener.NONE);
@ -155,8 +155,8 @@ class ConfigDataEnvironmentContributorsTests {
new ConfigData(List.of(secondPropertySource))); new ConfigData(List.of(secondPropertySource)));
given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(secondLocations))) given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(secondLocations)))
.willReturn(secondImported); .willReturn(secondImported);
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(LOCATION_1, ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor
this.conversionService); .ofInitialImports(List.of(LOCATION_1), this.conversionService);
ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory, ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory,
this.bootstrapContext, List.of(contributor), this.conversionService, this.bootstrapContext, List.of(contributor), this.conversionService,
ConfigDataEnvironmentUpdateListener.NONE); ConfigDataEnvironmentUpdateListener.NONE);
@ -184,8 +184,8 @@ class ConfigDataEnvironmentContributorsTests {
new ConfigData(List.of(propertySource))); new ConfigData(List.of(propertySource)));
given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(locations))) given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(locations)))
.willReturn(imported); .willReturn(imported);
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(LOCATION_1, ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor
this.conversionService); .ofInitialImports(List.of(LOCATION_1), this.conversionService);
ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory, ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory,
this.bootstrapContext, Arrays.asList(existingContributor, contributor), this.conversionService, this.bootstrapContext, Arrays.asList(existingContributor, contributor), this.conversionService,
ConfigDataEnvironmentUpdateListener.NONE); ConfigDataEnvironmentUpdateListener.NONE);
@ -215,8 +215,8 @@ class ConfigDataEnvironmentContributorsTests {
new ConfigData(List.of(secondPropertySource))); new ConfigData(List.of(secondPropertySource)));
given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(secondLocations))) given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(secondLocations)))
.willReturn(secondImported); .willReturn(secondImported);
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(LOCATION_1, ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor
this.conversionService); .ofInitialImports(List.of(LOCATION_1), this.conversionService);
ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory, ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory,
this.bootstrapContext, List.of(contributor), this.conversionService, this.bootstrapContext, List.of(contributor), this.conversionService,
ConfigDataEnvironmentUpdateListener.NONE); ConfigDataEnvironmentUpdateListener.NONE);
@ -243,8 +243,8 @@ class ConfigDataEnvironmentContributorsTests {
new ConfigData(List.of(propertySource))); new ConfigData(List.of(propertySource)));
given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(locations))) given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(locations)))
.willReturn(imported); .willReturn(imported);
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(LOCATION_1, ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor
this.conversionService); .ofInitialImports(List.of(LOCATION_1), this.conversionService);
ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory, ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory,
this.bootstrapContext, Arrays.asList(existingContributor, contributor), this.conversionService, this.bootstrapContext, Arrays.asList(existingContributor, contributor), this.conversionService,
ConfigDataEnvironmentUpdateListener.NONE); ConfigDataEnvironmentUpdateListener.NONE);
@ -269,8 +269,8 @@ class ConfigDataEnvironmentContributorsTests {
new ConfigData(List.of(propertySource))); new ConfigData(List.of(propertySource)));
given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(locations))) given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(locations)))
.willReturn(imported); .willReturn(imported);
ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(LOCATION_1, ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor
this.conversionService); .ofInitialImports(List.of(LOCATION_1), this.conversionService);
ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory, ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory,
this.bootstrapContext, Arrays.asList(existingContributor, contributor), this.conversionService, this.bootstrapContext, Arrays.asList(existingContributor, contributor), this.conversionService,
ConfigDataEnvironmentUpdateListener.NONE); ConfigDataEnvironmentUpdateListener.NONE);

2
spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentTests.java

@ -144,7 +144,7 @@ class ConfigDataEnvironmentTests {
.map(ConfigDataEnvironmentContributor::getImports) .map(ConfigDataEnvironmentContributor::getImports)
.map(Object::toString) .map(Object::toString)
.toArray(); .toArray();
assertThat(imports).containsExactly("[i2]", "[i1]", "[a2]", "[a1]", "[l2]", "[l1]"); assertThat(imports).containsExactly("[i1, i2]", "[a1, a2]", "[l1, l2]");
} }
@Test @Test

Loading…
Cancel
Save