This article explains how to implement handling and validation of common parameter into the Policy Framework Components using Spring boot framework.
Environment
A component can use org.springframework.core.env.Environment component directly.
Environment component is not a good approach because there is not type conversion and error checking, but it could be useful when the name of the property you need to access changes dynamically.
@Component @RequiredArgsConstructor public class Example { private Environment env; .... public void method(String pathPropertyName) { ..... String path = env.getProperty(pathPropertyName); ..... }
Annotation-based Spring configuration
All annotation-based Spring configurations support the Spring Expression Language (SpEL), a powerful expression language that supports querying and manipulating an object graph at runtime.
A documentation about SpEL could be found here: https://docs.spring.io/spring-framework/docs/3.0.x/reference/expressions.html.
A component can use org.springframework.beans.factory.annotation.Value, which reads from properties, performs a type conversion and injects the value into the filed. There is not error checking, but it can assign default value if the property is not defined.
@Value("${security.enable-csrf:true}") private boolean csrfEnabled = true;
The code below shows how to inject a value of a property into @Schedule configuration.
@Scheduled( fixedRateString = "${runtime.participantParameters.heartBeatMs}", initialDelayString = "${runtime.participantParameters.heartBeatMs}") public void schedule() { }
ConfigurationProperties
@ConfigurationProperties can be used to map values from .properties( .yml also supported) to a POJO. It performs all type conversion and error checking using validation javax.validation.constraints
@Validated @Getter @Setter @ConfigurationProperties(prefix = "runtime") public class ClRuntimeParameterGroup { @Min(100) private long heartBeatMs; @Valid @Positive private long reportingTimeIntervalMs; @Valid @NotNull private ParticipantUpdateParameters updateParameters; @NotBlank private String description; }
In a scenario that we need to include into a POJO shown before, a class that implement org.onap.policy.common.parameters.ParameterGroup interface, we need to add the org.onap.policy.common.parameters.validation.ParameterGroupConstraint annotation. That annotation is configured to use ParameterGroupValidator that handles the conversion of a org.onap.policy.common.parameters.BeanValidationResult to a Spring validation.
The code below shown how to add TopicParameterGroup parameter into ClRuntimeParameterGroup:
@NotNull @ParameterGroupConstraint private TopicParameterGroup topicParameterGroup;
A bean configured with ConfigurationProperties, is automatically a Spring component and could be injected into other Spring components. The code below shown an example:
@Component @RequiredArgsConstructor public class Example { private ClRuntimeParameterGroup parameters; .... public void method() { ..... long heartBeatMs = parameters.getHeartBeatMs(); ..... }
The code shows below, is an example of Unit Test validation of the POJO ClRuntimeParameterGroup:
private ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory(); @Test void testParameters_NullTopicParameterGroup() { final ClRuntimeParameterGroup parameters = CommonTestData.geParameterGroup(); parameters.setTopicParameterGroup(null); assertThat(validatorFactory.getValidator().validate(parameters)).isNotEmpty(); }
This page is Work in Progress