diff options
author | franciscovila <javier.paradela.vila@est.tech> | 2023-05-30 17:03:07 +0100 |
---|---|---|
committer | Michael Morris <michael.morris@est.tech> | 2023-06-02 14:29:33 +0000 |
commit | b206d04b36eb66fc69c1ac96c700d19ca0fbbd37 (patch) | |
tree | 54bea30b1f70670b5763f1499eed8af55a45cd6d | |
parent | 38812c3d47f0426f1c4108145b696441da5a5c1f (diff) |
Support INDEX in node filter tosca functions
Issue-ID: SDC-4517
Signed-off-by: franciscovila <javier.paradela.vila@est.tech>
Change-Id: I36e33821ef72c3375d9525513f2394b9b772c696
5 files changed, 171 insertions, 44 deletions
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/NodeFilterValidator.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/NodeFilterValidator.java index 30fe3dcad1..a0716fe4ce 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/NodeFilterValidator.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/NodeFilterValidator.java @@ -415,6 +415,22 @@ public class NodeFilterValidator { } return null; } + else { + if (null != ((PropertyDefinition) sourcePropDefinition).getSchemaProperty()){ + if (((PropertyDefinition) sourcePropDefinition).getSchemaProperty().getType().equals(targetType)) { + if (TYPES_WITH_SCHEMA.contains(((PropertyDefinition) sourcePropDefinition).getSchemaProperty().getType())) { + final String sourceSchemaType = sourcePropDefinition.getSchemaType(); + final String targetSchemaType = targetPropDefinition.getSchemaType(); + if (sourceSchemaType != null && !sourceSchemaType.equals(targetSchemaType)) { + return componentsUtils.getResponseFormat(ActionStatus.SOURCE_TARGET_SCHEMA_MISMATCH, + targetPropDefinition.getName(), targetSchemaType, sourcePropDefinition.getName(), + sourceSchemaType); + } + } + return null; + } + } + } } else { if (sourceType.equalsIgnoreCase("integer")) { diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/NodeFilterValidatorTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/NodeFilterValidatorTest.java index 67ecb7f675..ef5f7a0a84 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/NodeFilterValidatorTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/NodeFilterValidatorTest.java @@ -27,6 +27,7 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; import fj.data.Either; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -41,6 +42,7 @@ import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.openecomp.sdc.be.config.ConfigurationManager; import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition; import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition; @@ -52,6 +54,7 @@ import org.openecomp.sdc.be.datatypes.tosca.ToscaGetFunctionType; import org.openecomp.sdc.be.impl.ComponentsUtils; import org.openecomp.sdc.be.model.ComponentInstance; import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.DataTypeDefinition; import org.openecomp.sdc.be.model.PropertyDefinition; import org.openecomp.sdc.be.model.Service; import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache; @@ -139,7 +142,7 @@ class NodeFilterValidatorTest { FilterValueType.GET_PROPERTY, ConstraintType.EQUAL, PropertyFilterTargetType.PROPERTY, - createToscaGetFunction("test", PropertySource.INSTANCE, ToscaGetFunctionType.GET_PROPERTY, List.of("test2")) + createToscaGetFunction("test", PropertySource.INSTANCE, ToscaGetFunctionType.GET_PROPERTY, List.of("test2"), null) ); Either<Boolean, ResponseFormat> actualValidationResult = nodeFilterValidator.validateSubstitutionFilter(service, Collections.singletonList(filterConstraint1)); @@ -150,7 +153,7 @@ class NodeFilterValidatorTest { FilterValueType.GET_PROPERTY, ConstraintType.EQUAL, PropertyFilterTargetType.PROPERTY, - createToscaGetFunction(PARENT_SERVICE_ID, PropertySource.SELF, ToscaGetFunctionType.GET_PROPERTY, List.of("Prop1")) + createToscaGetFunction(PARENT_SERVICE_ID, PropertySource.SELF, ToscaGetFunctionType.GET_PROPERTY, List.of("Prop1"), null) ); actualValidationResult = nodeFilterValidator.validateSubstitutionFilter(service, Collections.singletonList(filterConstraint2)); @@ -200,6 +203,41 @@ class NodeFilterValidatorTest { } @Test + void testValidateComponentFilterWithIndex() { + Service service = createService("string", "schema"); + final var filterConstraint1 = buildFilterConstraintDto( + PROPERTY_NAME, + FilterValueType.GET_PROPERTY, + ConstraintType.EQUAL, + PropertyFilterTargetType.PROPERTY, + createToscaGetFunction("test", PropertySource.SELF, ToscaGetFunctionType.GET_PROPERTY, List.of(PROPERTY_NAME, "alist"), List.of("1")) + ); + Map<String, DataTypeDefinition> data = new HashMap<>(); + DataTypeDefinition dataTypeDefinition = new DataTypeDefinition(); + List<PropertyDefinition> properties = new ArrayList<>(); + PropertyDefinition propertyDefinition = new PropertyDefinition(); + propertyDefinition.setName("alist"); + propertyDefinition.setType("list"); + + SchemaDefinition schemaDefinition = new SchemaDefinition(); + PropertyDataDefinition schemaProperty = new PropertyDataDefinition(); + schemaProperty.setType("string"); + schemaDefinition.setProperty(schemaProperty); + propertyDefinition.setSchema(schemaDefinition); + + properties.add(propertyDefinition); + dataTypeDefinition.setProperties(properties); + + data.put("string", dataTypeDefinition); + Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> allDataTypes = Either.left(data); + when(applicationDataTypeCache.getAll(null)).thenReturn(allDataTypes); + + Either<Boolean, ResponseFormat> actualValidationResult = + nodeFilterValidator.validateSubstitutionFilter(service, Collections.singletonList(filterConstraint1)); + assertTrue(actualValidationResult.isLeft()); + } + + @Test void testValidateNodeFilterStaticIncorrectOperatorProvidedBoolean() { Service service = createService(ToscaPropertyType.BOOLEAN.getType()); final FilterConstraintDto filterConstraintDto = buildFilterConstraintDto( @@ -309,7 +347,7 @@ class NodeFilterValidatorTest { void testValidatePropertyConstraintBrotherSuccess() { Service service = createService(ToscaPropertyType.STRING.getType()); final ToscaGetFunctionDataDefinition toscaGetFunction = - createToscaGetFunction(COMPONENT2_ID, PropertySource.INSTANCE, ToscaGetFunctionType.GET_PROPERTY, List.of(PROPERTY_NAME)); + createToscaGetFunction(COMPONENT2_ID, PropertySource.INSTANCE, ToscaGetFunctionType.GET_PROPERTY, List.of(PROPERTY_NAME), null); final var filterConstraintDto = buildFilterConstraintDto( PROPERTY_NAME, FilterValueType.GET_PROPERTY, @@ -328,7 +366,7 @@ class NodeFilterValidatorTest { void testValidatePropertyConstraintParentSuccess() { final var service = createService(ToscaPropertyType.STRING.getType()); final ToscaGetFunctionDataDefinition toscaGetFunction = - createToscaGetFunction(PARENT_SERVICE_ID, PropertySource.SELF, ToscaGetFunctionType.GET_PROPERTY, List.of(PROPERTY_NAME)); + createToscaGetFunction(PARENT_SERVICE_ID, PropertySource.SELF, ToscaGetFunctionType.GET_PROPERTY, List.of(PROPERTY_NAME), null); final var filterConstraintDto = buildFilterConstraintDto( PROPERTY_NAME, FilterValueType.GET_PROPERTY, @@ -348,7 +386,7 @@ class NodeFilterValidatorTest { final Service service = createService(ToscaPropertyType.STRING.getType()); service.getComponentInstancesProperties().get(COMPONENT2_ID).get(0).setType(ToscaPropertyType.INTEGER.getType()); final ToscaGetFunctionDataDefinition toscaGetFunction = - createToscaGetFunction(COMPONENT2_ID, PropertySource.INSTANCE, ToscaGetFunctionType.GET_PROPERTY, List.of(PROPERTY_NAME)); + createToscaGetFunction(COMPONENT2_ID, PropertySource.INSTANCE, ToscaGetFunctionType.GET_PROPERTY, List.of(PROPERTY_NAME), null); final var filterConstraintDto = buildFilterConstraintDto( PROPERTY_NAME, FilterValueType.GET_PROPERTY, @@ -374,7 +412,7 @@ class NodeFilterValidatorTest { final Service service = createService(ToscaPropertyType.STRING.getType()); service.getComponentInstancesProperties().get(COMPONENT1_ID).get(0).setType(ToscaPropertyType.INTEGER.getType()); final ToscaGetFunctionDataDefinition toscaGetFunction = - createToscaGetFunction(PARENT_SERVICE_ID, PropertySource.SELF, ToscaGetFunctionType.GET_PROPERTY, List.of(PROPERTY_NAME)); + createToscaGetFunction(PARENT_SERVICE_ID, PropertySource.SELF, ToscaGetFunctionType.GET_PROPERTY, List.of(PROPERTY_NAME), null); final var filterConstraintDto = buildFilterConstraintDto( PROPERTY_NAME, FilterValueType.GET_PROPERTY, @@ -405,7 +443,7 @@ class NodeFilterValidatorTest { .thenReturn(expectedResponse); final ToscaGetFunctionDataDefinition toscaGetFunction = - createToscaGetFunction(PARENT_SERVICE_ID, PropertySource.SELF, ToscaGetFunctionType.GET_PROPERTY, List.of(PROPERTY_NAME)); + createToscaGetFunction(PARENT_SERVICE_ID, PropertySource.SELF, ToscaGetFunctionType.GET_PROPERTY, List.of(PROPERTY_NAME), null); final var filterConstraintDto = buildFilterConstraintDto( PROPERTY_NAME, FilterValueType.GET_PROPERTY, @@ -425,7 +463,7 @@ class NodeFilterValidatorTest { Service service = createService(ToscaPropertyType.STRING.getType()); service.getComponentInstancesProperties().get(COMPONENT1_ID).get(0).setName("Prop2"); final ToscaGetFunctionDataDefinition toscaGetFunction = - createToscaGetFunction(PARENT_SERVICE_ID, PropertySource.SELF, ToscaGetFunctionType.GET_PROPERTY, List.of(PROPERTY_NAME)); + createToscaGetFunction(PARENT_SERVICE_ID, PropertySource.SELF, ToscaGetFunctionType.GET_PROPERTY, List.of(PROPERTY_NAME), null); final var filterConstraintDto = buildFilterConstraintDto( PROPERTY_NAME, FilterValueType.GET_PROPERTY, @@ -446,13 +484,15 @@ class NodeFilterValidatorTest { protected static ToscaGetFunctionDataDefinition createToscaGetFunction(final String sourceName, final PropertySource propertySource, final ToscaGetFunctionType toscaGetFunctionType, - final List<String> propertyPathFromSource) { + final List<String> propertyPathFromSource, + final List<Object> toscaIndexList) { final var toscaGetFunction = new ToscaGetFunctionDataDefinition(); toscaGetFunction.setFunctionType(toscaGetFunctionType); toscaGetFunction.setPropertyPathFromSource(propertyPathFromSource); toscaGetFunction.setSourceName(sourceName); toscaGetFunction.setPropertySource(propertySource); toscaGetFunction.setPropertyName(propertyPathFromSource.get(0)); + toscaGetFunction.setToscaIndexList(toscaIndexList); return toscaGetFunction; } @@ -467,7 +507,7 @@ class NodeFilterValidatorTest { service.getComponentInstancesProperties().get(COMPONENT1_ID).get(0).setSchema(schemaDefinition); final ToscaGetFunctionDataDefinition toscaGetFunction = - createToscaGetFunction(PARENT_SERVICE_ID, PropertySource.SELF, ToscaGetFunctionType.GET_PROPERTY, List.of(PROPERTY_NAME)); + createToscaGetFunction(PARENT_SERVICE_ID, PropertySource.SELF, ToscaGetFunctionType.GET_PROPERTY, List.of(PROPERTY_NAME), null); final var filterConstraintDto = buildFilterConstraintDto( PROPERTY_NAME, FilterValueType.GET_PROPERTY, diff --git a/common-be/src/main/java/org/openecomp/sdc/be/utils/PropertyFilterConstraintDataDefinitionHelper.java b/common-be/src/main/java/org/openecomp/sdc/be/utils/PropertyFilterConstraintDataDefinitionHelper.java index 63c6781b94..6377152a13 100644 --- a/common-be/src/main/java/org/openecomp/sdc/be/utils/PropertyFilterConstraintDataDefinitionHelper.java +++ b/common-be/src/main/java/org/openecomp/sdc/be/utils/PropertyFilterConstraintDataDefinitionHelper.java @@ -21,12 +21,16 @@ package org.openecomp.sdc.be.utils; +import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; import lombok.AccessLevel; import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; import org.openecomp.sdc.be.datatypes.elements.PropertyFilterConstraintDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ToscaConcatFunction; import org.openecomp.sdc.be.datatypes.elements.ToscaFunction; @@ -39,7 +43,6 @@ import org.openecomp.sdc.be.datatypes.enums.FilterValueType; import org.openecomp.sdc.be.datatypes.enums.PropertyFilterTargetType; import org.openecomp.sdc.be.datatypes.enums.PropertySource; import org.openecomp.sdc.be.datatypes.tosca.ToscaGetFunctionType; -import org.openecomp.sdc.exception.InvalidArgumentException; import org.yaml.snakeyaml.Yaml; @NoArgsConstructor(access = AccessLevel.PRIVATE) @@ -125,53 +128,104 @@ public class PropertyFilterConstraintDataDefinitionHelper { private static Optional<ToscaFunction> readLegacyGetPropertyConstraintValue(Map<?, ?> filterValueAsMap, Object toscaFunctionType, ToscaFunctionType toscaFunctionType1) { - final var toscaGetFunction = new ToscaGetFunctionDataDefinition(); - toscaGetFunction.setFunctionType(ToscaGetFunctionType.fromToscaFunctionType(toscaFunctionType1) - .orElseThrow(() -> new InvalidArgumentException("Could not convert a ToscaFunctionType to a ToscaGetFunctionType")) + final ToscaGetFunctionDataDefinition toscaGetFunction = new ToscaGetFunctionDataDefinition(); + toscaGetFunction.setFunctionType( + toscaFunctionType.toString().equalsIgnoreCase(ToscaFunctionType.GET_PROPERTY.getName()) ? ToscaGetFunctionType.GET_PROPERTY : ToscaGetFunctionType.GET_ATTRIBUTE ); - final List<String> getFunctionValue; + final Object functionValueObj = null != filterValueAsMap.get(toscaFunctionType1) ? + filterValueAsMap.get(toscaFunctionType1) : filterValueAsMap.get(toscaFunctionType); + if (!(functionValueObj instanceof List)) { + return Optional.empty(); + } + final List<String> functionParameters; try { - getFunctionValue = (List<String>) filterValueAsMap.get(toscaFunctionType); - } catch (final Exception ignored) { - return Optional.of(toscaGetFunction); + functionParameters = ((List<Object>) functionValueObj).stream() + .map(object -> Objects.toString(object, null)) + .collect(Collectors.toList()); + } catch (final ClassCastException ignored) { + return Optional.empty(); } - if (!getFunctionValue.isEmpty()) { - final Optional<PropertySource> propertySource = PropertySource.findType(getFunctionValue.get(0)); - if (propertySource.isPresent()) { - toscaGetFunction.setPropertySource(propertySource.get()); - } else { - toscaGetFunction.setPropertySource(PropertySource.INSTANCE); - toscaGetFunction.setSourceName(getFunctionValue.get(0)); + if (functionParameters.size() < 2) { + return Optional.empty(); + } + final String propertySourceType = functionParameters.get(0); + final PropertySource propertySource = PropertySource.findType(propertySourceType).orElse(null); + if (propertySource == PropertySource.SELF) { + toscaGetFunction.setPropertySource(propertySource); + } else { + toscaGetFunction.setPropertySource(PropertySource.INSTANCE); + toscaGetFunction.setSourceName(propertySourceType); + } + List<String> propertySourceIndex = functionParameters.subList(1, functionParameters.size()); + List<String> propertySourcePath = new ArrayList<>(); + propertySourcePath.add((String)propertySourceIndex.get(0)); + if (propertySourceIndex.size() > 1 ) { + List<Object> indexParsedList = new ArrayList<Object>(); + List<String> indexObjectList = propertySourceIndex.subList(1,propertySourceIndex.size()); + boolean loopFlag = true; + for (String indexValue : indexObjectList) { + if (!indexValue.equalsIgnoreCase("INDEX") && !StringUtils.isNumeric(indexValue) && loopFlag) { + propertySourcePath.add(indexValue); + } else { + loopFlag = false; + if (StringUtils.isNumeric(indexValue)) { + indexParsedList.add(Integer.parseInt(indexValue)); + } else { + indexParsedList.add(indexValue); + } + } } - final List<String> propertyPathFromSource = getFunctionValue.subList(1, getFunctionValue.size()); - toscaGetFunction.setPropertyPathFromSource(propertyPathFromSource); - toscaGetFunction.setPropertyName(propertyPathFromSource.get(propertyPathFromSource.size() - 1)); + toscaGetFunction.setToscaIndexList(indexParsedList); } + toscaGetFunction.setPropertyPathFromSource(propertySourcePath); + final String propertyName = toscaGetFunction.getPropertyPathFromSource().get(toscaGetFunction.getPropertyPathFromSource().size() - 1); + toscaGetFunction.setPropertyName(propertyName); return Optional.of(toscaGetFunction); } private static Optional<ToscaFunction> readLegacyGetInputConstraintValue(Map<?, ?> filterValueAsMap, Object toscaFunctionType) { - final var toscaGetFunction = new ToscaGetFunctionDataDefinition(); + final ToscaGetFunctionDataDefinition toscaGetFunction = new ToscaGetFunctionDataDefinition(); toscaGetFunction.setFunctionType(ToscaGetFunctionType.GET_INPUT); - final List<String> getFunctionValue; - final Object valueAsObject = filterValueAsMap.get(toscaFunctionType); - if (valueAsObject instanceof String) { - getFunctionValue = List.of((String) valueAsObject); - } else if (valueAsObject instanceof List) { + toscaGetFunction.setPropertySource(PropertySource.SELF); + final Object functionValueObj = filterValueAsMap.get(toscaFunctionType); + if (!(functionValueObj instanceof List) && !(functionValueObj instanceof String)) { + return Optional.empty(); + } + if (functionValueObj instanceof String) { + toscaGetFunction.setPropertyPathFromSource(List.of((String) functionValueObj)); + } else { + final List<String> functionParameters; try { - getFunctionValue = (List<String>) filterValueAsMap.get(toscaFunctionType); - } catch (final Exception ignored) { + functionParameters = ((List<Object>) functionValueObj).stream() + .map(object -> Objects.toString(object, null)) + .collect(Collectors.toList()); + } catch (final ClassCastException ignored) { return Optional.empty(); } - } else { - return Optional.empty(); - } - - toscaGetFunction.setPropertyPathFromSource(getFunctionValue); - if (!getFunctionValue.isEmpty()) { - toscaGetFunction.setPropertyName(getFunctionValue.get(getFunctionValue.size() - 1)); + List<String> propertySourcePath = new ArrayList<>(); + propertySourcePath.add((String)functionParameters.get(0)); + if (functionParameters.size() > 1 ) { + List<Object> indexParsedList = new ArrayList<Object>(); + List<String> indexObjectList = functionParameters.subList(1,functionParameters.size()); + boolean loopFlag = true; + for (String indexValue : indexObjectList) { + if (!indexValue.equalsIgnoreCase("INDEX") && !StringUtils.isNumeric(indexValue) && loopFlag) { + propertySourcePath.add(indexValue); + } else { + loopFlag = false; + if (StringUtils.isNumeric(indexValue)) { + indexParsedList.add(Integer.parseInt(indexValue)); + } else { + indexParsedList.add(indexValue); + } + } + } + toscaGetFunction.setToscaIndexList(indexParsedList); + } + toscaGetFunction.setPropertyPathFromSource(propertySourcePath); } - toscaGetFunction.setPropertySource(PropertySource.SELF); + final String propertyName = toscaGetFunction.getPropertyPathFromSource().get(toscaGetFunction.getPropertyPathFromSource().size() - 1); + toscaGetFunction.setPropertyName(propertyName); return Optional.of(toscaGetFunction); } diff --git a/common-be/src/test/java/org/openecomp/sdc/be/utils/PropertyFilterConstraintDataDefinitionHelperTest.java b/common-be/src/test/java/org/openecomp/sdc/be/utils/PropertyFilterConstraintDataDefinitionHelperTest.java index 86548fa1d5..5684db2332 100644 --- a/common-be/src/test/java/org/openecomp/sdc/be/utils/PropertyFilterConstraintDataDefinitionHelperTest.java +++ b/common-be/src/test/java/org/openecomp/sdc/be/utils/PropertyFilterConstraintDataDefinitionHelperTest.java @@ -77,6 +77,17 @@ class PropertyFilterConstraintDataDefinitionHelperTest { } @Test + void convertLegacyConstraintGetInputFromSelfTest() throws IOException { + final PropertyFilterConstraintDataDefinition propertyFilterConstraint = + PropertyFilterConstraintDataDefinitionHelper.convertLegacyConstraint(readConstraintFile("legacy-get_input-from-self.yaml")); + assertPropertyFilterConstraint(propertyFilterConstraint, "flavour_id", null, ConstraintType.EQUAL, FilterValueType.GET_INPUT); + assertTrue(propertyFilterConstraint.getValue() instanceof ToscaGetFunctionDataDefinition); + final var toscaGetFunction = (ToscaGetFunctionDataDefinition) propertyFilterConstraint.getValue(); + assertToscaGetFunction(toscaGetFunction, ToscaFunctionType.GET_INPUT, ToscaGetFunctionType.GET_INPUT, PropertySource.SELF, + List.of("SELF", "input", "subInput"), "subInput", null); + } + + @Test void convertLegacyConstraintGetAttributeFromInstanceTest() throws IOException { final PropertyFilterConstraintDataDefinition propertyFilterConstraint = PropertyFilterConstraintDataDefinitionHelper.convertLegacyConstraint(readConstraintFile("legacy-get_attribute-from-instance.yaml")); diff --git a/common-be/src/test/resources/nodeFilter/constraints/legacy-get_input-from-self.yaml b/common-be/src/test/resources/nodeFilter/constraints/legacy-get_input-from-self.yaml new file mode 100644 index 0000000000..a12444e8c1 --- /dev/null +++ b/common-be/src/test/resources/nodeFilter/constraints/legacy-get_input-from-self.yaml @@ -0,0 +1,6 @@ +flavour_id: + equal: + get_input: + - SELF + - input + - subInput
\ No newline at end of file |