Support profile expression in yml profile matching
Closes gh-12469
This commit is contained in:
@@ -756,15 +756,25 @@ example:
|
||||
address: 127.0.0.1
|
||||
---
|
||||
spring:
|
||||
profiles: production
|
||||
profiles: production & eu-central
|
||||
server:
|
||||
address: 192.168.1.120
|
||||
----
|
||||
|
||||
In the preceding example, if the `development` profile is active, the `server.address`
|
||||
property is `127.0.0.1`. Similarly, if the `production` profile is active, the
|
||||
`server.address` property is `192.168.1.120`. If the `development` and `production`
|
||||
profiles are *not* enabled, then the value for the property is `192.168.1.100`.
|
||||
property is `127.0.0.1`. Similarly, if the `production` *and* `eu-central` profiles are
|
||||
active, the `server.address` property is `192.168.1.120`. If the `development` and
|
||||
`production` and `eu-central` profiles are *not* enabled, then the value for the property
|
||||
is `192.168.1.100`.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
`spring.profiles` can therefore contains a simple profile name (for example `production`)
|
||||
or a profile expression. A profile expression allows for more complicated profile logic
|
||||
to be expressed, for example `production & (eu-central | eu-west)`. Check the
|
||||
{spring-reference}core.html#beans-definition-profiles-java[reference guide] for more
|
||||
details.
|
||||
====
|
||||
|
||||
If none are explicitly active when the application context starts, the default profiles
|
||||
are activated. So, in the following YAML, we set a value for `spring.security.user.password`
|
||||
|
||||
@@ -57,6 +57,7 @@ import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.env.MutablePropertySources;
|
||||
import org.springframework.core.env.Profiles;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.core.io.Resource;
|
||||
@@ -411,14 +412,15 @@ public class ConfigFileApplicationListener
|
||||
}
|
||||
return ObjectUtils.containsElement(document.getProfiles(),
|
||||
profile.getName())
|
||||
&& this.environment.acceptsProfiles(document.getProfiles());
|
||||
&& this.environment
|
||||
.acceptsProfiles(Profiles.of(document.getProfiles()));
|
||||
};
|
||||
}
|
||||
|
||||
private DocumentFilter getNegativeProfileFilter(Profile profile) {
|
||||
return (Document document) -> (profile == null
|
||||
&& !ObjectUtils.isEmpty(document.getProfiles())
|
||||
&& this.environment.acceptsProfiles(document.getProfiles()));
|
||||
&& !ObjectUtils.isEmpty(document.getProfiles()) && this.environment
|
||||
.acceptsProfiles(Profiles.of(document.getProfiles())));
|
||||
}
|
||||
|
||||
private DocumentConsumer addToLoaded(
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.junit.Test;
|
||||
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.Profiles;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -50,8 +51,10 @@ public class ReproTests {
|
||||
this.context = application.run(
|
||||
"--spring.config.name=enableprofileviaapplicationproperties",
|
||||
"--spring.profiles.active=dev");
|
||||
assertThat(this.context.getEnvironment().acceptsProfiles("dev")).isTrue();
|
||||
assertThat(this.context.getEnvironment().acceptsProfiles("a")).isTrue();
|
||||
assertThat(this.context.getEnvironment().acceptsProfiles(Profiles.of("dev")))
|
||||
.isTrue();
|
||||
assertThat(this.context.getEnvironment().acceptsProfiles(Profiles.of("a")))
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -83,6 +83,7 @@ import org.springframework.core.env.CompositePropertySource;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.env.MapPropertySource;
|
||||
import org.springframework.core.env.Profiles;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
@@ -525,7 +526,7 @@ public class SpringApplicationTests {
|
||||
ConfigurableEnvironment environment = new StandardEnvironment();
|
||||
application.setEnvironment(environment);
|
||||
this.context = application.run();
|
||||
assertThat(environment.acceptsProfiles("foo")).isTrue();
|
||||
assertThat(environment.acceptsProfiles(Profiles.of("foo"))).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.support.StaticApplicationContext;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.Profiles;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
@@ -72,7 +73,8 @@ public class SpringApplicationBuilderTests {
|
||||
this.context = application.run();
|
||||
assertThat(this.context).isInstanceOf(StaticApplicationContext.class);
|
||||
assertThat(this.context.getEnvironment().getProperty("foo")).isEqualTo("bucket");
|
||||
assertThat(this.context.getEnvironment().acceptsProfiles("foo")).isTrue();
|
||||
assertThat(this.context.getEnvironment().acceptsProfiles(Profiles.of("foo")))
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -205,11 +207,12 @@ public class SpringApplicationBuilderTests {
|
||||
ExampleConfig.class).profiles("node").properties("transport=redis")
|
||||
.child(ChildConfig.class).web(WebApplicationType.NONE);
|
||||
this.context = application.run();
|
||||
assertThat(this.context.getEnvironment().acceptsProfiles("node")).isTrue();
|
||||
assertThat(this.context.getEnvironment().acceptsProfiles(Profiles.of("node")))
|
||||
.isTrue();
|
||||
assertThat(this.context.getEnvironment().getProperty("transport"))
|
||||
.isEqualTo("redis");
|
||||
assertThat(this.context.getParent().getEnvironment().acceptsProfiles("node"))
|
||||
.isTrue();
|
||||
assertThat(this.context.getParent().getEnvironment()
|
||||
.acceptsProfiles(Profiles.of("node"))).isTrue();
|
||||
assertThat(this.context.getParent().getEnvironment().getProperty("transport"))
|
||||
.isEqualTo("redis");
|
||||
// only defined in node profile
|
||||
@@ -223,10 +226,10 @@ public class SpringApplicationBuilderTests {
|
||||
.child(ChildConfig.class).profiles("admin")
|
||||
.web(WebApplicationType.NONE);
|
||||
this.context = application.run();
|
||||
assertThat(this.context.getEnvironment().acceptsProfiles("node", "admin"))
|
||||
.isTrue();
|
||||
assertThat(this.context.getParent().getEnvironment().acceptsProfiles("admin"))
|
||||
.isFalse();
|
||||
assertThat(this.context.getEnvironment()
|
||||
.acceptsProfiles(Profiles.of("node", "admin"))).isTrue();
|
||||
assertThat(this.context.getParent().getEnvironment()
|
||||
.acceptsProfiles(Profiles.of("admin"))).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -237,12 +240,12 @@ public class SpringApplicationBuilderTests {
|
||||
.profiles("admin").web(WebApplicationType.NONE);
|
||||
shared.profiles("parent");
|
||||
this.context = application.run();
|
||||
assertThat(this.context.getEnvironment().acceptsProfiles("node", "admin"))
|
||||
.isTrue();
|
||||
assertThat(this.context.getParent().getEnvironment().acceptsProfiles("node",
|
||||
"parent")).isTrue();
|
||||
assertThat(this.context.getParent().getEnvironment().acceptsProfiles("admin"))
|
||||
.isFalse();
|
||||
assertThat(this.context.getEnvironment()
|
||||
.acceptsProfiles(Profiles.of("node", "admin"))).isTrue();
|
||||
assertThat(this.context.getParent().getEnvironment()
|
||||
.acceptsProfiles(Profiles.of("node", "parent"))).isTrue();
|
||||
assertThat(this.context.getParent().getEnvironment()
|
||||
.acceptsProfiles(Profiles.of("admin"))).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -253,12 +256,12 @@ public class SpringApplicationBuilderTests {
|
||||
.child(ChildConfig.class).profiles("admin")
|
||||
.web(WebApplicationType.NONE);
|
||||
this.context = application.run();
|
||||
assertThat(this.context.getEnvironment().acceptsProfiles("node", "admin"))
|
||||
.isTrue();
|
||||
assertThat(this.context.getEnvironment()
|
||||
.acceptsProfiles(Profiles.of("node", "admin"))).isTrue();
|
||||
// Now they share an Environment explicitly so there's no way to keep the profiles
|
||||
// separate
|
||||
assertThat(this.context.getParent().getEnvironment().acceptsProfiles("admin"))
|
||||
.isTrue();
|
||||
assertThat(this.context.getParent().getEnvironment()
|
||||
.acceptsProfiles(Profiles.of("admin"))).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -54,6 +54,7 @@ import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.MapPropertySource;
|
||||
import org.springframework.core.env.Profiles;
|
||||
import org.springframework.core.env.SimpleCommandLinePropertySource;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
@@ -504,6 +505,29 @@ public class ConfigFileApplicationListenerTests {
|
||||
assertThat(property).isEqualTo("notempty");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void yamlProfileExpressionsAnd() {
|
||||
assertProfileExpression("devandother", "dev", "other");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void yamlProfileExpressionsComplex() {
|
||||
assertProfileExpression("devorotherandanother", "dev", "another");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void yamlProfileExpressionsNoMatch() {
|
||||
assertProfileExpression("fromyamlfile", "dev");
|
||||
}
|
||||
|
||||
private void assertProfileExpression(String value, String... activeProfiles) {
|
||||
this.environment.setActiveProfiles(activeProfiles);
|
||||
this.initializer.setSearchNames("testprofileexpression");
|
||||
this.initializer.postProcessEnvironment(this.environment, this.application);
|
||||
String property = this.environment.getProperty("my.property");
|
||||
assertThat(property).isEqualTo(value);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void yamlNegatedProfiles() {
|
||||
// gh-8011
|
||||
@@ -827,7 +851,7 @@ public class ConfigFileApplicationListenerTests {
|
||||
assertThat(environment.containsProperty("customprofile")).isTrue();
|
||||
assertThat(environment.containsProperty("customprofile-specific")).isTrue();
|
||||
assertThat(environment.containsProperty("customprofile-customdefault")).isTrue();
|
||||
assertThat(environment.acceptsProfiles("customdefault")).isTrue();
|
||||
assertThat(environment.acceptsProfiles(Profiles.of("customdefault"))).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -899,7 +923,7 @@ public class ConfigFileApplicationListenerTests {
|
||||
application.setWebApplicationType(WebApplicationType.NONE);
|
||||
this.context = application.run("--spring.config.name=applicationloop");
|
||||
ConfigurableEnvironment environment = this.context.getEnvironment();
|
||||
assertThat(environment.acceptsProfiles("loop")).isTrue();
|
||||
assertThat(environment.acceptsProfiles(Profiles.of("loop"))).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -909,8 +933,8 @@ public class ConfigFileApplicationListenerTests {
|
||||
application.setWebApplicationType(WebApplicationType.NONE);
|
||||
this.context = application.run("--spring.config.name=applicationmultiprofiles");
|
||||
ConfigurableEnvironment environment = this.context.getEnvironment();
|
||||
assertThat(environment.acceptsProfiles("test")).isTrue();
|
||||
assertThat(environment.acceptsProfiles("another-test")).isTrue();
|
||||
assertThat(environment.acceptsProfiles(Profiles.of("test"))).isTrue();
|
||||
assertThat(environment.acceptsProfiles(Profiles.of("another-test"))).isTrue();
|
||||
assertThat(environment.getProperty("message")).isEqualTo("multiprofile");
|
||||
}
|
||||
|
||||
@@ -932,7 +956,7 @@ public class ConfigFileApplicationListenerTests {
|
||||
|
||||
@Override
|
||||
public boolean matches(ConfigurableEnvironment value) {
|
||||
return value.acceptsProfiles(profile);
|
||||
return value.acceptsProfiles(Profiles.of(profile));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
my:
|
||||
property: fromyamlfile
|
||||
---
|
||||
spring:
|
||||
profiles: dev & other
|
||||
my:
|
||||
property: devandother
|
||||
---
|
||||
spring:
|
||||
profiles: (dev | other) & another
|
||||
my:
|
||||
property: devorotherandanother
|
||||
---
|
||||
Reference in New Issue
Block a user