Add validator to check atleast one non null field check 74/11974/1
authoraravind.est <aravindhan.a@est.tech>
Thu, 26 Oct 2023 15:26:48 +0000 (16:26 +0100)
committeraravind.est <aravindhan.a@est.tech>
Thu, 26 Oct 2023 15:26:48 +0000 (16:26 +0100)
Validator added to check atleast one non null field exists in the provided class.

Issue-ID: NONRTRIC-952
Signed-off-by: aravind.est <aravindhan.a@est.tech>
Change-Id: Ic525109aaaaa9f165b4562d10b4967987073a9f2

participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/handler/AutomationCompositionElementHandler.java
participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/models/ConfigurationEntity.java
participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/validator/AtleastOneNonNullField.java [new file with mode: 0755]
participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/validator/AtleastOneNonNullFieldValidator.java [new file with mode: 0755]
participants/participant-impl-dme/src/test/java/org/oransc/participant/dme/validator/AtleastOneNonNullFieldValidatorTest.java [new file with mode: 0755]

index 612295e..71d9aaf 100755 (executable)
@@ -103,9 +103,7 @@ public class AutomationCompositionElementHandler implements AutomationCompositio
             var configurationEntity = CODER.convert(properties, ConfigurationEntity.class);
             var violations = Validation.buildDefaultValidatorFactory().getValidator().validate(configurationEntity);
             if (violations.isEmpty()) {
-                if ((configurationEntity.getInfoTypeEntities() != null
-                             || configurationEntity.getDataProducerEntities() != null
-                             || configurationEntity.getDataConsumerEntities() != null) && acDmeClient.isDmeHealthy()) {
+                if (acDmeClient.isDmeHealthy()) {
                     if (configurationEntity.getInfoTypeEntities() != null) {
                         acDmeClient.createInfoType(configurationEntity.getInfoTypeEntities().stream().collect(
                                 Collectors.toMap(InfoTypeEntity::getInfoTypeId, InfoTypeEntity::getPayload)));
index a312226..058ab02 100755 (executable)
@@ -24,17 +24,19 @@ import jakarta.validation.Valid;
 import java.util.List;
 import lombok.AllArgsConstructor;
 import lombok.Data;
+import org.oransc.participant.dme.validator.AtleastOneNonNullField;
 
 @Data
 @AllArgsConstructor
+@AtleastOneNonNullField(fieldNames = {"infoTypeEntities", "dataProducerEntities", "dataConsumerEntities"})
 public class ConfigurationEntity {
 
     @Valid
-    private List<InfoTypeEntity> infoTypeEntities;
+    List<InfoTypeEntity> infoTypeEntities;
 
     @Valid
-    private List<DataProducerEntity> dataProducerEntities;
+    List<DataProducerEntity> dataProducerEntities;
 
     @Valid
-    private List<DataConsumerEntity> dataConsumerEntities;
+    List<DataConsumerEntity> dataConsumerEntities;
 }
diff --git a/participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/validator/AtleastOneNonNullField.java b/participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/validator/AtleastOneNonNullField.java
new file mode 100755 (executable)
index 0000000..b79feb7
--- /dev/null
@@ -0,0 +1,43 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.oransc.participant.dme.validator;
+
+import jakarta.validation.Constraint;
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Constraint(validatedBy = AtleastOneNonNullFieldValidator.class)
+public @interface AtleastOneNonNullField {
+
+    String message() default "Atleast one field should not be null.";
+
+    Class<?>[] groups() default {};
+
+    Class<?>[] payload() default {};
+
+    String[] fieldNames();
+}
diff --git a/participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/validator/AtleastOneNonNullFieldValidator.java b/participants/participant-impl-dme/src/main/java/org/oransc/participant/dme/validator/AtleastOneNonNullFieldValidator.java
new file mode 100755 (executable)
index 0000000..6e66a25
--- /dev/null
@@ -0,0 +1,58 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.oransc.participant.dme.validator;
+
+import jakarta.validation.ConstraintValidator;
+import jakarta.validation.ConstraintValidatorContext;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.InvocationTargetException;
+import org.springframework.beans.BeanUtils;
+
+public class AtleastOneNonNullFieldValidator implements ConstraintValidator<AtleastOneNonNullField, Object> {
+
+    String[] fieldNames;
+
+    @Override
+    public void initialize(AtleastOneNonNullField atleastOneNonNullField) {
+        fieldNames = atleastOneNonNullField.fieldNames();
+    }
+
+    @Override
+    public boolean isValid(Object object, ConstraintValidatorContext constraintValidatorContext) {
+        if (object == null) {
+            return false;
+        }
+        for (String fieldName : fieldNames) {
+            try {
+                PropertyDescriptor propertyDescriptor = BeanUtils.getPropertyDescriptor(object.getClass(), fieldName);
+                if (propertyDescriptor != null) {
+                    Object fieldValue = propertyDescriptor.getReadMethod().invoke(object);
+                    if (fieldValue != null) {
+                        return true;
+                    }
+                }
+            } catch (IllegalAccessException | InvocationTargetException e) {
+                return false;
+            }
+        }
+        return false;
+    }
+}
diff --git a/participants/participant-impl-dme/src/test/java/org/oransc/participant/dme/validator/AtleastOneNonNullFieldValidatorTest.java b/participants/participant-impl-dme/src/test/java/org/oransc/participant/dme/validator/AtleastOneNonNullFieldValidatorTest.java
new file mode 100755 (executable)
index 0000000..bbd3d6f
--- /dev/null
@@ -0,0 +1,79 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.oransc.participant.dme.validator;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.when;
+
+import jakarta.validation.ConstraintValidatorContext;
+import java.util.List;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.oransc.participant.dme.models.ConfigurationEntity;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+@ExtendWith(SpringExtension.class)
+class AtleastOneNonNullFieldValidatorTest {
+
+    @Mock
+    AtleastOneNonNullField atleastOneNonNullField;
+    @Mock
+    ConstraintValidatorContext constraintValidatorContext;
+
+    String[] fields = new String[] {"infoTypeEntities", "dataProducerEntities", "dataConsumerEntities"};
+
+    @Test
+    void testValidObject() {
+        when(atleastOneNonNullField.fieldNames()).thenReturn(fields);
+        AtleastOneNonNullFieldValidator atleastOneNonNullFieldValidator = new AtleastOneNonNullFieldValidator();
+        atleastOneNonNullFieldValidator.initialize(atleastOneNonNullField);
+        ConfigurationEntity configurationEntity = new ConfigurationEntity(List.of(), List.of(), List.of());
+        assertTrue(atleastOneNonNullFieldValidator.isValid(configurationEntity, constraintValidatorContext));
+    }
+
+    @Test
+    void testInvalidObject() {
+        when(atleastOneNonNullField.fieldNames()).thenReturn(fields);
+        AtleastOneNonNullFieldValidator atleastOneNonNullFieldValidator = new AtleastOneNonNullFieldValidator();
+        atleastOneNonNullFieldValidator.initialize(atleastOneNonNullField);
+        ConfigurationEntity configurationEntity = new ConfigurationEntity(null, null, null);
+        assertFalse(atleastOneNonNullFieldValidator.isValid(configurationEntity, constraintValidatorContext));
+    }
+
+    @Test
+    void testInvalidField() {
+        when(atleastOneNonNullField.fieldNames()).thenReturn(new String[] {"invalidField"});
+        AtleastOneNonNullFieldValidator atleastOneNonNullFieldValidator = new AtleastOneNonNullFieldValidator();
+        atleastOneNonNullFieldValidator.initialize(atleastOneNonNullField);
+        ConfigurationEntity configurationEntity = new ConfigurationEntity(List.of(), List.of(), List.of());
+        assertFalse(atleastOneNonNullFieldValidator.isValid(configurationEntity, constraintValidatorContext));
+    }
+
+    @Test
+    void testNullObject() {
+        when(atleastOneNonNullField.fieldNames()).thenReturn(new String[] {"invalidField"});
+        AtleastOneNonNullFieldValidator atleastOneNonNullFieldValidator = new AtleastOneNonNullFieldValidator();
+        atleastOneNonNullFieldValidator.initialize(atleastOneNonNullField);
+        assertFalse(atleastOneNonNullFieldValidator.isValid(null, constraintValidatorContext));
+    }
+}