diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/Profiles.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/Profiles.java index 92d48b905ee..8230854e703 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/Profiles.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/Profiles.java @@ -62,8 +62,6 @@ public class Profiles implements Iterable { private final List defaultProfiles; - private final List acceptedProfiles; - /** * Create a new {@link Profiles} instance based on the {@link Environment} and * {@link Binder}. @@ -73,11 +71,19 @@ public class Profiles implements Iterable { */ Profiles(Environment environment, Binder binder, Collection additionalProfiles) { this.groups = binder.bind("spring.profiles.group", STRING_STRINGS_MAP).orElseGet(LinkedMultiValueMap::new); - this.activeProfiles = asUniqueItemList(get(environment, binder, environment::getActiveProfiles, + this.activeProfiles = expandProfiles(getActivatedProfiles(environment, binder, additionalProfiles)); + this.defaultProfiles = expandProfiles(getDefaultProfiles(environment, binder)); + } + + private List getActivatedProfiles(Environment environment, Binder binder, + Collection additionalProfiles) { + return asUniqueItemList(get(environment, binder, environment::getActiveProfiles, AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME, UNSET_ACTIVE), additionalProfiles); - this.defaultProfiles = asUniqueItemList(get(environment, binder, environment::getDefaultProfiles, + } + + private List getDefaultProfiles(Environment environment, Binder binder) { + return asUniqueItemList(get(environment, binder, environment::getDefaultProfiles, AbstractEnvironment.DEFAULT_PROFILES_PROPERTY_NAME, UNSET_DEFAULT)); - this.acceptedProfiles = expandAcceptedProfiles(this.activeProfiles, this.defaultProfiles); } private String[] get(Environment environment, Binder binder, Supplier supplier, String propertyName, @@ -99,16 +105,16 @@ public class Profiles implements Iterable { return !propertyProfiles.equals(profiles); } - private List expandAcceptedProfiles(List activeProfiles, List defaultProfiles) { + private List expandProfiles(List profiles) { Deque stack = new ArrayDeque<>(); - asReversedList((!activeProfiles.isEmpty()) ? activeProfiles : defaultProfiles).forEach(stack::push); - Set acceptedProfiles = new LinkedHashSet<>(); + asReversedList(profiles).forEach(stack::push); + Set expandedProfiles = new LinkedHashSet<>(); while (!stack.isEmpty()) { String current = stack.pop(); - acceptedProfiles.add(current); + expandedProfiles.add(current); asReversedList(this.groups.get(current)).forEach(stack::push); } - return asUniqueItemList(StringUtils.toStringArray(acceptedProfiles)); + return asUniqueItemList(StringUtils.toStringArray(expandedProfiles)); } private List asReversedList(List list) { @@ -161,7 +167,7 @@ public class Profiles implements Iterable { * @return the accepted profiles */ public List getAccepted() { - return this.acceptedProfiles; + return (!this.activeProfiles.isEmpty()) ? this.activeProfiles : this.defaultProfiles; } /** @@ -170,7 +176,7 @@ public class Profiles implements Iterable { * @return if the profile is active */ public boolean isAccepted(String profile) { - return this.acceptedProfiles.contains(profile); + return getAccepted().contains(profile); } @Override 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 f564ce1d2a6..a92fde5ed31 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 @@ -174,6 +174,15 @@ class ConfigDataEnvironmentTests { assertThat(this.environment.getActiveProfiles()).containsExactly("one", "two", "three"); } + @Test + void processAndApplySetsActiveProfilesAndProfileGroups(TestInfo info) { + this.environment.setProperty("spring.config.location", getConfigLocation(info)); + ConfigDataEnvironment configDataEnvironment = new ConfigDataEnvironment(this.logFactory, this.environment, + this.resourceLoader, this.additionalProfiles); + configDataEnvironment.processAndApply(); + assertThat(this.environment.getActiveProfiles()).containsExactly("one", "four", "five", "two", "three"); + } + @Test @Disabled("Disabled until spring.profiles suppport is dropped") void processAndApplyWhenHasInvalidPropertyThrowsException() { diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ProfilesTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ProfilesTests.java index c147dd432dd..5271fc52b2f 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ProfilesTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ProfilesTests.java @@ -114,6 +114,16 @@ class ProfilesTests { assertThat(profiles.getActive()).containsExactly("a", "b", "c"); } + @Test + void getActiveWithProfileGroups() { + MockEnvironment environment = new MockEnvironment(); + environment.setProperty("spring.profiles.active", "a,b,c"); + environment.setProperty("spring.profiles.group.a", "d,e"); + Binder binder = Binder.get(environment); + Profiles profiles = new Profiles(environment, binder, null); + assertThat(profiles.getActive()).containsExactly("a", "d", "e", "b", "c"); + } + @Test void getActiveWhenHasAdditionalIncludesAdditional() { MockEnvironment environment = new MockEnvironment(); @@ -189,6 +199,16 @@ class ProfilesTests { assertThat(profiles.getDefault()).containsExactly("a", "b", "c"); } + @Test + void getDefaultWithProfileGroups() { + MockEnvironment environment = new MockEnvironment(); + environment.setProperty("spring.profiles.default", "a,b,c"); + environment.setProperty("spring.profiles.group.a", "d,e"); + Binder binder = Binder.get(environment); + Profiles profiles = new Profiles(environment, binder, null); + assertThat(profiles.getDefault()).containsExactly("a", "d", "e", "b", "c"); + } + @Test void getDefaultWhenEnvironmentProfilesInBindNotationAndEnvironmentPropertyReturnsEnvironmentProfiles() { MockEnvironment environment = new MockEnvironment(); diff --git a/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/context/config/ConfigDataEnvironmentTests-processAndApplySetsActiveProfilesAndProfileGroups.properties b/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/context/config/ConfigDataEnvironmentTests-processAndApplySetsActiveProfilesAndProfileGroups.properties new file mode 100644 index 00000000000..74de2859947 --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/context/config/ConfigDataEnvironmentTests-processAndApplySetsActiveProfilesAndProfileGroups.properties @@ -0,0 +1,2 @@ +spring.profiles.active=one,two,three +spring.profiles.group.one=four,five