We have an application that can be deployed with different profiles. Some features are disabled via feature toggle. When a feature is enabled, we want to make sure that the necessary configuration is valid. Today we have @NotBlank
annotation, so when a feature is disabled we put a dummy value for that property. What is important is to make sure it's well configured when the feature is enabled.
We tried to clean the configuration by removing the @NotBlank
and make the validation by using a Validator
based on active profiles. The issue is that the validate
method is not called.
Sample Application:
@SpringBootApplication
public class ConfigurationPropertiesValidationApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigurationPropertiesValidationApplication.class, args);
}
}
@Configuration
@EnableConfigurationProperties(MyProperties.class)
class AppConfig {
}
@ConstructorBinding
@ConfigurationProperties(prefix = "experiment")
@Validated
class MyProperties implements Validator {
private static final Logger LOGGER = LoggerFactory.getLogger(MyProperties.class);
// The NotBlank validation would be handled by the validate method
// @NotBlank
private final String value;
MyProperties(String value) {
this.value = value;
}
public String getValue() {
return value;
}
@Override
public boolean supports(Class<?> aClass) {
return MyProperties.class.isAssignableFrom(aClass);
}
@Override
public void validate(Object o, Errors errors) {
// Validate based on active profiles
}
}
application-aws.yaml
experiment:
value: mandatory on AWS
Spring Boot 2.3.4 +
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
Comment From: wilkinsona
This isn't how the Validator
interface is intended to be used. A Validator
implementation is intended to perform validation of various types of objects rather than being an indication that an object should validate itself. There's nothing that knows to use yourMyProperties
as a validator so there's nothing that calls validate(Object, Errors)
.
As you are using constructor binding, you could perform your manual validation in the constructor. Alternatively you could implement InitializingBean
and perform the validation in afterPropertiesSet
.
If you have any further questions, please follow up on Stack Overflow or Gitter. As mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements.