aboutsummaryrefslogtreecommitdiffstats
path: root/deployment-configs/src
diff options
context:
space:
mode:
Diffstat (limited to 'deployment-configs/src')
0 files changed, 0 insertions, 0 deletions
ref='#n94'>94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
.. This work is licensed under a
.. Creative Commons Attribution 4.0 International License.
.. http://creativecommons.org/licenses/by/4.0

.. _property-configuration:

Property-configuration mechanisms
#################################

.. contents::
    :depth: 3

This article explains how to implement handling and validation of common parameter into the Policy Framework Components.

Not Spring boot framework
*************************
The application should have a ParameterHandler class to support the map values from Json to a POJO, so it should be load the file, convert it performing all type conversion.

The code below shown an example of ParameterHandler:

.. code-block:: java

   public class PapParameterHandler {

       private static final Logger LOGGER = LoggerFactory.getLogger(PapParameterHandler.class);

       private static final Coder CODER = new StandardCoder();

    public PapParameterGroup getParameters(final PapCommandLineArguments arguments) throws PolicyPapException {
           PapParameterGroup papParameterGroup = null;

           try {
               var file = new File(arguments.getFullConfigurationFilePath());
               papParameterGroup = CODER.decode(file, PapParameterGroup.class);
           } catch (final CoderException e) {
               final String errorMessage = "error reading parameters from \"" + arguments.getConfigurationFilePath()
                       + "\"\n" + "(" + e.getClass().getSimpleName() + ")";
               throw new PolicyPapException(errorMessage, e);
           }

           if (papParameterGroup == null) {
               final String errorMessage = "no parameters found in \"" + arguments.getConfigurationFilePath() + "\"";
               LOGGER.error(errorMessage);
               throw new PolicyPapException(errorMessage);
           }

           final ValidationResult validationResult = papParameterGroup.validate();
           if (!validationResult.isValid()) {
               String returnMessage =
                       "validation error(s) on parameters from \"" + arguments.getConfigurationFilePath() + "\"\n";
               returnMessage += validationResult.getResult();

               LOGGER.error(returnMessage);
               throw new PolicyPapException(returnMessage);
           }

           return papParameterGroup;
       }
   }


The POJO have to implement **org.onap.policy.common.parameters.ParameterGroup** interface or eventually extend **org.onap.policy.common.parameters.ParameterGroupImpl**. The last one already implements **validate()** method that performs error checking using validation **org.onap.policy.common.parameters.annotations**.

The code below shown an example of POJO:

.. code-block:: java

   @NotNull
   @NotBlank
   @Getter
   public class PapParameterGroup extends ParameterGroupImpl {
       @Valid
       private RestServerParameters restServerParameters;
       @Valid
       private PdpParameters pdpParameters;
       @Valid
       private PolicyModelsProviderParameters databaseProviderParameters;
       private boolean savePdpStatisticsInDb;
       @Valid
       private TopicParameterGroup topicParameterGroup;

       private List<@NotNull @Valid RestClientParameters> healthCheckRestClientParameters;

       public PapParameterGroup(final String name) {
           super(name);
       }
   }


The code shows below, is an example of Unit Test validation of the POJO PapParameterGroup:

.. code-block:: java

   private static final Coder coder = new StandardCoder();

   @Test
   void testPapParameterGroup_NullName() throws Exception {
       String json = commonTestData.getPapParameterGroupAsString(1).replace("\"PapGroup\"", "null");
       final PapParameterGroup papParameters = coder.decode(json, PapParameterGroup.class);
       final ValidationResult validationResult = papParameters.validate();
       assertFalse(validationResult.isValid());
       assertEquals(null, papParameters.getName());
       assertThat(validationResult.getResult()).contains("is null");
   }


Using Spring boot framework
***************************
Spring loads automatically the property file and put it available under the **org.springframework.core.env.Environment** Spring component.

Environment
+++++++++++
A component can use 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.

.. code-block:: java

   @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.

.. code-block:: java

   @Value("${security.enable-csrf:true}")
   private boolean csrfEnabled = true;


The code below shows how to inject a value of a property into @Scheduled configuration.

.. code-block:: java

    @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**.

.. code-block:: java

   @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 **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:

.. code-block:: java

   @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:

.. code-block:: java

   @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:

.. code-block:: java

   private ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();

   @Test
   void testParameters_NullTopicParameterGroup() {
       final ClRuntimeParameterGroup parameters = CommonTestData.geParameterGroup();
       parameters.setTopicParameterGroup(null);
       assertThat(validatorFactory.getValidator().validate(parameters)).isNotEmpty();
   }