Commit 8d70010f authored by Madhura Bhave's avatar Madhura Bhave

Add expanded profile groups to environment

Fixes gh-22605
parent ddb4de2d
...@@ -62,8 +62,6 @@ public class Profiles implements Iterable<String> { ...@@ -62,8 +62,6 @@ public class Profiles implements Iterable<String> {
private final List<String> defaultProfiles; private final List<String> defaultProfiles;
private final List<String> acceptedProfiles;
/** /**
* Create a new {@link Profiles} instance based on the {@link Environment} and * Create a new {@link Profiles} instance based on the {@link Environment} and
* {@link Binder}. * {@link Binder}.
...@@ -73,11 +71,19 @@ public class Profiles implements Iterable<String> { ...@@ -73,11 +71,19 @@ public class Profiles implements Iterable<String> {
*/ */
Profiles(Environment environment, Binder binder, Collection<String> additionalProfiles) { Profiles(Environment environment, Binder binder, Collection<String> additionalProfiles) {
this.groups = binder.bind("spring.profiles.group", STRING_STRINGS_MAP).orElseGet(LinkedMultiValueMap::new); 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<String> getActivatedProfiles(Environment environment, Binder binder,
Collection<String> additionalProfiles) {
return asUniqueItemList(get(environment, binder, environment::getActiveProfiles,
AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME, UNSET_ACTIVE), additionalProfiles); AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME, UNSET_ACTIVE), additionalProfiles);
this.defaultProfiles = asUniqueItemList(get(environment, binder, environment::getDefaultProfiles, }
private List<String> getDefaultProfiles(Environment environment, Binder binder) {
return asUniqueItemList(get(environment, binder, environment::getDefaultProfiles,
AbstractEnvironment.DEFAULT_PROFILES_PROPERTY_NAME, UNSET_DEFAULT)); AbstractEnvironment.DEFAULT_PROFILES_PROPERTY_NAME, UNSET_DEFAULT));
this.acceptedProfiles = expandAcceptedProfiles(this.activeProfiles, this.defaultProfiles);
} }
private String[] get(Environment environment, Binder binder, Supplier<String[]> supplier, String propertyName, private String[] get(Environment environment, Binder binder, Supplier<String[]> supplier, String propertyName,
...@@ -99,16 +105,16 @@ public class Profiles implements Iterable<String> { ...@@ -99,16 +105,16 @@ public class Profiles implements Iterable<String> {
return !propertyProfiles.equals(profiles); return !propertyProfiles.equals(profiles);
} }
private List<String> expandAcceptedProfiles(List<String> activeProfiles, List<String> defaultProfiles) { private List<String> expandProfiles(List<String> profiles) {
Deque<String> stack = new ArrayDeque<>(); Deque<String> stack = new ArrayDeque<>();
asReversedList((!activeProfiles.isEmpty()) ? activeProfiles : defaultProfiles).forEach(stack::push); asReversedList(profiles).forEach(stack::push);
Set<String> acceptedProfiles = new LinkedHashSet<>(); Set<String> expandedProfiles = new LinkedHashSet<>();
while (!stack.isEmpty()) { while (!stack.isEmpty()) {
String current = stack.pop(); String current = stack.pop();
acceptedProfiles.add(current); expandedProfiles.add(current);
asReversedList(this.groups.get(current)).forEach(stack::push); asReversedList(this.groups.get(current)).forEach(stack::push);
} }
return asUniqueItemList(StringUtils.toStringArray(acceptedProfiles)); return asUniqueItemList(StringUtils.toStringArray(expandedProfiles));
} }
private List<String> asReversedList(List<String> list) { private List<String> asReversedList(List<String> list) {
...@@ -161,7 +167,7 @@ public class Profiles implements Iterable<String> { ...@@ -161,7 +167,7 @@ public class Profiles implements Iterable<String> {
* @return the accepted profiles * @return the accepted profiles
*/ */
public List<String> getAccepted() { public List<String> getAccepted() {
return this.acceptedProfiles; return (!this.activeProfiles.isEmpty()) ? this.activeProfiles : this.defaultProfiles;
} }
/** /**
...@@ -170,7 +176,7 @@ public class Profiles implements Iterable<String> { ...@@ -170,7 +176,7 @@ public class Profiles implements Iterable<String> {
* @return if the profile is active * @return if the profile is active
*/ */
public boolean isAccepted(String profile) { public boolean isAccepted(String profile) {
return this.acceptedProfiles.contains(profile); return getAccepted().contains(profile);
} }
@Override @Override
......
...@@ -174,6 +174,15 @@ class ConfigDataEnvironmentTests { ...@@ -174,6 +174,15 @@ class ConfigDataEnvironmentTests {
assertThat(this.environment.getActiveProfiles()).containsExactly("one", "two", "three"); 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 @Test
@Disabled("Disabled until spring.profiles suppport is dropped") @Disabled("Disabled until spring.profiles suppport is dropped")
void processAndApplyWhenHasInvalidPropertyThrowsException() { void processAndApplyWhenHasInvalidPropertyThrowsException() {
......
...@@ -114,6 +114,16 @@ class ProfilesTests { ...@@ -114,6 +114,16 @@ class ProfilesTests {
assertThat(profiles.getActive()).containsExactly("a", "b", "c"); 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 @Test
void getActiveWhenHasAdditionalIncludesAdditional() { void getActiveWhenHasAdditionalIncludesAdditional() {
MockEnvironment environment = new MockEnvironment(); MockEnvironment environment = new MockEnvironment();
...@@ -189,6 +199,16 @@ class ProfilesTests { ...@@ -189,6 +199,16 @@ class ProfilesTests {
assertThat(profiles.getDefault()).containsExactly("a", "b", "c"); 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 @Test
void getDefaultWhenEnvironmentProfilesInBindNotationAndEnvironmentPropertyReturnsEnvironmentProfiles() { void getDefaultWhenEnvironmentProfilesInBindNotationAndEnvironmentPropertyReturnsEnvironmentProfiles() {
MockEnvironment environment = new MockEnvironment(); MockEnvironment environment = new MockEnvironment();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment