Add support for profile groups
Add support for profile groups so that users can combine a number of fine-grained profiles into a single logical group. Closes gh-22522
This commit is contained in:
committed by
Phillip Webb
parent
8c6c4fa9fa
commit
eee260fc03
@@ -28,11 +28,15 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.springframework.boot.context.properties.bind.Bindable;
|
||||
import org.springframework.boot.context.properties.bind.Binder;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.env.AbstractEnvironment;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.style.ToStringCreator;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -45,10 +49,15 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
public class Profiles implements Iterable<String> {
|
||||
|
||||
private static final Bindable<MultiValueMap<String, String>> STRING_STRINGS_MAP = Bindable
|
||||
.of(ResolvableType.forClassWithGenerics(MultiValueMap.class, String.class, String.class));
|
||||
|
||||
private static final Set<String> UNSET_ACTIVE = Collections.emptySet();
|
||||
|
||||
private static final Set<String> UNSET_DEFAULT = Collections.singleton("default");
|
||||
|
||||
private final MultiValueMap<String, String> groups;
|
||||
|
||||
private final List<String> activeProfiles;
|
||||
|
||||
private final List<String> defaultProfiles;
|
||||
@@ -63,6 +72,7 @@ public class Profiles implements Iterable<String> {
|
||||
* @param additionalProfiles and additional active profiles
|
||||
*/
|
||||
Profiles(Environment environment, Binder binder, Collection<String> additionalProfiles) {
|
||||
this.groups = binder.bind("spring.profiles.group", STRING_STRINGS_MAP).orElseGet(LinkedMultiValueMap::new);
|
||||
this.activeProfiles = asUniqueItemList(get(environment, binder, environment::getActiveProfiles,
|
||||
AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME, UNSET_ACTIVE), additionalProfiles);
|
||||
this.defaultProfiles = asUniqueItemList(get(environment, binder, environment::getDefaultProfiles,
|
||||
@@ -94,7 +104,9 @@ public class Profiles implements Iterable<String> {
|
||||
asReversedList((!activeProfiles.isEmpty()) ? activeProfiles : defaultProfiles).forEach(stack::push);
|
||||
Set<String> acceptedProfiles = new LinkedHashSet<>();
|
||||
while (!stack.isEmpty()) {
|
||||
acceptedProfiles.add(stack.pop());
|
||||
String current = stack.pop();
|
||||
acceptedProfiles.add(current);
|
||||
asReversedList(this.groups.get(current)).forEach(stack::push);
|
||||
}
|
||||
return asUniqueItemList(StringUtils.toStringArray(acceptedProfiles));
|
||||
}
|
||||
|
||||
@@ -262,6 +262,17 @@ class ProfilesTests {
|
||||
assertThat(profiles.isAccepted("x")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void iteratorWithProfileGroups() {
|
||||
MockEnvironment environment = new MockEnvironment();
|
||||
environment.setProperty("spring.profiles.active", "a,b,c");
|
||||
environment.setProperty("spring.profiles.group.a", "e,f");
|
||||
environment.setProperty("spring.profiles.group.e", "x,y");
|
||||
Binder binder = Binder.get(environment);
|
||||
Profiles profiles = new Profiles(environment, binder, null);
|
||||
assertThat(profiles).containsExactly("a", "e", "x", "y", "f", "b", "c");
|
||||
}
|
||||
|
||||
@Test
|
||||
void iteratorWithProfileGroupsAndNoActive() {
|
||||
MockEnvironment environment = new MockEnvironment();
|
||||
@@ -272,4 +283,60 @@ class ProfilesTests {
|
||||
assertThat(profiles).containsExactly("default");
|
||||
}
|
||||
|
||||
@Test
|
||||
void iteratorWithProfileGroupsForDefault() {
|
||||
MockEnvironment environment = new MockEnvironment();
|
||||
environment.setProperty("spring.profiles.group.default", "e,f");
|
||||
Binder binder = Binder.get(environment);
|
||||
Profiles profiles = new Profiles(environment, binder, null);
|
||||
assertThat(profiles).containsExactly("default", "e", "f");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getAcceptedWithProfileGroups() {
|
||||
MockEnvironment environment = new MockEnvironment();
|
||||
environment.setProperty("spring.profiles.active", "a,b,c");
|
||||
environment.setProperty("spring.profiles.group.a", "e,f");
|
||||
environment.setProperty("spring.profiles.group.e", "x,y");
|
||||
environment.setDefaultProfiles("g", "h", "i");
|
||||
Binder binder = Binder.get(environment);
|
||||
Profiles profiles = new Profiles(environment, binder, null);
|
||||
assertThat(profiles.getAccepted()).containsExactly("a", "e", "x", "y", "f", "b", "c");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getAcceptedWhenNoActiveAndDefaultWithGroups() {
|
||||
MockEnvironment environment = new MockEnvironment();
|
||||
environment.setDefaultProfiles("d", "e", "f");
|
||||
environment.setProperty("spring.profiles.group.e", "x,y");
|
||||
Binder binder = Binder.get(environment);
|
||||
Profiles profiles = new Profiles(environment, binder, null);
|
||||
assertThat(profiles.getAccepted()).containsExactly("d", "e", "x", "y", "f");
|
||||
}
|
||||
|
||||
@Test
|
||||
void isAcceptedWithGroupsReturnsTrue() {
|
||||
MockEnvironment environment = new MockEnvironment();
|
||||
environment.setProperty("spring.profiles.active", "a,b,c");
|
||||
environment.setProperty("spring.profiles.group.a", "e,f");
|
||||
environment.setProperty("spring.profiles.group.e", "x,y");
|
||||
environment.setDefaultProfiles("g", "h", "i");
|
||||
Binder binder = Binder.get(environment);
|
||||
Profiles profiles = new Profiles(environment, binder, null);
|
||||
assertThat(profiles.isAccepted("a")).isTrue();
|
||||
assertThat(profiles.isAccepted("e")).isTrue();
|
||||
assertThat(profiles.isAccepted("g")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isAcceptedWhenNoActiveAndDefaultWithGroupsContainsProfileReturnsTrue() {
|
||||
MockEnvironment environment = new MockEnvironment();
|
||||
environment.setDefaultProfiles("d", "e", "f");
|
||||
environment.setProperty("spring.profiles.group.e", "x,y");
|
||||
Binder binder = Binder.get(environment);
|
||||
Profiles profiles = new Profiles(environment, binder, null);
|
||||
assertThat(profiles.isAccepted("d")).isTrue();
|
||||
assertThat(profiles.isAccepted("x")).isTrue();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user