Support relaxed names with ConditionalOnProperty

Update ConditionalOnProperty to optionally support relaxed form names.

Fixes gh-835
This commit is contained in:
Phillip Webb 2014-05-10 00:08:38 +01:00
parent f80d23ada7
commit 4b51b6f9df
3 changed files with 105 additions and 45 deletions

View File

@ -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;
}

View File

@ -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");
}
}

View File

@ -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();
assertTrue(this.context.containsBean("foo"));
assertEquals("foo", this.context.getBean("foo"));
}
@Test
public void testBeanIsNotCreatedWhenNotAllPropertiesAreDefined() {
EnvironmentTestUtils.addEnvironment(this.context.getEnvironment(),
"property1=value1");
setupContext();
assertFalse(this.context.containsBean("foo"));
}
@Test
public void testBeanIsNotCreatedWhenPropertyValueEqualsFalse() {
EnvironmentTestUtils.addEnvironment(this.context.getEnvironment(),
"property1=false", "property2=value2");
setupContext();
assertFalse(this.context.containsBean("foo"));
}
@Test
public void testBeanIsNotCreatedWhenPropertyValueEqualsFALSE() {
EnvironmentTestUtils.addEnvironment(this.context.getEnvironment(),
"property1=FALSE", "property2=value2");
setupContext();
assertFalse(this.context.containsBean("foo"));
}
private void setupContext() {
this.context.register(MultiplePropertiesRequiredConfiguration.class);
this.context.refresh();
assertTrue(this.context.containsBean("foo"));
}
@Test
public void notAllPropertiesAreDefined() {
EnvironmentTestUtils.addEnvironment(this.context.getEnvironment(),
"property1=value1");
this.context.register(MultiplePropertiesRequiredConfiguration.class);
this.context.refresh();
assertFalse(this.context.containsBean("foo"));
}
@Test
public void propertyValueEqualsFalse() {
EnvironmentTestUtils.addEnvironment(this.context.getEnvironment(),
"property1=false", "property2=value2");
this.context.register(MultiplePropertiesRequiredConfiguration.class);
this.context.refresh();
assertFalse(this.context.containsBean("foo"));
}
@Test
public void propertyValueEqualsFALSE() {
EnvironmentTestUtils.addEnvironment(this.context.getEnvironment(),
"property1=FALSE", "property2=value2");
this.context.register(MultiplePropertiesRequiredConfiguration.class);
this.context.refresh();
assertFalse(this.context.containsBean("foo"));
}
@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";
}
}
}