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 { 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 * @return the property names
*/ */
String[] value(); 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.ArrayList;
import java.util.List; import java.util.List;
import org.springframework.boot.bind.RelaxedPropertyResolver;
import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext; 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.core.type.AnnotatedTypeMetadata;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
@ -29,6 +30,7 @@ import org.springframework.util.StringUtils;
* {@link Condition} that checks if properties are defined in environment. * {@link Condition} that checks if properties are defined in environment.
* *
* @author Maciej Walkowiak * @author Maciej Walkowiak
* @author Phillip Webb
* @see ConditionalOnProperty * @see ConditionalOnProperty
* @since 1.1.0 * @since 1.1.0
*/ */
@ -38,17 +40,27 @@ class OnPropertyCondition extends SpringBootCondition {
public ConditionOutcome getMatchOutcome(ConditionContext context, public ConditionOutcome getMatchOutcome(ConditionContext context,
AnnotatedTypeMetadata metadata) { 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"); ConditionalOnProperty.class.getName()).get("value");
Boolean relaxedNames = (Boolean) metadata.getAnnotationAttributes(
ConditionalOnProperty.class.getName()).get("relaxedNames");
List<String> missingProperties = new ArrayList<String>(); List<String> missingProperties = new ArrayList<String>();
Environment environment = context.getEnvironment(); PropertyResolver resolver = context.getEnvironment();
for (String property : onProperties) { if (relaxedNames) {
if (!environment.containsProperty(property) resolver = new RelaxedPropertyResolver(resolver, prefix);
|| StringUtils.endsWithIgnoreCase(environment.getProperty(property), prefix = "";
"false")) { }
missingProperties.add(property);
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.match();
} }
return ConditionOutcome return ConditionOutcome.noMatch("@ConditionalOnProperty "
.noMatch("@ConditionalOnProperty missing required properties: " + "missing required properties: "
+ StringUtils.arrayToCommaDelimitedString(missingProperties + StringUtils.arrayToCommaDelimitedString(missingProperties.toArray())
.toArray()) + " not found"); + " 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.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
@ -36,41 +35,57 @@ public class ConditionalOnPropertyTests {
private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
@Test @Test
public void testBeanIsCreatedWhenAllPropertiesAreDefined() { public void allPropertiesAreDefined() {
EnvironmentTestUtils.addEnvironment(this.context.getEnvironment(), EnvironmentTestUtils.addEnvironment(this.context.getEnvironment(),
"property1=value1", "property2=value2"); "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.register(MultiplePropertiesRequiredConfiguration.class);
this.context.refresh(); 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 @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";
}
}
} }