diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataEnvironment.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataEnvironment.java index 2b312d8b3c..feeefde56e 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataEnvironment.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataEnvironment.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2024 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. @@ -172,20 +172,23 @@ class ConfigDataEnvironment { else { this.logger.trace(LogMessage.format("Creating wrapped config data contributor for '%s'", propertySource.getName())); - contributors.add(ConfigDataEnvironmentContributor.ofExisting(propertySource)); + contributors.add(ConfigDataEnvironmentContributor.ofExisting(propertySource, + this.environment.getConversionService())); } } contributors.addAll(getInitialImportContributors(binder)); if (defaultPropertySource != null) { this.logger.trace("Creating wrapped config data contributor for default property source"); - contributors.add(ConfigDataEnvironmentContributor.ofExisting(defaultPropertySource)); + contributors.add(ConfigDataEnvironmentContributor.ofExisting(defaultPropertySource, + this.environment.getConversionService())); } return createContributors(contributors); } protected ConfigDataEnvironmentContributors createContributors( List contributors) { - return new ConfigDataEnvironmentContributors(this.logFactory, this.bootstrapContext, contributors); + return new ConfigDataEnvironmentContributors(this.logFactory, this.bootstrapContext, contributors, + this.environment.getConversionService()); } ConfigDataEnvironmentContributors getContributors() { @@ -215,7 +218,7 @@ class ConfigDataEnvironment { private ConfigDataEnvironmentContributor createInitialImportContributor(ConfigDataLocation location) { this.logger.trace(LogMessage.format("Adding initial config data import from location '%s'", location)); - return ConfigDataEnvironmentContributor.ofInitialImport(location); + return ConfigDataEnvironmentContributor.ofInitialImport(location, this.environment.getConversionService()); } /** @@ -288,7 +291,7 @@ class ConfigDataEnvironment { private Collection getIncludedProfiles(ConfigDataEnvironmentContributors contributors, ConfigDataActivationContext activationContext) { PlaceholdersResolver placeholdersResolver = new ConfigDataEnvironmentContributorPlaceholdersResolver( - contributors, activationContext, null, true); + contributors, activationContext, null, true, this.environment.getConversionService()); Set result = new LinkedHashSet<>(); for (ConfigDataEnvironmentContributor contributor : contributors) { ConfigurationPropertySource source = contributor.getConfigurationPropertySource(); diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataEnvironmentContributor.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataEnvironmentContributor.java index dc2dcd45aa..4d74198c1e 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataEnvironmentContributor.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataEnvironmentContributor.java @@ -29,6 +29,7 @@ import java.util.stream.StreamSupport; import org.springframework.boot.context.properties.bind.Binder; import org.springframework.boot.context.properties.bind.PlaceholdersResolver; import org.springframework.boot.context.properties.source.ConfigurationPropertySource; +import org.springframework.core.convert.ConversionService; import org.springframework.core.env.Environment; import org.springframework.core.env.PropertySource; import org.springframework.util.CollectionUtils; @@ -74,6 +75,8 @@ class ConfigDataEnvironmentContributor implements Iterable propertySource, ConfigurationPropertySource configurationPropertySource, ConfigDataProperties properties, - ConfigData.Options configDataOptions, Map> children) { + ConfigData.Options configDataOptions, Map> children, + ConversionService conversionService) { this.kind = kind; this.location = location; this.resource = resource; @@ -101,6 +106,7 @@ class ConfigDataEnvironmentContributor implements Iterable sources = Collections.singleton(getConfigurationPropertySource()); PlaceholdersResolver placeholdersResolver = new ConfigDataEnvironmentContributorPlaceholdersResolver( - contributors, activationContext, this, true); + contributors, activationContext, this, true, this.conversionService); Binder binder = new Binder(sources, placeholdersResolver, null, null, null); ConfigDataProperties properties = ConfigDataProperties.get(binder); if (properties != null && this.configDataOptions.contains(ConfigData.Option.IGNORE_IMPORTS)) { @@ -243,7 +249,7 @@ class ConfigDataEnvironmentContributor implements Iterable> children) { @@ -337,7 +343,7 @@ class ConfigDataEnvironmentContributor implements Iterable contributors) { + static ConfigDataEnvironmentContributor of(List contributors, + ConversionService conversionService) { Map> children = new LinkedHashMap<>(); children.put(ImportPhase.BEFORE_PROFILE_ACTIVATION, Collections.unmodifiableList(contributors)); - return new ConfigDataEnvironmentContributor(Kind.ROOT, null, null, false, null, null, null, null, children); + return new ConfigDataEnvironmentContributor(Kind.ROOT, null, null, false, null, null, null, null, children, + conversionService); } /** @@ -383,13 +392,15 @@ class ConfigDataEnvironmentContributor implements Iterable imports = Collections.singletonList(initialImport); ConfigDataProperties properties = new ConfigDataProperties(imports, null); return new ConfigDataEnvironmentContributor(Kind.INITIAL_IMPORT, null, null, false, null, null, properties, - null, null); + null, null, conversionService); } /** @@ -397,11 +408,13 @@ class ConfigDataEnvironmentContributor implements Iterable propertySource) { + static ConfigDataEnvironmentContributor ofExisting(PropertySource propertySource, + ConversionService conversionService) { return new ConfigDataEnvironmentContributor(Kind.EXISTING, null, null, false, propertySource, - ConfigurationPropertySource.from(propertySource), null, null, null); + ConfigurationPropertySource.from(propertySource), null, null, null, conversionService); } /** @@ -413,26 +426,30 @@ class ConfigDataEnvironmentContributor implements Iterable propertySource = configData.getPropertySources().get(propertySourceIndex); ConfigData.Options options = configData.getOptions(propertySource); ConfigurationPropertySource configurationPropertySource = ConfigurationPropertySource.from(propertySource); return new ConfigDataEnvironmentContributor(Kind.UNBOUND_IMPORT, location, resource, profileSpecific, - propertySource, configurationPropertySource, null, options, null); + propertySource, configurationPropertySource, null, options, null, conversionService); } /** * Factory method to create an {@link Kind#EMPTY_LOCATION empty location} contributor. * @param location the location of this contributor * @param profileSpecific if the contributor is from a profile specific import + * @param conversionService the conversion service to use * @return a new {@link ConfigDataEnvironmentContributor} instance */ - static ConfigDataEnvironmentContributor ofEmptyLocation(ConfigDataLocation location, boolean profileSpecific) { + static ConfigDataEnvironmentContributor ofEmptyLocation(ConfigDataLocation location, boolean profileSpecific, + ConversionService conversionService) { return new ConfigDataEnvironmentContributor(Kind.EMPTY_LOCATION, location, null, profileSpecific, null, null, - null, EMPTY_LOCATION_OPTIONS, null); + null, EMPTY_LOCATION_OPTIONS, null, conversionService); } /** diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataEnvironmentContributorPlaceholdersResolver.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataEnvironmentContributorPlaceholdersResolver.java index c7a26a98fd..111a84f5a5 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataEnvironmentContributorPlaceholdersResolver.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataEnvironmentContributorPlaceholdersResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2024 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. @@ -20,6 +20,7 @@ import org.springframework.boot.context.config.ConfigDataEnvironmentContributor. import org.springframework.boot.context.properties.bind.PlaceholdersResolver; import org.springframework.boot.origin.Origin; import org.springframework.boot.origin.OriginLookup; +import org.springframework.core.convert.ConversionService; import org.springframework.core.env.PropertySource; import org.springframework.util.PropertyPlaceholderHelper; import org.springframework.util.SystemPropertyUtils; @@ -30,6 +31,7 @@ import org.springframework.util.SystemPropertyUtils; * * @author Phillip Webb * @author Madhura Bhave + * @author Moritz Halbritter */ class ConfigDataEnvironmentContributorPlaceholdersResolver implements PlaceholdersResolver { @@ -43,13 +45,16 @@ class ConfigDataEnvironmentContributorPlaceholdersResolver implements Placeholde private final ConfigDataEnvironmentContributor activeContributor; + private final ConversionService conversionService; + ConfigDataEnvironmentContributorPlaceholdersResolver(Iterable contributors, ConfigDataActivationContext activationContext, ConfigDataEnvironmentContributor activeContributor, - boolean failOnResolveFromInactiveContributor) { + boolean failOnResolveFromInactiveContributor, ConversionService conversionService) { this.contributors = contributors; this.activationContext = activationContext; this.activeContributor = activeContributor; this.failOnResolveFromInactiveContributor = failOnResolveFromInactiveContributor; + this.conversionService = conversionService; this.helper = new PropertyPlaceholderHelper(SystemPropertyUtils.PLACEHOLDER_PREFIX, SystemPropertyUtils.PLACEHOLDER_SUFFIX, SystemPropertyUtils.VALUE_SEPARATOR, true); } @@ -77,7 +82,7 @@ class ConfigDataEnvironmentContributorPlaceholdersResolver implements Placeholde } result = (result != null) ? result : value; } - return (result != null) ? String.valueOf(result) : null; + return (result != null) ? convertValueIfNecessary(result) : null; } private boolean isActive(ConfigDataEnvironmentContributor contributor) { @@ -91,4 +96,11 @@ class ConfigDataEnvironmentContributorPlaceholdersResolver implements Placeholde .isActive(this.activationContext); } + private String convertValueIfNecessary(Object value) { + if (value instanceof String string) { + return string; + } + return this.conversionService.convert(value, String.class); + } + } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataEnvironmentContributors.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataEnvironmentContributors.java index ca6bf96784..84b21ee1a5 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataEnvironmentContributors.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigDataEnvironmentContributors.java @@ -39,6 +39,7 @@ import org.springframework.boot.context.properties.bind.PlaceholdersResolver; import org.springframework.boot.context.properties.source.ConfigurationPropertyName; import org.springframework.boot.context.properties.source.ConfigurationPropertySource; import org.springframework.boot.logging.DeferredLogFactory; +import org.springframework.core.convert.ConversionService; import org.springframework.core.log.LogMessage; import org.springframework.util.ObjectUtils; @@ -59,24 +60,29 @@ class ConfigDataEnvironmentContributors implements Iterable contributors) { + List contributors, ConversionService conversionService) { this.logger = logFactory.getLog(getClass()); this.bootstrapContext = bootstrapContext; - this.root = ConfigDataEnvironmentContributor.of(contributors); + this.root = ConfigDataEnvironmentContributor.of(contributors, conversionService); + this.conversionService = conversionService; } private ConfigDataEnvironmentContributors(Log logger, ConfigurableBootstrapContext bootstrapContext, - ConfigDataEnvironmentContributor root) { + ConfigDataEnvironmentContributor root, ConversionService conversionService) { this.logger = logger; this.bootstrapContext = bootstrapContext; this.root = root; + this.conversionService = conversionService; } /** @@ -104,7 +110,7 @@ class ConfigDataEnvironmentContributors implements Iterable= 0; i--) { contributors.add(ConfigDataEnvironmentContributor.ofUnboundImport(location, resource, - profileSpecific, data, i)); + profileSpecific, data, i, this.conversionService)); } } }); @@ -214,7 +221,7 @@ class ConfigDataEnvironmentContributors implements Iterable sources = () -> getBinderSources( filter.and((contributor) -> failOnInactiveSource || contributor.isActive(activationContext))); PlaceholdersResolver placeholdersResolver = new ConfigDataEnvironmentContributorPlaceholdersResolver(this.root, - activationContext, null, failOnInactiveSource); + activationContext, null, failOnInactiveSource, this.conversionService); BindHandler bindHandler = !failOnInactiveSource ? null : new InactiveSourceChecker(activationContext); return new Binder(sources, placeholdersResolver, null, null, bindHandler); } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentContributorPlaceholdersResolverTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentContributorPlaceholdersResolverTests.java index 23022678f5..d7993fd99e 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentContributorPlaceholdersResolverTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentContributorPlaceholdersResolverTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2024 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. @@ -27,6 +27,9 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.origin.Origin; import org.springframework.boot.origin.OriginLookup; import org.springframework.boot.origin.PropertySourceOrigin; +import org.springframework.core.convert.ConversionService; +import org.springframework.core.convert.support.DefaultConversionService; +import org.springframework.core.convert.support.GenericConversionService; import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.PropertySource; @@ -38,42 +41,63 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; * * @author Phillip Webb * @author Madhura Bhave + * @author Moritz Halbritter */ class ConfigDataEnvironmentContributorPlaceholdersResolverTests { + private final ConversionService conversionService = DefaultConversionService.getSharedInstance(); + @Test void resolvePlaceholdersWhenNotStringReturnsResolved() { ConfigDataEnvironmentContributorPlaceholdersResolver resolver = new ConfigDataEnvironmentContributorPlaceholdersResolver( - Collections.emptyList(), null, null, false); + Collections.emptyList(), null, null, false, this.conversionService); assertThat(resolver.resolvePlaceholders(123)).isEqualTo(123); } @Test void resolvePlaceholdersWhenNotFoundReturnsOriginal() { ConfigDataEnvironmentContributorPlaceholdersResolver resolver = new ConfigDataEnvironmentContributorPlaceholdersResolver( - Collections.emptyList(), null, null, false); + Collections.emptyList(), null, null, false, this.conversionService); assertThat(resolver.resolvePlaceholders("${test}")).isEqualTo("${test}"); } @Test void resolvePlaceholdersWhenFoundReturnsFirstMatch() { List contributors = new ArrayList<>(); - contributors.add(new TestConfigDataEnvironmentContributor(new TestPropertySource("s1", "nope", "t1"), true)); - contributors.add(new TestConfigDataEnvironmentContributor(new TestPropertySource("s2", "test", "t2"), true)); - contributors.add(new TestConfigDataEnvironmentContributor(new TestPropertySource("s3", "test", "t3"), true)); + contributors.add(new TestConfigDataEnvironmentContributor(new TestPropertySource("s1", "nope", "t1"), true, + this.conversionService)); + contributors.add(new TestConfigDataEnvironmentContributor(new TestPropertySource("s2", "test", "t2"), true, + this.conversionService)); + contributors.add(new TestConfigDataEnvironmentContributor(new TestPropertySource("s3", "test", "t3"), true, + this.conversionService)); ConfigDataEnvironmentContributorPlaceholdersResolver resolver = new ConfigDataEnvironmentContributorPlaceholdersResolver( - contributors, null, null, true); + contributors, null, null, true, this.conversionService); assertThat(resolver.resolvePlaceholders("${test}")).isEqualTo("t2"); } + @Test + void shouldUseConversionService() { + GenericConversionService conversionService = new GenericConversionService(); + conversionService.addConverter(CustomValue.class, String.class, (input) -> "custom-value"); + List contributors = new ArrayList<>(); + contributors.add(new TestConfigDataEnvironmentContributor( + new TestPropertySource("s1", Map.of("test", new CustomValue())), true, conversionService)); + ConfigDataEnvironmentContributorPlaceholdersResolver resolver = new ConfigDataEnvironmentContributorPlaceholdersResolver( + contributors, null, null, true, conversionService); + assertThat(resolver.resolvePlaceholders("${test}")).isEqualTo("custom-value"); + } + @Test void resolvePlaceholdersWhenFoundInInactiveThrowsException() { List contributors = new ArrayList<>(); - contributors.add(new TestConfigDataEnvironmentContributor(new TestPropertySource("s1", "nope", "t1"), true)); - contributors.add(new TestConfigDataEnvironmentContributor(new TestPropertySource("s2", "test", "t2"), true)); - contributors.add(new TestConfigDataEnvironmentContributor(new TestPropertySource("s3", "test", "t3"), false)); + contributors.add(new TestConfigDataEnvironmentContributor(new TestPropertySource("s1", "nope", "t1"), true, + this.conversionService)); + contributors.add(new TestConfigDataEnvironmentContributor(new TestPropertySource("s2", "test", "t2"), true, + this.conversionService)); + contributors.add(new TestConfigDataEnvironmentContributor(new TestPropertySource("s3", "test", "t3"), false, + this.conversionService)); ConfigDataEnvironmentContributorPlaceholdersResolver resolver = new ConfigDataEnvironmentContributorPlaceholdersResolver( - contributors, null, null, true); + contributors, null, null, true, this.conversionService); assertThatExceptionOfType(InactiveConfigDataAccessException.class) .isThrownBy(() -> resolver.resolvePlaceholders("${test}")) .satisfies(propertyNameAndOriginOf("test", "s3")); @@ -82,11 +106,14 @@ class ConfigDataEnvironmentContributorPlaceholdersResolverTests { @Test void resolvePlaceholderWhenFoundInInactiveAndIgnoringReturnsResolved() { List contributors = new ArrayList<>(); - contributors.add(new TestConfigDataEnvironmentContributor(new TestPropertySource("s1", "nope", "t1"), true)); - contributors.add(new TestConfigDataEnvironmentContributor(new TestPropertySource("s2", "test", "t2"), true)); - contributors.add(new TestConfigDataEnvironmentContributor(new TestPropertySource("s3", "test", "t3"), false)); + contributors.add(new TestConfigDataEnvironmentContributor(new TestPropertySource("s1", "nope", "t1"), true, + this.conversionService)); + contributors.add(new TestConfigDataEnvironmentContributor(new TestPropertySource("s2", "test", "t2"), true, + this.conversionService)); + contributors.add(new TestConfigDataEnvironmentContributor(new TestPropertySource("s3", "test", "t3"), false, + this.conversionService)); ConfigDataEnvironmentContributorPlaceholdersResolver resolver = new ConfigDataEnvironmentContributorPlaceholdersResolver( - contributors, null, null, false); + contributors, null, null, false, this.conversionService); assertThat(resolver.resolvePlaceholders("${test}")).isEqualTo("t2"); } @@ -121,8 +148,9 @@ class ConfigDataEnvironmentContributorPlaceholdersResolverTests { private final boolean active; - protected TestConfigDataEnvironmentContributor(PropertySource propertySource, boolean active) { - super(Kind.ROOT, null, null, false, propertySource, null, null, null, null); + protected TestConfigDataEnvironmentContributor(PropertySource propertySource, boolean active, + ConversionService conversionService) { + super(Kind.ROOT, null, null, false, propertySource, null, null, null, null, conversionService); this.active = active; } @@ -133,4 +161,8 @@ class ConfigDataEnvironmentContributorPlaceholdersResolverTests { } + private static final class CustomValue { + + } + } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentContributorTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentContributorTests.java index 38be31e1a8..e18ec561f8 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentContributorTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentContributorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2024 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. @@ -31,6 +31,8 @@ import org.springframework.boot.context.config.ConfigData.PropertySourceOptions; import org.springframework.boot.context.config.ConfigDataEnvironmentContributor.ImportPhase; import org.springframework.boot.context.config.ConfigDataEnvironmentContributor.Kind; import org.springframework.boot.context.properties.source.ConfigurationPropertyName; +import org.springframework.core.convert.ConversionService; +import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.mock.env.MockPropertySource; import static org.assertj.core.api.Assertions.assertThat; @@ -50,15 +52,19 @@ class ConfigDataEnvironmentContributorTests { private final ConfigDataActivationContext activationContext = new ConfigDataActivationContext( CloudPlatform.KUBERNETES, null); + private final ConversionService conversionService = DefaultConversionService.getSharedInstance(); + @Test void getKindReturnsKind() { - ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(TEST_LOCATION); + ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(TEST_LOCATION, + this.conversionService); assertThat(contributor.getKind()).isEqualTo(Kind.INITIAL_IMPORT); } @Test void isActiveWhenPropertiesIsNullReturnsTrue() { - ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(TEST_LOCATION); + ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(TEST_LOCATION, + this.conversionService); assertThat(contributor.isActive(null)).isTrue(); } @@ -85,14 +91,15 @@ class ConfigDataEnvironmentContributorTests { ConfigData configData = new ConfigData(Collections.singleton(new MockPropertySource())); ConfigDataResource resource = mock(ConfigDataResource.class); ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofUnboundImport(TEST_LOCATION, - resource, false, configData, 0); + resource, false, configData, 0, this.conversionService); assertThat(contributor.getResource()).isSameAs(resource); } @Test void getPropertySourceReturnsPropertySource() { MockPropertySource propertySource = new MockPropertySource(); - ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofExisting(propertySource); + ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofExisting(propertySource, + this.conversionService); assertThat(contributor.getPropertySource()).isSameAs(propertySource); } @@ -102,7 +109,7 @@ class ConfigDataEnvironmentContributorTests { propertySource.setProperty("spring", "boot"); ConfigData configData = new ConfigData(Collections.singleton(propertySource)); ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofUnboundImport(null, null, - false, configData, 0); + false, configData, 0, this.conversionService); assertThat(contributor.getConfigurationPropertySource() .getConfigurationProperty(ConfigurationPropertyName.of("spring")) .getValue()).isEqualTo("boot"); @@ -267,7 +274,8 @@ class ConfigDataEnvironmentContributorTests { void ofCreatesRootContributor() { ConfigDataEnvironmentContributor one = createBoundContributor("one"); ConfigDataEnvironmentContributor two = createBoundContributor("two"); - ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.of(Arrays.asList(one, two)); + ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.of(Arrays.asList(one, two), + this.conversionService); assertThat(contributor.getKind()).isEqualTo(Kind.ROOT); assertThat(contributor.getResource()).isNull(); assertThat(contributor.getImports()).isEmpty(); @@ -279,7 +287,8 @@ class ConfigDataEnvironmentContributorTests { @Test void ofInitialImportCreatedInitialImportContributor() { - ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(TEST_LOCATION); + ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(TEST_LOCATION, + this.conversionService); assertThat(contributor.getKind()).isEqualTo(Kind.INITIAL_IMPORT); assertThat(contributor.getResource()).isNull(); assertThat(contributor.getImports()).containsExactly(TEST_LOCATION); @@ -294,7 +303,8 @@ class ConfigDataEnvironmentContributorTests { MockPropertySource propertySource = new MockPropertySource(); propertySource.setProperty("spring.config.import", "test"); propertySource.setProperty("spring.config.activate.on-cloud-platform", "cloudfoundry"); - ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofExisting(propertySource); + ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofExisting(propertySource, + this.conversionService); assertThat(contributor.getKind()).isEqualTo(Kind.EXISTING); assertThat(contributor.getResource()).isNull(); assertThat(contributor.getImports()).isEmpty(); // Properties must not be bound @@ -311,7 +321,7 @@ class ConfigDataEnvironmentContributorTests { propertySource.setProperty("spring.config.import", "test"); ConfigData configData = new ConfigData(Collections.singleton(propertySource)); ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofUnboundImport(TEST_LOCATION, - resource, false, configData, 0); + resource, false, configData, 0, this.conversionService); assertThat(contributor.getKind()).isEqualTo(Kind.UNBOUND_IMPORT); assertThat(contributor.getResource()).isSameAs(resource); assertThat(contributor.getImports()).isEmpty(); @@ -358,7 +368,7 @@ class ConfigDataEnvironmentContributorTests { TestResource resource = new TestResource("a"); ConfigData configData = new ConfigData(Collections.singleton(new MockPropertySource()), Option.IGNORE_IMPORTS); ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofUnboundImport(TEST_LOCATION, - resource, false, configData, 0); + resource, false, configData, 0, this.conversionService); ConfigDataEnvironmentContributor bound = contributor.withBoundProperties(Collections.singleton(contributor), null); assertThat(bound).isNotNull(); @@ -372,7 +382,7 @@ class ConfigDataEnvironmentContributorTests { private ConfigDataEnvironmentContributor createBoundContributor(ConfigDataResource resource, ConfigData configData, int propertySourceIndex) { ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofUnboundImport(TEST_LOCATION, - resource, false, configData, propertySourceIndex); + resource, false, configData, propertySourceIndex, this.conversionService); return contributor.withBoundProperties(Collections.singleton(contributor), null); } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentContributorsTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentContributorsTests.java index fc2462447d..d721bdcda2 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentContributorsTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentContributorsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2024 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. @@ -37,6 +37,8 @@ import org.springframework.boot.context.config.ConfigDataEnvironmentContributors import org.springframework.boot.context.properties.bind.BindException; import org.springframework.boot.context.properties.bind.Binder; import org.springframework.boot.logging.DeferredLogFactory; +import org.springframework.core.convert.ConversionService; +import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.support.SpringFactoriesLoader; import org.springframework.mock.env.MockEnvironment; @@ -68,9 +70,7 @@ class ConfigDataEnvironmentContributorsTests { private final DefaultBootstrapContext bootstrapContext = new DefaultBootstrapContext(); - private MockEnvironment environment; - - private Binder binder; + private final ConversionService conversionService = DefaultConversionService.getSharedInstance(); private ConfigDataImporter importer; @@ -78,10 +78,10 @@ class ConfigDataEnvironmentContributorsTests { @BeforeEach void setup() { - this.environment = new MockEnvironment(); - this.binder = Binder.get(this.environment); + MockEnvironment environment = new MockEnvironment(); + Binder binder = Binder.get(environment); ConfigDataLocationResolvers resolvers = new ConfigDataLocationResolvers(this.logFactory, this.bootstrapContext, - this.binder, new DefaultResourceLoader(getClass().getClassLoader()), + binder, new DefaultResourceLoader(getClass().getClassLoader()), SpringFactoriesLoader.forDefaultResourceLocation(getClass().getClassLoader())); ConfigDataLoaders loaders = new ConfigDataLoaders(this.logFactory, this.bootstrapContext, SpringFactoriesLoader.forDefaultResourceLocation()); @@ -91,9 +91,10 @@ class ConfigDataEnvironmentContributorsTests { @Test void createCreatesWithInitialContributors() { - ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(LOCATION_1); + ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(LOCATION_1, + this.conversionService); ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory, - this.bootstrapContext, Arrays.asList(contributor)); + this.bootstrapContext, List.of(contributor), this.conversionService); Iterator iterator = contributors.iterator(); assertThat(iterator.next()).isSameAs(contributor); assertThat(iterator.next().getKind()).isEqualTo(Kind.ROOT); @@ -102,9 +103,9 @@ class ConfigDataEnvironmentContributorsTests { @Test void withProcessedImportsWhenHasNoUnprocessedImportsReturnsSameInstance() { ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor - .ofExisting(new MockPropertySource()); + .ofExisting(new MockPropertySource(), this.conversionService); ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory, - this.bootstrapContext, Arrays.asList(contributor)); + this.bootstrapContext, List.of(contributor), this.conversionService); ConfigDataEnvironmentContributors withProcessedImports = contributors.withProcessedImports(this.importer, this.activationContext); assertThat(withProcessedImports).isSameAs(contributors); @@ -113,16 +114,17 @@ class ConfigDataEnvironmentContributorsTests { @Test void withProcessedImportsResolvesAndLoads() { this.importer = mock(ConfigDataImporter.class); - List locations = Arrays.asList(LOCATION_1); + List locations = Collections.singletonList(LOCATION_1); MockPropertySource propertySource = new MockPropertySource(); Map imported = new LinkedHashMap<>(); imported.put(new ConfigDataResolutionResult(LOCATION_1, new TestConfigDataResource("a"), false), - new ConfigData(Arrays.asList(propertySource))); + new ConfigData(List.of(propertySource))); given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(locations))) .willReturn(imported); - ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(LOCATION_1); + ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(LOCATION_1, + this.conversionService); ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory, - this.bootstrapContext, Arrays.asList(contributor)); + this.bootstrapContext, List.of(contributor), this.conversionService); ConfigDataEnvironmentContributors withProcessedImports = contributors.withProcessedImports(this.importer, this.activationContext); Iterator iterator = withProcessedImports.iterator(); @@ -135,24 +137,25 @@ class ConfigDataEnvironmentContributorsTests { @Test void withProcessedImportsResolvesAndLoadsChainedImports() { this.importer = mock(ConfigDataImporter.class); - List initialLocations = Arrays.asList(LOCATION_1); + List initialLocations = Collections.singletonList(LOCATION_1); MockPropertySource initialPropertySource = new MockPropertySource(); initialPropertySource.setProperty("spring.config.import", "location2"); Map initialImported = new LinkedHashMap<>(); initialImported.put(new ConfigDataResolutionResult(LOCATION_1, new TestConfigDataResource("a"), false), - new ConfigData(Arrays.asList(initialPropertySource))); + new ConfigData(List.of(initialPropertySource))); given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(initialLocations))) .willReturn(initialImported); - List secondLocations = Arrays.asList(LOCATION_2); + List secondLocations = Collections.singletonList(LOCATION_2); MockPropertySource secondPropertySource = new MockPropertySource(); Map secondImported = new LinkedHashMap<>(); secondImported.put(new ConfigDataResolutionResult(LOCATION_2, new TestConfigDataResource("b"), false), - new ConfigData(Arrays.asList(secondPropertySource))); + new ConfigData(List.of(secondPropertySource))); given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(secondLocations))) .willReturn(secondImported); - ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(LOCATION_1); + ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(LOCATION_1, + this.conversionService); ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory, - this.bootstrapContext, Arrays.asList(contributor)); + this.bootstrapContext, List.of(contributor), this.conversionService); ConfigDataEnvironmentContributors withProcessedImports = contributors.withProcessedImports(this.importer, this.activationContext); Iterator iterator = withProcessedImports.iterator(); @@ -168,18 +171,19 @@ class ConfigDataEnvironmentContributorsTests { MockPropertySource existingPropertySource = new MockPropertySource(); existingPropertySource.setProperty("test", "springboot"); ConfigDataEnvironmentContributor existingContributor = ConfigDataEnvironmentContributor - .ofExisting(existingPropertySource); + .ofExisting(existingPropertySource, this.conversionService); this.importer = mock(ConfigDataImporter.class); - List locations = Arrays.asList(LOCATION_1); + List locations = Collections.singletonList(LOCATION_1); MockPropertySource propertySource = new MockPropertySource(); Map imported = new LinkedHashMap<>(); imported.put(new ConfigDataResolutionResult(LOCATION_1, new TestConfigDataResource("a'"), false), - new ConfigData(Arrays.asList(propertySource))); + new ConfigData(List.of(propertySource))); given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(locations))) .willReturn(imported); - ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(LOCATION_1); + ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(LOCATION_1, + this.conversionService); ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory, - this.bootstrapContext, Arrays.asList(existingContributor, contributor)); + this.bootstrapContext, Arrays.asList(existingContributor, contributor), this.conversionService); contributors.withProcessedImports(this.importer, this.activationContext); then(this.importer).should() .resolveAndLoad(any(), @@ -191,24 +195,25 @@ class ConfigDataEnvironmentContributorsTests { @Test void withProcessedImportsProvidesLocationResolverContextWithAccessToParent() { this.importer = mock(ConfigDataImporter.class); - List initialLocations = Arrays.asList(LOCATION_1); + List initialLocations = Collections.singletonList(LOCATION_1); MockPropertySource initialPropertySource = new MockPropertySource(); initialPropertySource.setProperty("spring.config.import", "location2"); Map initialImported = new LinkedHashMap<>(); initialImported.put(new ConfigDataResolutionResult(LOCATION_1, new TestConfigDataResource("a"), false), - new ConfigData(Arrays.asList(initialPropertySource))); + new ConfigData(List.of(initialPropertySource))); given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(initialLocations))) .willReturn(initialImported); - List secondLocations = Arrays.asList(LOCATION_2); + List secondLocations = Collections.singletonList(LOCATION_2); MockPropertySource secondPropertySource = new MockPropertySource(); Map secondImported = new LinkedHashMap<>(); secondImported.put(new ConfigDataResolutionResult(LOCATION_2, new TestConfigDataResource("b"), false), - new ConfigData(Arrays.asList(secondPropertySource))); + new ConfigData(List.of(secondPropertySource))); given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(secondLocations))) .willReturn(secondImported); - ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(LOCATION_1); + ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(LOCATION_1, + this.conversionService); ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory, - this.bootstrapContext, Arrays.asList(contributor)); + this.bootstrapContext, List.of(contributor), this.conversionService); ArgumentCaptor locationResolverContext = ArgumentCaptor .forClass(ConfigDataLocationResolverContext.class); contributors.withProcessedImports(this.importer, this.activationContext); @@ -223,18 +228,19 @@ class ConfigDataEnvironmentContributorsTests { MockPropertySource existingPropertySource = new MockPropertySource(); existingPropertySource.setProperty("test", "springboot"); ConfigDataEnvironmentContributor existingContributor = ConfigDataEnvironmentContributor - .ofExisting(existingPropertySource); + .ofExisting(existingPropertySource, this.conversionService); this.importer = mock(ConfigDataImporter.class); - List locations = Arrays.asList(LOCATION_1); + List locations = Collections.singletonList(LOCATION_1); MockPropertySource propertySource = new MockPropertySource(); Map imported = new LinkedHashMap<>(); imported.put(new ConfigDataResolutionResult(LOCATION_1, new TestConfigDataResource("a'"), false), - new ConfigData(Arrays.asList(propertySource))); + new ConfigData(List.of(propertySource))); given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(locations))) .willReturn(imported); - ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(LOCATION_1); + ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(LOCATION_1, + this.conversionService); ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory, - this.bootstrapContext, Arrays.asList(existingContributor, contributor)); + this.bootstrapContext, Arrays.asList(existingContributor, contributor), this.conversionService); contributors.withProcessedImports(this.importer, this.activationContext); then(this.importer).should() .resolveAndLoad(any(), @@ -247,18 +253,19 @@ class ConfigDataEnvironmentContributorsTests { MockPropertySource existingPropertySource = new MockPropertySource(); existingPropertySource.setProperty("test", "springboot"); ConfigDataEnvironmentContributor existingContributor = ConfigDataEnvironmentContributor - .ofExisting(existingPropertySource); + .ofExisting(existingPropertySource, this.conversionService); this.importer = mock(ConfigDataImporter.class); - List locations = Arrays.asList(LOCATION_1); + List locations = Collections.singletonList(LOCATION_1); MockPropertySource propertySource = new MockPropertySource(); Map imported = new LinkedHashMap<>(); imported.put(new ConfigDataResolutionResult(LOCATION_1, new TestConfigDataResource("a'"), false), - new ConfigData(Arrays.asList(propertySource))); + new ConfigData(List.of(propertySource))); given(this.importer.resolveAndLoad(eq(this.activationContext), any(), any(), eq(locations))) .willReturn(imported); - ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(LOCATION_1); + ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofInitialImport(LOCATION_1, + this.conversionService); ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory, - this.bootstrapContext, Arrays.asList(existingContributor, contributor)); + this.bootstrapContext, Arrays.asList(existingContributor, contributor), this.conversionService); contributors.withProcessedImports(this.importer, this.activationContext); then(this.importer).should() .resolveAndLoad(any(), any(), @@ -270,9 +277,10 @@ class ConfigDataEnvironmentContributorsTests { void getBinderProvidesBinder() { MockPropertySource propertySource = new MockPropertySource(); propertySource.setProperty("test", "springboot"); - ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofExisting(propertySource); + ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofExisting(propertySource, + this.conversionService); ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory, - this.bootstrapContext, Arrays.asList(contributor)); + this.bootstrapContext, List.of(contributor), this.conversionService); Binder binder = contributors.getBinder(this.activationContext); assertThat(binder.bind("test", String.class).get()).isEqualTo("springboot"); } @@ -287,7 +295,7 @@ class ConfigDataEnvironmentContributorsTests { ConfigDataEnvironmentContributor firstContributor = createBoundImportContributor(configData, 0); ConfigDataEnvironmentContributor secondContributor = createBoundImportContributor(configData, 1); ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory, - this.bootstrapContext, Arrays.asList(firstContributor, secondContributor)); + this.bootstrapContext, Arrays.asList(firstContributor, secondContributor), this.conversionService); Binder binder = contributors.getBinder(this.activationContext); assertThat(binder.bind("test", String.class).get()).isEqualTo("one"); } @@ -303,7 +311,7 @@ class ConfigDataEnvironmentContributorsTests { ConfigDataEnvironmentContributor firstContributor = createBoundImportContributor(configData, 0); ConfigDataEnvironmentContributor secondContributor = createBoundImportContributor(configData, 1); ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory, - this.bootstrapContext, Arrays.asList(firstContributor, secondContributor)); + this.bootstrapContext, Arrays.asList(firstContributor, secondContributor), this.conversionService); Binder binder = contributors.getBinder(this.activationContext); assertThat(binder.bind("test", String.class).get()).isEqualTo("two"); } @@ -313,9 +321,10 @@ class ConfigDataEnvironmentContributorsTests { MockPropertySource propertySource = new MockPropertySource(); propertySource.setProperty("test", "${other}"); propertySource.setProperty("other", "springboot"); - ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofExisting(propertySource); + ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofExisting(propertySource, + this.conversionService); ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory, - this.bootstrapContext, Arrays.asList(contributor)); + this.bootstrapContext, List.of(contributor), this.conversionService); Binder binder = contributors.getBinder(this.activationContext); assertThat(binder.bind("test", String.class).get()).isEqualTo("springboot"); } @@ -332,7 +341,7 @@ class ConfigDataEnvironmentContributorsTests { ConfigDataEnvironmentContributor firstContributor = createBoundImportContributor(configData, 0); ConfigDataEnvironmentContributor secondContributor = createBoundImportContributor(configData, 1); ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory, - this.bootstrapContext, Arrays.asList(firstContributor, secondContributor)); + this.bootstrapContext, Arrays.asList(firstContributor, secondContributor), this.conversionService); Binder binder = contributors.getBinder(this.activationContext); assertThat(binder.bind("test", String.class).get()).isEqualTo("two"); } @@ -348,7 +357,7 @@ class ConfigDataEnvironmentContributorsTests { ConfigDataEnvironmentContributor firstContributor = createBoundImportContributor(configData, 0); ConfigDataEnvironmentContributor secondContributor = createBoundImportContributor(configData, 1); ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory, - this.bootstrapContext, Arrays.asList(firstContributor, secondContributor)); + this.bootstrapContext, Arrays.asList(firstContributor, secondContributor), this.conversionService); Binder binder = contributors.getBinder(this.activationContext, BinderOption.FAIL_ON_BIND_TO_INACTIVE_SOURCE); assertThatExceptionOfType(BindException.class).isThrownBy(() -> binder.bind("test", String.class)) .satisfies((ex) -> assertThat(ex.getCause()).isInstanceOf(InactiveConfigDataAccessException.class)); @@ -365,7 +374,7 @@ class ConfigDataEnvironmentContributorsTests { ConfigDataEnvironmentContributor firstContributor = createBoundImportContributor(configData, 0); ConfigDataEnvironmentContributor secondContributor = createBoundImportContributor(configData, 1); ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory, - this.bootstrapContext, Arrays.asList(firstContributor, secondContributor)); + this.bootstrapContext, Arrays.asList(firstContributor, secondContributor), this.conversionService); Binder binder = contributors.getBinder(this.activationContext, BinderOption.FAIL_ON_BIND_TO_INACTIVE_SOURCE); assertThatExceptionOfType(BindException.class).isThrownBy(() -> binder.bind("test", String.class)) .satisfies((ex) -> assertThat(ex.getCause()).isInstanceOf(InactiveConfigDataAccessException.class)); @@ -383,7 +392,7 @@ class ConfigDataEnvironmentContributorsTests { ConfigDataEnvironmentContributor firstContributor = createBoundImportContributor(configData, 0); ConfigDataEnvironmentContributor secondContributor = createBoundImportContributor(configData, 1); ConfigDataEnvironmentContributors contributors = new ConfigDataEnvironmentContributors(this.logFactory, - this.bootstrapContext, Arrays.asList(firstContributor, secondContributor)); + this.bootstrapContext, Arrays.asList(firstContributor, secondContributor), this.conversionService); Binder binder = contributors.getBinder(this.activationContext, BinderOption.FAIL_ON_BIND_TO_INACTIVE_SOURCE); assertThatExceptionOfType(BindException.class).isThrownBy(() -> binder.bind("test", String.class)) .satisfies((ex) -> assertThat(ex.getCause()).isInstanceOf(InactiveConfigDataAccessException.class)); @@ -392,7 +401,7 @@ class ConfigDataEnvironmentContributorsTests { private ConfigDataEnvironmentContributor createBoundImportContributor(ConfigData configData, int propertySourceIndex) { ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofUnboundImport(null, null, - false, configData, propertySourceIndex); + false, configData, propertySourceIndex, this.conversionService); return contributor.withBoundProperties(Collections.singleton(contributor), null); } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentTests.java index fdad67f2e0..d602bf2154 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigDataEnvironmentTests.java @@ -42,6 +42,8 @@ import org.springframework.boot.context.config.ConfigDataEnvironmentContributor. import org.springframework.boot.context.config.TestConfigDataEnvironmentUpdateListener.AddedPropertySource; import org.springframework.boot.context.properties.bind.Binder; import org.springframework.boot.logging.DeferredLogFactory; +import org.springframework.core.convert.ConversionService; +import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.PropertySource; @@ -73,6 +75,8 @@ class ConfigDataEnvironmentTests { private final Collection additionalProfiles = Collections.emptyList(); + private final ConversionService conversionService = DefaultConversionService.getSharedInstance(); + @Test void createExposesEnvironmentBinderToConfigDataLocationResolvers() { this.environment.setProperty("spring", "boot"); @@ -217,7 +221,8 @@ class ConfigDataEnvironmentTests { ConfigData data = new ConfigData(Collections.singleton(new MapPropertySource("test", source)), ConfigData.Option.IGNORE_PROFILES); contributors.add(ConfigDataEnvironmentContributor.ofUnboundImport(ConfigDataLocation.of("test"), - mock(ConfigDataResource.class), false, data, 0)); + mock(ConfigDataResource.class), false, data, 0, + ConfigDataEnvironmentTests.this.conversionService)); return super.createContributors(contributors); } @@ -241,7 +246,8 @@ class ConfigDataEnvironmentTests { source.put("spring.profiles." + property, "include"); ConfigData data = new ConfigData(Collections.singleton(new MapPropertySource("test", source))); contributors.add(ConfigDataEnvironmentContributor.ofUnboundImport(ConfigDataLocation.of("test"), - mock(ConfigDataResource.class), false, data, 0)); + mock(ConfigDataResource.class), false, data, 0, + ConfigDataEnvironmentTests.this.conversionService)); return super.createContributors(contributors); } @@ -264,7 +270,8 @@ class ConfigDataEnvironmentTests { source.put(property, "included"); ConfigData data = new ConfigData(Collections.singleton(new MapPropertySource("test", source))); contributors.add(ConfigDataEnvironmentContributor.ofUnboundImport(ConfigDataLocation.of("test"), - mock(ConfigDataResource.class), false, data, 0)); + mock(ConfigDataResource.class), false, data, 0, + ConfigDataEnvironmentTests.this.conversionService)); return super.createContributors(contributors); } @@ -288,7 +295,8 @@ class ConfigDataEnvironmentTests { ConfigData data = new ConfigData(Collections.singleton(new MapPropertySource("test", source)), ConfigData.Option.IGNORE_PROFILES); contributors.add(ConfigDataEnvironmentContributor.ofUnboundImport(ConfigDataLocation.of("test"), - mock(ConfigDataResource.class), false, data, 0)); + mock(ConfigDataResource.class), false, data, 0, + ConfigDataEnvironmentTests.this.conversionService)); return super.createContributors(contributors); } @@ -305,7 +313,7 @@ class ConfigDataEnvironmentTests { ConfigDataEnvironment configDataEnvironment = new ConfigDataEnvironment(this.logFactory, this.bootstrapContext, this.environment, this.resourceLoader, this.additionalProfiles, null); assertThatExceptionOfType(InvalidConfigDataPropertyException.class) - .isThrownBy(() -> configDataEnvironment.processAndApply()); + .isThrownBy(configDataEnvironment::processAndApply); } @Test diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/InvalidConfigDataPropertyExceptionTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/InvalidConfigDataPropertyExceptionTests.java index 4c198709f0..45b54bae9d 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/InvalidConfigDataPropertyExceptionTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/InvalidConfigDataPropertyExceptionTests.java @@ -23,6 +23,8 @@ import org.springframework.boot.context.properties.source.ConfigurationProperty; import org.springframework.boot.context.properties.source.ConfigurationPropertyName; import org.springframework.boot.context.properties.source.ConfigurationPropertySource; import org.springframework.boot.origin.MockOrigin; +import org.springframework.core.convert.ConversionService; +import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.mock.env.MockPropertySource; import static org.assertj.core.api.Assertions.assertThat; @@ -46,6 +48,8 @@ class InvalidConfigDataPropertyExceptionTests { private final ConfigurationProperty property = new ConfigurationProperty(this.invalid, "bad", MockOrigin.of("origin")); + private final ConversionService conversionService = DefaultConversionService.getSharedInstance(); + @Test void createHasCorrectMessage() { assertThat(new InvalidConfigDataPropertyException(this.property, false, this.replacement, this.resource)) @@ -104,7 +108,8 @@ class InvalidConfigDataPropertyExceptionTests { void throwOrWarnWhenHasInvalidPropertyThrowsException() { MockPropertySource propertySource = new MockPropertySource(); propertySource.setProperty("spring.profiles", "a"); - ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofExisting(propertySource); + ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor.ofExisting(propertySource, + this.conversionService); assertThatExceptionOfType(InvalidConfigDataPropertyException.class) .isThrownBy(() -> InvalidConfigDataPropertyException.throwIfPropertyFound(contributor)) .withMessageStartingWith("Property 'spring.profiles' is invalid and should be replaced with " @@ -136,16 +141,15 @@ class InvalidConfigDataPropertyExceptionTests { ConfigData.Option... configDataOptions) { MockPropertySource propertySource = new MockPropertySource(); propertySource.setProperty(name, "a"); - ConfigDataEnvironmentContributor contributor = new ConfigDataEnvironmentContributor(Kind.BOUND_IMPORT, null, - null, true, propertySource, ConfigurationPropertySource.from(propertySource), null, - ConfigData.Options.of(configDataOptions), null); - return contributor; + return new ConfigDataEnvironmentContributor(Kind.BOUND_IMPORT, null, null, true, propertySource, + ConfigurationPropertySource.from(propertySource), null, ConfigData.Options.of(configDataOptions), null, + this.conversionService); } @Test void throwOrWarnWhenHasNoInvalidPropertyDoesNothing() { ConfigDataEnvironmentContributor contributor = ConfigDataEnvironmentContributor - .ofExisting(new MockPropertySource()); + .ofExisting(new MockPropertySource(), this.conversionService); InvalidConfigDataPropertyException.throwIfPropertyFound(contributor); }