Skip to content

Commit df9de81

Browse files
committed
Let spring.profiles.[include|active] accept list as well as comma separated value in bootstrapProperties
Fix GH-1417 GH-1329 Signed-off-by: Yanming Zhou <zhouyanming@gmail.com>
1 parent a3ef42f commit df9de81

File tree

2 files changed

+43
-22
lines changed

2 files changed

+43
-22
lines changed

spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/config/PropertySourceBootstrapConfiguration.java

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
import org.springframework.boot.context.properties.EnableConfigurationProperties;
3535
import org.springframework.boot.context.properties.bind.Bindable;
3636
import org.springframework.boot.context.properties.bind.Binder;
37+
import org.springframework.boot.context.properties.bind.PropertySourcesPlaceholdersResolver;
38+
import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
3739
import org.springframework.boot.logging.LogFile;
3840
import org.springframework.boot.logging.LoggingInitializationContext;
3941
import org.springframework.boot.logging.LoggingSystem;
@@ -46,6 +48,7 @@
4648
import org.springframework.context.annotation.Configuration;
4749
import org.springframework.context.event.ContextRefreshedEvent;
4850
import org.springframework.core.Ordered;
51+
import org.springframework.core.ResolvableType;
4952
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
5053
import org.springframework.core.env.AbstractEnvironment;
5154
import org.springframework.core.env.CompositePropertySource;
@@ -54,13 +57,13 @@
5457
import org.springframework.core.env.Environment;
5558
import org.springframework.core.env.MutablePropertySources;
5659
import org.springframework.core.env.PropertySource;
57-
import org.springframework.util.StringUtils;
5860

5961
import static org.springframework.cloud.bootstrap.encrypt.AbstractEnvironmentDecrypt.DECRYPTED_PROPERTY_SOURCE_NAME;
6062
import static org.springframework.core.env.StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME;
6163

6264
/**
6365
* @author Dave Syer
66+
* @author Yanming Zhou
6467
*
6568
*/
6669
@Configuration(proxyBeanMethods = false)
@@ -294,6 +297,7 @@ private List<String> addActiveProfilesTo(List<String> profiles, PropertySource<?
294297
return addProfilesTo(profiles, propertySource, AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME, environment);
295298
}
296299

300+
@SuppressWarnings("unchecked")
297301
private <T extends Collection<String>> T addProfilesTo(T profiles, PropertySource<?> propertySource,
298302
String property, ConfigurableEnvironment environment) {
299303
if (propertySource instanceof CompositePropertySource) {
@@ -303,27 +307,19 @@ private <T extends Collection<String>> T addProfilesTo(T profiles, PropertySourc
303307
}
304308
}
305309
else {
306-
Collections.addAll(profiles, getProfilesForValue(propertySource.getProperty(property), environment));
310+
// bootstrapProperties is loaded as package-private
311+
// ConfigurationPropertySourcesPropertySource
312+
ResolvableType requiredType = ResolvableType.forClassWithGenerics(PropertySource.class,
313+
ResolvableType.forClassWithGenerics(Iterable.class, ConfigurationPropertySource.class));
314+
if (requiredType.isInstance(propertySource)) {
315+
Binder binder = new Binder((Iterable<ConfigurationPropertySource>) propertySource.getSource(),
316+
new PropertySourcesPlaceholdersResolver(environment));
317+
binder.bind(property, Bindable.listOf(String.class)).ifBound(profiles::addAll);
318+
}
307319
}
308320
return profiles;
309321
}
310322

311-
private String[] getProfilesForValue(Object property, ConfigurableEnvironment environment) {
312-
final String value = (property == null ? null : property.toString());
313-
return property == null ? new String[0] : resolvePlaceholdersInProfiles(value, environment);
314-
}
315-
316-
private String[] resolvePlaceholdersInProfiles(String profiles, ConfigurableEnvironment environment) {
317-
return Arrays.stream(StringUtils.tokenizeToStringArray(profiles, ",")).map(s -> {
318-
if (s.startsWith("${") && s.endsWith("}")) {
319-
return environment.resolvePlaceholders(s);
320-
}
321-
else {
322-
return s;
323-
}
324-
}).toArray(String[]::new);
325-
}
326-
327323
/*
328324
* The ConextRefreshedEvent gets called at the end of the boostrap phase after config
329325
* data is loaded during bootstrap. This will run and do an "initial fetch" of

spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/config/BootstrapConfigurationTests.java

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,20 @@ public void includeProfileFromBootstrapPropertySourceWithAppContext() {
597597

598598
private void includeProfileFromBootstrapPropertySource(String... properties) {
599599
PropertySourceConfiguration.MAP.put("spring.profiles.include", "bar,baz");
600-
context = new SpringApplicationBuilder().web(WebApplicationType.NONE)
600+
assertIncludeProfileFromBootstrapPropertySource(properties);
601+
602+
PropertySourceConfiguration.MAP.clear();
603+
PropertySourceConfiguration.MAP.put("spring.profiles.include[0]", "bar");
604+
PropertySourceConfiguration.MAP.put("spring.profiles.include[1]", "baz");
605+
assertIncludeProfileFromBootstrapPropertySource(properties);
606+
607+
PropertySourceConfiguration.MAP.clear();
608+
PropertySourceConfiguration.MAP.put("spring.profiles.include", "${ENVIRONMENT_PROFILE_NAME:bar,baz}");
609+
assertIncludeProfileFromBootstrapPropertySource(properties);
610+
}
611+
612+
private void assertIncludeProfileFromBootstrapPropertySource(String... properties) {
613+
this.context = new SpringApplicationBuilder().web(WebApplicationType.NONE)
601614
.properties(properties)
602615
.profiles("foo")
603616
.sources(BareConfiguration.class)
@@ -622,13 +635,25 @@ public void activeProfileFromBootstrapPropertySourceWithAppContext() {
622635

623636
private void activeProfileFromBootstrapPropertySource(String... properties) {
624637
PropertySourceConfiguration.MAP.put("spring.profiles.active", "bar,baz");
625-
context = new SpringApplicationBuilder().web(WebApplicationType.NONE)
638+
assertActiveProfileFromBootstrapPropertySource(properties);
639+
640+
PropertySourceConfiguration.MAP.clear();
641+
PropertySourceConfiguration.MAP.put("spring.profiles.active[0]", "bar");
642+
PropertySourceConfiguration.MAP.put("spring.profiles.active[1]", "baz");
643+
assertActiveProfileFromBootstrapPropertySource(properties);
644+
645+
PropertySourceConfiguration.MAP.clear();
646+
PropertySourceConfiguration.MAP.put("spring.profiles.active", "${ENVIRONMENT_PROFILE_NAME:bar,baz}");
647+
assertActiveProfileFromBootstrapPropertySource(properties);
648+
}
649+
650+
private void assertActiveProfileFromBootstrapPropertySource(String... properties) {
651+
this.context = new SpringApplicationBuilder().web(WebApplicationType.NONE)
626652
.properties(properties)
627653
.profiles("foo")
628654
.sources(BareConfiguration.class)
629655
.run();
630-
then(context.getEnvironment().acceptsProfiles("baz", "bar", "foo")).isTrue();
631-
656+
then(this.context.getEnvironment().acceptsProfiles("baz", "bar", "foo")).isTrue();
632657
}
633658

634659
@Test

0 commit comments

Comments
 (0)