Commit a8707c52 authored by Madhura Bhave's avatar Madhura Bhave

Merge branch '2.0.x'

parents e72306b3 cab9bff4
...@@ -26,7 +26,6 @@ import java.util.LinkedHashSet; ...@@ -26,7 +26,6 @@ import java.util.LinkedHashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Queue;
import java.util.Set; import java.util.Set;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.stream.Collectors; import java.util.stream.Collectors;
...@@ -302,7 +301,7 @@ public class ConfigFileApplicationListener ...@@ -302,7 +301,7 @@ public class ConfigFileApplicationListener
private final List<PropertySourceLoader> propertySourceLoaders; private final List<PropertySourceLoader> propertySourceLoaders;
private Queue<Profile> profiles; private LinkedList<Profile> profiles;
private List<Profile> processedProfiles; private List<Profile> processedProfiles;
...@@ -321,7 +320,7 @@ public class ConfigFileApplicationListener ...@@ -321,7 +320,7 @@ public class ConfigFileApplicationListener
} }
public void load() { public void load() {
this.profiles = Collections.asLifoQueue(new LinkedList<Profile>()); this.profiles = new LinkedList<>();
this.processedProfiles = new LinkedList<>(); this.processedProfiles = new LinkedList<>();
this.activatedProfiles = false; this.activatedProfiles = false;
this.loaded = new LinkedHashMap<>(); this.loaded = new LinkedHashMap<>();
...@@ -343,62 +342,62 @@ public class ConfigFileApplicationListener ...@@ -343,62 +342,62 @@ public class ConfigFileApplicationListener
* properties that are already set. * properties that are already set.
*/ */
private void initializeProfiles() { private void initializeProfiles() {
Set<Profile> initialActiveProfiles = initializeActiveProfiles(); //The default profile for these purposes is represented as null. We add it
this.profiles.addAll(getUnprocessedActiveProfiles(initialActiveProfiles)); // first so that it is processed first and has lowest priority.
if (this.profiles.isEmpty()) { this.profiles.add(null);
Set<Profile> activatedViaProperty = getProfilesActivatedViaActiveProfileProperty();
processOtherActiveProfiles(activatedViaProperty);
// Any pre-existing active activeProfiles set via property sources (e.g. System
// properties) take precedence over those added in config files.
addActiveProfiles(activatedViaProperty);
if (this.profiles.size() == 1) { //only has null profile
for (String defaultProfileName : this.environment.getDefaultProfiles()) { for (String defaultProfileName : this.environment.getDefaultProfiles()) {
Profile defaultProfile = new Profile(defaultProfileName, true); ConfigFileApplicationListener.Profile defaultProfile = new ConfigFileApplicationListener.Profile(
if (!this.profiles.contains(defaultProfile)) { defaultProfileName, true);
this.profiles.add(defaultProfile); this.profiles.add(defaultProfile);
} }
} }
} }
// The default profile for these purposes is represented as null. We add it
// last so that it is first out of the queue (active profiles will then
// override any settings in the defaults when the list is reversed later).
this.profiles.add(null);
}
private Set<Profile> initializeActiveProfiles() { private Set<Profile> getProfilesActivatedViaActiveProfileProperty() {
if (!this.environment.containsProperty(ACTIVE_PROFILES_PROPERTY) if (!this.environment.containsProperty(ACTIVE_PROFILES_PROPERTY)
&& !this.environment.containsProperty(INCLUDE_PROFILES_PROPERTY)) { && !this.environment.containsProperty(INCLUDE_PROFILES_PROPERTY)) {
return Collections.emptySet(); return Collections.emptySet();
} }
// Any pre-existing active profiles set via property sources (e.g. System
// properties) take precedence over those added in config files.
Binder binder = Binder.get(this.environment); Binder binder = Binder.get(this.environment);
Set<Profile> activeProfiles = new LinkedHashSet<>(); Set<Profile> activeProfiles = new LinkedHashSet<>();
activeProfiles.addAll(getProfiles(binder, ACTIVE_PROFILES_PROPERTY)); activeProfiles.addAll(getProfiles(binder, ACTIVE_PROFILES_PROPERTY));
activeProfiles.addAll(getProfiles(binder, INCLUDE_PROFILES_PROPERTY)); activeProfiles.addAll(getProfiles(binder, INCLUDE_PROFILES_PROPERTY));
maybeActivateProfiles(activeProfiles);
return activeProfiles; return activeProfiles;
} }
/** private void processOtherActiveProfiles(Set<Profile> activatedViaProperty) {
* Return the active profiles that have not been processed yet. If a profile is List<Profile> otherActiveProfiles = Arrays.stream(this.environment.getActiveProfiles())
* enabled via both {@link #ACTIVE_PROFILES_PROPERTY} and .map(Profile::new)
* {@link ConfigurableEnvironment#addActiveProfile(String)} it needs to be .filter(o -> !activatedViaProperty.contains(o)).collect(Collectors.toList());
* filtered so that the {@link #ACTIVE_PROFILES_PROPERTY} value takes precedence. this.profiles.addAll(otherActiveProfiles);
* <p>
* Concretely, if the "cloud" profile is enabled via the environment, it will take
* less precedence that any profile set via the {@link #ACTIVE_PROFILES_PROPERTY}.
* @param initialActiveProfiles the profiles that have been enabled via
* {@link #ACTIVE_PROFILES_PROPERTY}
* @return the unprocessed active profiles from the environment to enable
*/
private List<Profile> getUnprocessedActiveProfiles(
Set<Profile> initialActiveProfiles) {
List<Profile> unprocessedActiveProfiles = new ArrayList<>();
for (String profileName : this.environment.getActiveProfiles()) {
Profile profile = new Profile(profileName);
if (!initialActiveProfiles.contains(profile)) {
unprocessedActiveProfiles.add(profile);
} }
void addActiveProfiles(Set<Profile> profiles) {
if (this.activatedProfiles || profiles.isEmpty()) {
return;
} }
// Reverse them so the order is the same as from getProfilesForValue() addProfiles(profiles);
// (last one wins when properties are eventually resolved) this.logger.debug("Activated activeProfiles "
Collections.reverse(unprocessedActiveProfiles); + StringUtils.collectionToCommaDelimitedString(profiles));
return unprocessedActiveProfiles; this.activatedProfiles = true;
removeUnprocessedDefaultProfiles();
}
void addProfiles(Set<Profile> profiles) {
for (Profile profile : profiles) {
this.profiles.add(profile);
addProfileToEnvironment(profile.getName());
}
}
private void removeUnprocessedDefaultProfiles() {
this.profiles.removeIf(profile -> (profile != null && profile.isDefaultProfile()));
} }
private DocumentFilter getPositiveProfileFilter(Profile profile) { private DocumentFilter getPositiveProfileFilter(Profile profile) {
...@@ -520,7 +519,7 @@ public class ConfigFileApplicationListener ...@@ -520,7 +519,7 @@ public class ConfigFileApplicationListener
List<Document> loaded = new ArrayList<>(); List<Document> loaded = new ArrayList<>();
for (Document document : documents) { for (Document document : documents) {
if (filter.match(document)) { if (filter.match(document)) {
maybeActivateProfiles(document.getActiveProfiles()); addActiveProfiles(document.getActiveProfiles());
addProfiles(document.getIncludeProfiles()); addProfiles(document.getIncludeProfiles());
loaded.add(document); loaded.add(document);
} }
...@@ -587,58 +586,16 @@ public class ConfigFileApplicationListener ...@@ -587,58 +586,16 @@ public class ConfigFileApplicationListener
for (String profileName : profileNames) { for (String profileName : profileNames) {
profiles.add(new Profile(profileName)); profiles.add(new Profile(profileName));
} }
Collections.reverse(profiles);
return new LinkedHashSet<>(profiles); return new LinkedHashSet<>(profiles);
} }
private void maybeActivateProfiles(Set<Profile> profiles) { private void addProfileToEnvironment(String profile) {
if (profiles.isEmpty()) {
return;
}
if (this.activatedProfiles) {
this.logger.debug("Profiles already activated, '" + profiles
+ "' will not be applied");
return;
}
addProfiles(profiles);
this.logger.debug("Activated profiles "
+ StringUtils.collectionToCommaDelimitedString(profiles));
this.activatedProfiles = true;
removeUnprocessedDefaultProfiles();
}
private void removeUnprocessedDefaultProfiles() {
this.profiles.removeIf(Profile::isDefaultProfile);
}
private void addProfiles(Set<Profile> profiles) {
for (Profile profile : profiles) {
this.profiles.add(profile);
if (!environmentHasActiveProfile(profile.getName())) {
// If it's already accepted we assume the order was set
// intentionally
prependProfile(this.environment, profile);
}
}
}
private boolean environmentHasActiveProfile(String profile) {
for (String activeProfile : this.environment.getActiveProfiles()) { for (String activeProfile : this.environment.getActiveProfiles()) {
if (activeProfile.equals(profile)) { if (activeProfile.equals(profile)) {
return true; return;
} }
} }
return false; this.environment.addActiveProfile(profile);
}
private void prependProfile(ConfigurableEnvironment environment,
Profile profile) {
Set<String> profiles = new LinkedHashSet<>();
environment.getActiveProfiles(); // ensure they are initialized
// But this one should go first (last wins in a property key clash)
profiles.add(profile.getName());
profiles.addAll(Arrays.asList(environment.getActiveProfiles()));
environment.setActiveProfiles(StringUtils.toStringArray(profiles));
} }
private Set<String> getSearchLocations() { private Set<String> getSearchLocations() {
......
...@@ -758,6 +758,8 @@ public class ConfigFileApplicationListenerTests { ...@@ -758,6 +758,8 @@ public class ConfigFileApplicationListenerTests {
assertThat(environment).has(matchingProfile("morespecific")); assertThat(environment).has(matchingProfile("morespecific"));
assertThat(environment).has(matchingProfile("yetmorespecific")); assertThat(environment).has(matchingProfile("yetmorespecific"));
assertThat(environment).doesNotHave(matchingProfile("missing")); assertThat(environment).doesNotHave(matchingProfile("missing"));
assertThat(this.out.toString())
.contains("The following profiles are active: includeprofile,specific,morespecific,yetmorespecific");
} }
@Test @Test
......
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