From 1118d15dad97ee855e504e036e292f2395171d4d Mon Sep 17 00:00:00 2001 From: imamSidero Date: Mon, 26 Sep 2022 15:04:33 +0100 Subject: Constraint validation for instance properties in a service Validating the properties of instance in a service against it's constraints Issue-ID: SDC-4190 Signed-off-by: Imam hussain Change-Id: I04bb907f52229c3d214e15434595e5429ef5101c --- .../impl/ComponentInstanceBusinessLogic.java | 22 +++++++++++++- .../PropertyValueConstraintValidationUtil.java | 9 ++++++ .../impl/ComponentInstanceBusinessLogicTest.java | 35 ++++++++++++++++++++-- .../impl/ResourceInstanceBusinessLogicTest.java | 4 +-- 4 files changed, 64 insertions(+), 6 deletions(-) (limited to 'catalog-be') diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java index 1d10c92313..0b3610a611 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java @@ -63,6 +63,7 @@ import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum; import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.datamodel.utils.PropertyValueConstraintValidationUtil; import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition; import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition; @@ -187,6 +188,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { @Autowired private ContainerInstanceTypesData containerInstanceTypesData; private final ToscaFunctionValidator toscaFunctionValidator; + private final PropertyBusinessLogic propertyBusinessLogic; @Autowired public ComponentInstanceBusinessLogic(IElementOperation elementDao, IGroupOperation groupOperation, @@ -196,7 +198,8 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { ComponentInstanceMergeDataBusinessLogic compInstMergeDataBL, ComponentInstanceChangeOperationOrchestrator onChangeInstanceOperationOrchestrator, ForwardingPathOperation forwardingPathOperation, NodeFilterOperation nodeFilterOperation, - ArtifactsOperations artifactToscaOperation, final ToscaFunctionValidator toscaFunctionValidator) { + ArtifactsOperations artifactToscaOperation, final ToscaFunctionValidator toscaFunctionValidator, + PropertyBusinessLogic propertyBusinessLogic) { super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation, artifactToscaOperation); this.componentInstanceOperation = componentInstanceOperation; @@ -206,6 +209,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { this.forwardingPathOperation = forwardingPathOperation; this.nodeFilterOperation = nodeFilterOperation; this.toscaFunctionValidator = toscaFunctionValidator; + this.propertyBusinessLogic = propertyBusinessLogic; } public ComponentInstance createComponentInstance(String containerComponentParam, String containerComponentId, String userId, @@ -1953,6 +1957,12 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { } ComponentInstance foundResourceInstance = resourceInstanceStatus.left().value(); + // Validate instance property against it's constrains + Either constraintValidatorResponse = validatePropertyValueConstraint(properties,componentId); + if (constraintValidatorResponse.isRight()) { + log.error("Failed validation value and constraint of property: {}", constraintValidatorResponse.right().value()); + return Either.right(constraintValidatorResponse.right().value()); + } // lock resource StorageOperationStatus lockStatus = graphLockOperation.lockComponent(componentId, componentTypeEnum.getNodeType()); if (lockStatus != StorageOperationStatus.OK) { @@ -3908,6 +3918,16 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { } } + private Either validatePropertyValueConstraint(List properties, final String componentId) { + try { + String propertyModel = propertyBusinessLogic.getComponentModelByComponentId(componentId); + PropertyValueConstraintValidationUtil propertyValueConstraintValidationUtil = new PropertyValueConstraintValidationUtil(); + return propertyValueConstraintValidationUtil.validatePropertyConstraints(properties, applicationDataTypeCache, propertyModel); + } catch (BusinessLogicException e) { + return Either.right(e.getResponseFormat()); + } + } + public void validateUser(final String userId) { final User user = userValidations.validateUserExists(userId); userValidations.validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN)); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/PropertyValueConstraintValidationUtil.java b/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/PropertyValueConstraintValidationUtil.java index 442c3da16c..2d3ef85488 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/PropertyValueConstraintValidationUtil.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/PropertyValueConstraintValidationUtil.java @@ -34,6 +34,7 @@ import org.apache.commons.lang3.StringUtils; import org.openecomp.sdc.be.components.impl.ResponseFormatManager; import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition; +import org.openecomp.sdc.be.model.ComponentInstanceInput; import org.openecomp.sdc.be.model.DataTypeDefinition; import org.openecomp.sdc.be.model.InputDefinition; import org.openecomp.sdc.be.model.PropertyConstraint; @@ -77,6 +78,9 @@ public class PropertyValueConstraintValidationUtil { } private boolean isValuePresent(PropertyDefinition propertyDefinition) { + if (propertyDefinition instanceof ComponentInstanceInput) { + return StringUtils.isNotEmpty(propertyDefinition.getValue()); + } if (propertyDefinition instanceof InputDefinition) { return StringUtils.isNotEmpty(propertyDefinition.getDefaultValue()); } @@ -90,6 +94,11 @@ public class PropertyValueConstraintValidationUtil { } completeInputName = ""; completePropertyName = new StringBuilder(); + if (propertyDefinition instanceof ComponentInstanceInput) { + setCompletePropertyName(propertyDefinition); + evaluateComplexTypeProperties(propertyDefinition); + return; + } if (propertyDefinition instanceof InputDefinition) { completeInputName = propertyDefinition.getName(); propertyDefinition = getPropertyDefinitionObjectFromInputs(propertyDefinition); diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogicTest.java index 3a5f40cb8c..f22b346052 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogicTest.java @@ -51,6 +51,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; +import lombok.SneakyThrows; import mockit.Deencapsulation; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; @@ -72,6 +73,7 @@ import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.dao.janusgraph.JanusGraphDao; import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum; +import org.openecomp.sdc.be.datamodel.utils.PropertyValueConstraintValidationUtil; import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ForwardingPathElementDataDefinition; @@ -190,7 +192,8 @@ class ComponentInstanceBusinessLogicTest { private CompositionBusinessLogic compositionBusinessLogic; @Mock private ToscaFunctionValidator toscaFunctionValidator; - + @Mock + private PropertyBusinessLogic propertyBusinessLogic; private Component service; private Component resource; private ComponentInstance toInstance; @@ -216,7 +219,7 @@ class ComponentInstanceBusinessLogicTest { void init() { MockitoAnnotations.openMocks(this); componentInstanceBusinessLogic = new ComponentInstanceBusinessLogic(null, null, null, null, null, null, null, artifactsBusinessLogic, null, - null, forwardingPathOperation, null, null, toscaFunctionValidator); + null, forwardingPathOperation, null, null, toscaFunctionValidator, propertyBusinessLogic); componentInstanceBusinessLogic.setComponentsUtils(componentsUtils); componentInstanceBusinessLogic.setToscaOperationFacade(toscaOperationFacade); componentInstanceBusinessLogic.setUserValidations(userValidations); @@ -305,6 +308,7 @@ class ComponentInstanceBusinessLogicTest { } + @SneakyThrows @Test void testCreateOrUpdatePropertiesValues2() { String containerComponentID = "containerId"; @@ -356,6 +360,10 @@ class ComponentInstanceBusinessLogicTest { when(janusGraphDao.commit()).thenReturn(JanusGraphOperationStatus.OK); when(graphLockOperation.unlockComponent(containerComponentID, NodeTypeEnum.ResourceInstance)) .thenReturn(StorageOperationStatus.OK); + when(propertyBusinessLogic.getComponentModelByComponentId(any())).thenReturn(component.getModel()); + when(applicationDataTypeCache.getAll(any())).thenReturn(Either.left(types)); + PropertyValueConstraintValidationUtil validationUtil = Mockito.mock(PropertyValueConstraintValidationUtil.class); + when(validationUtil.validatePropertyConstraints(any(),any(),any())).thenReturn(Either.left(any())); Either, ResponseFormat> responseFormatEither = componentInstanceBusinessLogic .createOrUpdatePropertiesValues( @@ -365,6 +373,7 @@ class ComponentInstanceBusinessLogicTest { + @SneakyThrows @Test void testCreateOrUpdatePropertiesValuesPropertyNotExists() { String containerComponentID = "containerId"; @@ -396,6 +405,12 @@ class ComponentInstanceBusinessLogicTest { .thenReturn(StorageOperationStatus.OK); when(graphLockOperation.unlockComponent(containerComponentID, NodeTypeEnum.ResourceInstance)) .thenReturn(StorageOperationStatus.OK); + when(propertyBusinessLogic.getComponentModelByComponentId(any())).thenReturn(component.getModel()); + Map dataTypeMap = new HashMap<>(); + when(applicationDataTypeCache.getAll(any())).thenReturn(Either.left(dataTypeMap)); + PropertyValueConstraintValidationUtil validationUtil = Mockito.mock(PropertyValueConstraintValidationUtil.class); + when(validationUtil.validatePropertyConstraints(any(),any(),any())) + .thenReturn(Either.left(any())); try { componentInstanceBusinessLogic.createOrUpdatePropertiesValues( @@ -406,6 +421,7 @@ class ComponentInstanceBusinessLogicTest { } + @SneakyThrows @Test void testCreateOrUpdatePropertiesValuesValidationFailure() { String containerComponentID = "containerId"; @@ -449,15 +465,22 @@ class ComponentInstanceBusinessLogicTest { .thenReturn(Either.right(false)); when(componentsUtils.convertFromStorageResponse(StorageOperationStatus.BAD_REQUEST)) .thenReturn(ActionStatus.INVALID_CONTENT); + when(propertyBusinessLogic.getComponentModelByComponentId(any())).thenReturn(component.getModel()); + Map dataTypeMap = new HashMap<>(); + when(applicationDataTypeCache.getAll(any())).thenReturn(Either.left(dataTypeMap)); + PropertyValueConstraintValidationUtil validationUtil = Mockito.mock(PropertyValueConstraintValidationUtil.class); + when(validationUtil.validatePropertyConstraints(any(),any(),any())) + .thenReturn(Either.left(any())); final Either, ResponseFormat> response = componentInstanceBusinessLogic.createOrUpdatePropertiesValues( ComponentTypeEnum.RESOURCE_INSTANCE, containerComponentID, resourceInstanceId, properties, "userId"); assertThat(response.isRight()).as("Response should be an error").isTrue(); final ResponseFormat responseFormat = response.right().value(); assertThat(responseFormat.getStatus()).as("Response status should be as expected").isEqualTo(400); - assertThat(responseFormat.getMessageId()).as("Error message id should be as expected").isEqualTo("SVC4000"); + assertThat(responseFormat.getMessageId()).as("Error message id should be as expected").isEqualTo("SVC4726"); } + @SneakyThrows @Test void testCreateOrUpdatePropertiesValuesMissingFieldFailure() { String containerComponentID = "containerId"; @@ -491,6 +514,12 @@ class ComponentInstanceBusinessLogicTest { .thenReturn(Either.left(component)); when(graphLockOperation.lockComponent(containerComponentID, NodeTypeEnum.ResourceInstance)) .thenReturn(StorageOperationStatus.OK); + when(propertyBusinessLogic.getComponentModelByComponentId(any())).thenReturn(component.getModel()); + Map dataTypeMap = new HashMap<>(); + when(applicationDataTypeCache.getAll(any())).thenReturn(Either.left(dataTypeMap)); + PropertyValueConstraintValidationUtil validationUtil = Mockito.mock(PropertyValueConstraintValidationUtil.class); + when(validationUtil.validatePropertyConstraints(any(),any(),any())) + .thenReturn(Either.left(any())); try { componentInstanceBusinessLogic.createOrUpdatePropertiesValues( diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceInstanceBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceInstanceBusinessLogicTest.java index 8bd39af919..e5ecf0cc05 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceInstanceBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceInstanceBusinessLogicTest.java @@ -90,7 +90,7 @@ class ResourceInstanceBusinessLogicTest extends BaseBusinessLogicMock { private final ForwardingPathOperation forwardingPathOperation = mock(ForwardingPathOperation.class); private final NodeFilterOperation serviceFilterOperation = mock(NodeFilterOperation.class); private final ToscaFunctionValidator toscaFunctionValidator = mock(ToscaFunctionValidator.class); - + private final PropertyBusinessLogic propertyBusinessLogic = mock(PropertyBusinessLogic.class); private static final UserBusinessLogic userAdminManager = mock(UserBusinessLogic.class); public static final ComponentsUtils componentsUtils = mock(ComponentsUtils.class); public static final IGroupInstanceOperation groupInstanceOperation = mock(IGroupInstanceOperation.class); @@ -101,7 +101,7 @@ class ResourceInstanceBusinessLogicTest extends BaseBusinessLogicMock { private final ComponentInstanceBusinessLogic bl = new ComponentInstanceBusinessLogic(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation, componentInstanceOperation, artifactBusinessLogic, compInstMergeDataBL, onChangeInstanceOperationOrchestrator, - forwardingPathOperation, serviceFilterOperation, artifactToscaOperation, toscaFunctionValidator); + forwardingPathOperation, serviceFilterOperation, artifactToscaOperation, toscaFunctionValidator, propertyBusinessLogic); @BeforeEach void setUp() throws Exception { -- cgit 1.2.3-korg