Commit 4b51b6f9 authored by Phillip Webb's avatar Phillip Webb

Support relaxed names with ConditionalOnProperty

Update ConditionalOnProperty to optionally support relaxed form names.

Fixes gh-835
parent f80d23ad
......@@ -37,9 +37,20 @@ import org.springframework.core.env.Environment;
public @interface ConditionalOnProperty {
/**
* One or more properties that must be present.
* A prefix that should be applied to each property.
*/
String prefix() default "";
/**
* One or more properties that must be present. If you are checking relaxed names you
* should specify the property in its dashed form.
* @return the property names
*/
String[] value();
/**
* If relaxed names should be checked. Defaults to {@code true}.
*/
boolean relaxedNames() default true;
}
......@@ -19,9 +19,10 @@ package org.springframework.boot.autoconfigure.condition;
import java.util.ArrayList;
import java.util.List;
import org.springframework.boot.bind.RelaxedPropertyResolver;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.env.PropertyResolver;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.util.StringUtils;
......@@ -29,6 +30,7 @@ import org.springframework.util.StringUtils;
* {@link Condition} that checks if properties are defined in environment.
*
* @author Maciej Walkowiak
* @author Phillip Webb
* @see ConditionalOnProperty
* @since 1.1.0
*/
......@@ -38,17 +40,27 @@ class OnPropertyCondition extends SpringBootCondition {
public ConditionOutcome getMatchOutcome(ConditionContext context,
AnnotatedTypeMetadata metadata) {
String[] onProperties = (String[]) metadata.getAnnotationAttributes(
String prefix = (String) metadata.getAnnotationAttributes(
ConditionalOnProperty.class.getName()).get("prefix");
String[] names = (String[]) metadata.getAnnotationAttributes(
ConditionalOnProperty.class.getName()).get("value");
Boolean relaxedNames = (Boolean) metadata.getAnnotationAttributes(
ConditionalOnProperty.class.getName()).get("relaxedNames");
List<String> missingProperties = new ArrayList<String>();
Environment environment = context.getEnvironment();
for (String property : onProperties) {
if (!environment.containsProperty(property)
|| StringUtils.endsWithIgnoreCase(environment.getProperty(property),
"false")) {
missingProperties.add(property);
PropertyResolver resolver = context.getEnvironment();
if (relaxedNames) {
resolver = new RelaxedPropertyResolver(resolver, prefix);
prefix = "";
}
for (String name : names) {
name = prefix + name;
if (!resolver.containsProperty(name)
|| "false".equalsIgnoreCase(resolver.getProperty(name))) {
missingProperties.add(name);
}
}
......@@ -56,9 +68,9 @@ class OnPropertyCondition extends SpringBootCondition {
return ConditionOutcome.match();
}
return ConditionOutcome
.noMatch("@ConditionalOnProperty missing required properties: "
+ StringUtils.arrayToCommaDelimitedString(missingProperties
.toArray()) + " not found");
return ConditionOutcome.noMatch("@ConditionalOnProperty "
+ "missing required properties: "
+ StringUtils.arrayToCommaDelimitedString(missingProperties.toArray())
+ " not found");
}
}
......@@ -22,7 +22,6 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
......@@ -36,41 +35,57 @@ public class ConditionalOnPropertyTests {
private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
@Test
public void testBeanIsCreatedWhenAllPropertiesAreDefined() {
public void allPropertiesAreDefined() {
EnvironmentTestUtils.addEnvironment(this.context.getEnvironment(),
"property1=value1", "property2=value2");
setupContext();
this.context.register(MultiplePropertiesRequiredConfiguration.class);
this.context.refresh();
assertTrue(this.context.containsBean("foo"));
assertEquals("foo", this.context.getBean("foo"));
}
@Test
public void testBeanIsNotCreatedWhenNotAllPropertiesAreDefined() {
public void notAllPropertiesAreDefined() {
EnvironmentTestUtils.addEnvironment(this.context.getEnvironment(),
"property1=value1");
setupContext();
this.context.register(MultiplePropertiesRequiredConfiguration.class);
this.context.refresh();
assertFalse(this.context.containsBean("foo"));
}
@Test
public void testBeanIsNotCreatedWhenPropertyValueEqualsFalse() {
public void propertyValueEqualsFalse() {
EnvironmentTestUtils.addEnvironment(this.context.getEnvironment(),
"property1=false", "property2=value2");
setupContext();
this.context.register(MultiplePropertiesRequiredConfiguration.class);
this.context.refresh();
assertFalse(this.context.containsBean("foo"));
}
@Test
public void testBeanIsNotCreatedWhenPropertyValueEqualsFALSE() {
public void propertyValueEqualsFALSE() {
EnvironmentTestUtils.addEnvironment(this.context.getEnvironment(),
"property1=FALSE", "property2=value2");
setupContext();
this.context.register(MultiplePropertiesRequiredConfiguration.class);
this.context.refresh();
assertFalse(this.context.containsBean("foo"));
}
private void setupContext() {
this.context.register(MultiplePropertiesRequiredConfiguration.class);
@Test
public void relaxedName() throws Exception {
EnvironmentTestUtils.addEnvironment(this.context.getEnvironment(),
"spring.theRelaxedProperty=value1");
this.context.register(RelaxedPropertiesRequiredConfiguration.class);
this.context.refresh();
assertTrue(this.context.containsBean("foo"));
}
@Test
public void nonRelaxedName() throws Exception {
EnvironmentTestUtils.addEnvironment(this.context.getEnvironment(),
"theRelaxedProperty=value1");
this.context.register(NonRelaxedPropertiesRequiredConfiguration.class);
this.context.refresh();
assertFalse(this.context.containsBean("foo"));
}
@Configuration
......@@ -84,4 +99,26 @@ public class ConditionalOnPropertyTests {
}
@Configuration
@ConditionalOnProperty(prefix = "spring.", value = "the-relaxed-property")
protected static class RelaxedPropertiesRequiredConfiguration {
@Bean
public String foo() {
return "foo";
}
}
@Configuration
@ConditionalOnProperty(value = "the-relaxed-property", relaxedNames = false)
protected static class NonRelaxedPropertiesRequiredConfiguration {
@Bean
public String foo() {
return "foo";
}
}
}
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