diff options
author | andre.schmid <andre.schmid@est.tech> | 2022-08-10 14:50:08 +0100 |
---|---|---|
committer | Vasyl Razinkov <vasyl.razinkov@est.tech> | 2022-09-08 18:24:44 +0000 |
commit | 92b18f188105d5ba4b2c469cdfaedc7d2953d593 (patch) | |
tree | df7c7562faa99a76b0e6b5bc079de8d514b35006 | |
parent | c0c2637f201f488a74cb1916f05eece0cc207e9d (diff) |
Support TOSCA functions in Node Filters
Adds support to use tosca functions as value in the node property
filters and substitution filters
Change-Id: Id242691cc9ddd233245b58f052b9f0e2c7bbd66b
Issue-ID: SDC-4128
Signed-off-by: André Schmid <andre.schmid@est.tech>
135 files changed, 5476 insertions, 2421 deletions
diff --git a/catalog-be-plugins/etsi-nfv-nsd-csar-plugin/src/main/java/org/openecomp/sdc/be/plugins/etsi/nfv/nsd/generator/NsDescriptorGeneratorImpl.java b/catalog-be-plugins/etsi-nfv-nsd-csar-plugin/src/main/java/org/openecomp/sdc/be/plugins/etsi/nfv/nsd/generator/NsDescriptorGeneratorImpl.java index fd5255cab6..18ba2ec21b 100644 --- a/catalog-be-plugins/etsi-nfv-nsd-csar-plugin/src/main/java/org/openecomp/sdc/be/plugins/etsi/nfv/nsd/generator/NsDescriptorGeneratorImpl.java +++ b/catalog-be-plugins/etsi-nfv-nsd-csar-plugin/src/main/java/org/openecomp/sdc/be/plugins/etsi/nfv/nsd/generator/NsDescriptorGeneratorImpl.java @@ -34,7 +34,7 @@ import org.apache.commons.collections4.MapUtils; import org.openecomp.sdc.be.config.ConfigurationManager; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.model.Component; -import org.openecomp.sdc.be.model.tosca.constraints.ConstraintType; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; import org.openecomp.sdc.be.plugins.etsi.nfv.nsd.exception.NsdException; import org.openecomp.sdc.be.plugins.etsi.nfv.nsd.model.Nsd; import org.openecomp.sdc.be.plugins.etsi.nfv.nsd.model.VnfDescriptor; diff --git a/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml b/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml index 50a7014f10..7eb5ee47e9 100644 --- a/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml +++ b/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml @@ -2302,13 +2302,14 @@ errors: messageId: "SVC4716" } - #---------SVC4717---------------------------- - # %1 - Property Name - MAPPED_PROPERTY_NOT_FOUND: { - code: 400, - message: "Error: %1 property does not exist.", - messageId: "SVC4717" - } + #---------SVC4184---------------------------- + # %1 - Source type + # %2 - Property Type + # %3 - Property Name + FILTER_PROPERTY_NOT_FOUND: + code: 400 + message: "%1 %2 %3 does not exist." + messageId: "SVC4184" #---------SVC4718---------------------------- # %1 - Property Name @@ -2326,13 +2327,13 @@ errors: messageId: "SVC4719" } - #---------SVC4720---------------------------- + #---------SVC4182---------------------------- # %1 - Property Name # %2 - Operator Type SOURCE_TARGET_PROPERTY_TYPE_MISMATCH: { code: 400, - message: "Error: %1 property and %2 property type is not same.", - messageId: "SVC4720" + message: "Error: Property '%1' type '%2' does not match with property '%3' type '%4'.", + messageId: "SVC4182" } #---------SVC4721---------------------------- @@ -2420,7 +2421,7 @@ errors: messageId: "SVC4734" } #-----------SVC4735--------------------------- - #%1 - input name + #%1 - input name INPUT_ALREADY_EXIST: { code: 409, message: "Error: Input with '%1' name already exists.", @@ -2746,3 +2747,69 @@ errors: message: "Relationship_templates definition not found in TOSCA CSAR.", messageId: "SVC4174" } + + #-----------SVC4175--------------------------- + TOSCA_FUNCTION_EXPECTED_ERROR: { + code: 400, + message: "Expecting a Tosca Function value.", + messageId: "SVC4175" + } + + #-----------SVC4176--------------------------- + FILTER_CONSTRAINT_MISSING: { + code: 400, + message: "The filter constraint was not provided.", + messageId: "SVC4176" + } + + #-----------SVC4177--------------------------- + #%1 - The missing field + FILTER_CONSTRAINT_MISSING_FIELD: { + code: 400, + message: "Required field '%1' is missing in the filter constraint.", + messageId: "SVC4177" + } + + #%1 - the component id + SUBSTITUTION_FILTER_NOT_FOUND: { + code: 404, + message: 'Substitution filter not found in the component "%1"', + messageId: "SVC4178" + } + + # %1 - Component name + COMPONENT_DOES_NOT_HAVE_INPUTS: { + code: 400, + message: "Component '%1' does not have inputs.", + messageId: "SVC4179" + } + + # %1 - Input name + # %2 - Component name + COMPONENT_INPUT_NOT_FOUND: { + code: 400, + message: "Input '%1' does not exist in '%2'.", + messageId: "SVC4180" + } + + # %1 - Target property name + # %2 - Source property name + SOURCE_TARGET_SCHEMA_MISMATCH: { + code: 400, + message: "Target property '%1' schema '%2' does not match with source property '%3' schema '%4'.", + messageId: "SVC4181" + } + + # %1 - Property name + # %2 - Component name + COMPONENT_PROPERTY_NOT_FOUND: + code: 400 + message: "Property '%1' does not exist in '%2'." + messageId: "SVC4183" + + # %1 - The component type + # %2 - The expected component types + INVALID_COMPONENT_TYPE: + code: 400 + message: "Invalid component type '%1'. Expected types are: %2" + messageId: "SVC4185" diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandler.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandler.java index 25d5c1f43e..82aa1343c1 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandler.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandler.java @@ -103,7 +103,12 @@ import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition; import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition; import org.openecomp.sdc.be.datatypes.elements.PolicyTargetType; import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; -import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterPropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyFilterConstraintDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterPropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ToscaFunction; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; +import org.openecomp.sdc.be.datatypes.enums.FilterValueType; +import org.openecomp.sdc.be.datatypes.enums.PropertyFilterTargetType; import org.openecomp.sdc.be.model.CapabilityDefinition; import org.openecomp.sdc.be.model.Component; import org.openecomp.sdc.be.model.ComponentInstanceProperty; @@ -128,6 +133,7 @@ import org.openecomp.sdc.be.tosca.model.ToscaInterfaceDefinition; import org.openecomp.sdc.be.tosca.utils.OperationArtifactUtil; import org.openecomp.sdc.be.ui.model.OperationUi; import org.openecomp.sdc.be.ui.model.PropertyAssignmentUi; +import org.openecomp.sdc.be.utils.PropertyFilterConstraintDataDefinitionHelper; import org.openecomp.sdc.be.utils.TypeUtils; import org.openecomp.sdc.common.log.wrappers.Logger; import org.yaml.snakeyaml.parser.ParserException; @@ -236,8 +242,8 @@ public class YamlTemplateParsingHandler { return ImportUtils.getProperties(toscaJson).left().on(err -> new HashMap<>()); } - private ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> getSubstitutionFilterProperties(Map<String, Object> toscaJson) { - ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> propertyList = new ListDataDefinition<>(); + private ListDataDefinition<SubstitutionFilterPropertyDataDefinition> getSubstitutionFilterProperties(Map<String, Object> toscaJson) { + ListDataDefinition<SubstitutionFilterPropertyDataDefinition> propertyList = new ListDataDefinition<>(); Map<String, Object> substitutionFilters = findFirstToscaMapElement(toscaJson, SUBSTITUTION_FILTERS).left().on(err -> new HashMap<>()); if (MapUtils.isEmpty(substitutionFilters)) { return propertyList; @@ -248,25 +254,41 @@ public class YamlTemplateParsingHandler { return propertyList; } for (Map<String, List<Map<String, Object>>> filterProps : substitutionFilterProperties) { - for (Map.Entry<String, List<Map<String, Object>>> filterPropsMap : filterProps.entrySet()) { - for (Map<String, Object> mapValue : filterPropsMap.getValue()) { - RequirementSubstitutionFilterPropertyDataDefinition requirementSubstitutionFilterPropertyDataDefinition = - new RequirementSubstitutionFilterPropertyDataDefinition(); - requirementSubstitutionFilterPropertyDataDefinition.setName(filterPropsMap.getKey()); - requirementSubstitutionFilterPropertyDataDefinition.setConstraints( - getSubstitutionFilterConstraints(filterPropsMap.getKey(), mapValue)); - propertyList.add(requirementSubstitutionFilterPropertyDataDefinition); + for (Map.Entry<String, List<Map<String, Object>>> propertyFilterEntry : filterProps.entrySet()) { + final String propertyName = propertyFilterEntry.getKey(); + for (Map<String, Object> filterValueMap : propertyFilterEntry.getValue()) { + final var substitutionFilterPropertyDataDefinition = new SubstitutionFilterPropertyDataDefinition(); + substitutionFilterPropertyDataDefinition.setName(propertyName); + substitutionFilterPropertyDataDefinition.setConstraints(createSubstitutionFilterConstraints(propertyName, filterValueMap)); + propertyList.add(substitutionFilterPropertyDataDefinition); } } } return propertyList; } - private List<String> getSubstitutionFilterConstraints(String name, Map<String, Object> value) { - List<String> constraints = new ArrayList<>(); - for (Map.Entry<String, Object> valueMap : value.entrySet()) { - constraints.add(name + ": {" + valueMap.getKey() + ": " + valueMap.getValue() + "}"); + private List<PropertyFilterConstraintDataDefinition> createSubstitutionFilterConstraints(final String name, final Map<String, Object> value) { + final List<PropertyFilterConstraintDataDefinition> constraints = new ArrayList<>(); + for (final Map.Entry<String, Object> valueEntry : value.entrySet()) { + final var propertyFilterConstraint = new PropertyFilterConstraintDataDefinition(); + propertyFilterConstraint.setPropertyName(name); + propertyFilterConstraint.setOperator(ConstraintType.findByType(valueEntry.getKey()).orElse(null)); + propertyFilterConstraint.setTargetType(PropertyFilterTargetType.PROPERTY); + final Optional<ToscaFunction> toscaFunction = PropertyFilterConstraintDataDefinitionHelper + .createToscaFunctionFromLegacyConstraintValue(valueEntry.getValue()); + if (toscaFunction.isPresent()) { + final ToscaFunction toscaFunction1 = toscaFunction.get(); + propertyFilterConstraint.setValue(toscaFunction1); + propertyFilterConstraint.setValueType( + PropertyFilterConstraintDataDefinitionHelper.convertFromToscaFunctionType(toscaFunction1.getType()).orElse(null) + ); + } else { + propertyFilterConstraint.setValue(valueEntry.getValue()); + propertyFilterConstraint.setValueType(FilterValueType.STATIC); + } + constraints.add(propertyFilterConstraint); } + return constraints; } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentNodeFilterBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentNodeFilterBusinessLogic.java index 65b5794687..ff65d84416 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentNodeFilterBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentNodeFilterBusinessLogic.java @@ -21,9 +21,7 @@ package org.openecomp.sdc.be.components.impl; import static org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR; import fj.data.Either; -import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -31,21 +29,19 @@ import java.util.Optional; import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException; import org.openecomp.sdc.be.components.impl.exceptions.ComponentException; import org.openecomp.sdc.be.components.impl.utils.CINodeFilterUtils; -import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction; import org.openecomp.sdc.be.components.validation.NodeFilterValidator; import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.datamodel.utils.ConstraintConvertor; import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyFilterDataDefinition; import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterCapabilityDataDefinition; -import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.datatypes.enums.NodeFilterConstraintType; import org.openecomp.sdc.be.model.Component; import org.openecomp.sdc.be.model.ComponentInstance; -import org.openecomp.sdc.be.model.ComponentInstanceProperty; import org.openecomp.sdc.be.model.UploadNodeFilterInfo; import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.dto.FilterConstraintDto; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.NodeFilterOperation; @@ -55,6 +51,7 @@ import org.openecomp.sdc.be.model.operations.api.IGroupOperation; import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation; +import org.openecomp.sdc.be.ui.mapper.FilterConstraintMapper; import org.openecomp.sdc.be.ui.model.UIConstraint; import org.openecomp.sdc.be.user.Role; import org.openecomp.sdc.common.log.wrappers.Logger; @@ -85,8 +82,8 @@ public class ComponentNodeFilterBusinessLogic extends BaseBusinessLogic { final boolean shouldLock, final ComponentTypeEnum componentTypeEnum) throws BusinessLogicException { final Component component = getComponent(componentId); - final Optional<ComponentInstance> componentInstance = getComponentInstance(componentInstanceId, component); - Optional<CINodeFilterDataDefinition> filterDataDefinition = getCiNodeFilterDataDefinition(componentInstance); + Optional<CINodeFilterDataDefinition> filterDataDefinition = + component.getComponentInstanceById(componentInstanceId).map(ComponentInstance::getNodeFilter); if (filterDataDefinition.isPresent()) { return filterDataDefinition; } @@ -123,8 +120,8 @@ public class ComponentNodeFilterBusinessLogic extends BaseBusinessLogic { public Optional<String> deleteNodeFilterIfExists(final String componentId, final String componentInstanceId, final boolean shouldLock, final ComponentTypeEnum componentTypeEnum) throws BusinessLogicException { final Component component = getComponent(componentId); - final Optional<CINodeFilterDataDefinition> nodeFilterDataDefinition = getCiNodeFilterDataDefinition(componentInstanceId, component); - if (!nodeFilterDataDefinition.isPresent()) { + final Optional<CINodeFilterDataDefinition> nodeFilterDataDefinition = getComponentInstanceNodeFilter(componentInstanceId, component); + if (nodeFilterDataDefinition.isEmpty()) { return Optional.ofNullable(componentInstanceId); } final Either<String, StorageOperationStatus> result; @@ -156,43 +153,29 @@ public class ComponentNodeFilterBusinessLogic extends BaseBusinessLogic { return Optional.ofNullable(result.left().value()); } - private String getComponentInstancePropertyType(Component component, String componentInstanceId, String propertyName) { - List<ComponentInstanceProperty> componentInstanceProperties = component.getComponentInstancesProperties().get(componentInstanceId); - if (!componentInstanceProperties.isEmpty()) { - for (ComponentInstanceProperty componentInstanceProperty : componentInstanceProperties) { - if (componentInstanceProperty.getName().equals(propertyName)) { - return componentInstanceProperty.getType(); - } - } - } - return null; - } - public Optional<CINodeFilterDataDefinition> addNodeFilter(final String componentId, final String componentInstanceId, - final NodeFilterConstraintAction action, final String propertyName, - final String constraint, final boolean shouldLock, + final FilterConstraintDto filterConstraint, final boolean shouldLock, final ComponentTypeEnum componentTypeEnum, - final NodeFilterConstraintType nodeFilterConstraintType, final String capabilityName) - throws BusinessLogicException { + final NodeFilterConstraintType nodeFilterConstraintType, + final String capabilityName) throws BusinessLogicException { final Component component = getComponent(componentId); - CINodeFilterDataDefinition nodeFilterDataDefinition = validateAndReturnNodeFilterDefinition(componentInstanceId, action, constraint, - component, nodeFilterConstraintType, capabilityName); + validateNodeFilter(component, componentInstanceId, filterConstraint); + CINodeFilterDataDefinition nodeFilterDataDefinition = getComponentInstanceNodeFilterOrThrow(componentInstanceId, component); boolean wasLocked = false; try { if (shouldLock) { lockComponent(component.getUniqueId(), component, "Add Node Filter on Component"); wasLocked = true; } - final RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition = new RequirementNodeFilterPropertyDataDefinition(); - requirementNodeFilterPropertyDataDefinition.setName(propertyName); - requirementNodeFilterPropertyDataDefinition.setConstraints(Collections.singletonList(constraint)); - requirementNodeFilterPropertyDataDefinition.setType(getComponentInstancePropertyType(component, componentInstanceId, propertyName)); - final Either<CINodeFilterDataDefinition, StorageOperationStatus> result = addNewNodeFilter(componentId, componentInstanceId, - nodeFilterConstraintType, nodeFilterDataDefinition, requirementNodeFilterPropertyDataDefinition, capabilityName); + final PropertyFilterDataDefinition filterPropertyDataDefinition = new PropertyFilterDataDefinition(); + filterPropertyDataDefinition.setName(filterConstraint.getPropertyName()); + filterPropertyDataDefinition.setConstraints(List.of(new FilterConstraintMapper().mapTo(filterConstraint))); + final Either<CINodeFilterDataDefinition, StorageOperationStatus> result = addNodeFilter(componentId, componentInstanceId, + nodeFilterConstraintType, nodeFilterDataDefinition, filterPropertyDataDefinition, capabilityName); if (result.isRight()) { - janusGraphDao.rollback(); - throw new BusinessLogicException(componentsUtils - .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(result.right().value()), component.getSystemName())); + throw new BusinessLogicException(componentsUtils.getResponseFormatByResource( + componentsUtils.convertFromStorageResponse(result.right().value()), component.getSystemName() + )); } else { nodeFilterDataDefinition = result.left().value(); } @@ -201,6 +184,9 @@ public class ComponentNodeFilterBusinessLogic extends BaseBusinessLogic { } catch (final Exception e) { janusGraphDao.rollback(); LOGGER.error(BUSINESS_PROCESS_ERROR, "Exception occurred during add component node filter property values: {}", e.getMessage(), e); + if (e instanceof BusinessLogicException) { + throw e; + } throw new BusinessLogicException(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); } finally { if (wasLocked) { @@ -210,14 +196,13 @@ public class ComponentNodeFilterBusinessLogic extends BaseBusinessLogic { return Optional.ofNullable(nodeFilterDataDefinition); } - public Optional<CINodeFilterDataDefinition> deleteNodeFilter(final String componentId, final String componentInstanceId, - final NodeFilterConstraintAction action, final String constraint, final int position, + public Optional<CINodeFilterDataDefinition> deleteNodeFilter(final String componentId, final String componentInstanceId, final int position, final boolean shouldLock, final ComponentTypeEnum componentTypeEnum, final NodeFilterConstraintType nodeFilterConstraintType) throws BusinessLogicException { + final Component component = getComponent(componentId); - CINodeFilterDataDefinition nodeFilterDataDefinition = validateAndReturnNodeFilterDefinition(componentInstanceId, action, constraint, - component, nodeFilterConstraintType, ""); + CINodeFilterDataDefinition nodeFilterDataDefinition = getComponentInstanceNodeFilterOrThrow(componentInstanceId, component); boolean wasLocked = false; try { if (shouldLock) { @@ -247,23 +232,23 @@ public class ComponentNodeFilterBusinessLogic extends BaseBusinessLogic { return Optional.ofNullable(nodeFilterDataDefinition); } - private Either<CINodeFilterDataDefinition, StorageOperationStatus> addNewNodeFilter(final String componentId, final String componentInstanceId, - final NodeFilterConstraintType nodeFilterConstraintType, - final CINodeFilterDataDefinition nodeFilterDataDefinition, - final RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition, - final String capabilityName) { + private Either<CINodeFilterDataDefinition, StorageOperationStatus> addNodeFilter(final String componentId, final String componentInstanceId, + final NodeFilterConstraintType nodeFilterConstraintType, + final CINodeFilterDataDefinition nodeFilterDataDefinition, + final PropertyFilterDataDefinition propertyFilterDataDefinition, + final String capabilityName) { if (NodeFilterConstraintType.PROPERTIES.equals(nodeFilterConstraintType)) { return nodeFilterOperation - .addNewProperty(componentId, componentInstanceId, nodeFilterDataDefinition, requirementNodeFilterPropertyDataDefinition); + .addPropertyFilter(componentId, componentInstanceId, nodeFilterDataDefinition, propertyFilterDataDefinition); } final RequirementNodeFilterCapabilityDataDefinition requirementNodeFilterCapabilityDataDefinition = new RequirementNodeFilterCapabilityDataDefinition(); requirementNodeFilterCapabilityDataDefinition.setName(capabilityName); - final ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> propertyDataDefinitionListDataDefinition = new ListDataDefinition<>(); + final ListDataDefinition<PropertyFilterDataDefinition> propertyDataDefinitionListDataDefinition = new ListDataDefinition<>(); propertyDataDefinitionListDataDefinition.getListToscaDataDefinition() - .addAll(Collections.singleton(requirementNodeFilterPropertyDataDefinition)); + .add(propertyFilterDataDefinition); requirementNodeFilterCapabilityDataDefinition.setProperties(propertyDataDefinitionListDataDefinition); return nodeFilterOperation - .addNewCapabilities(componentId, componentInstanceId, nodeFilterDataDefinition, requirementNodeFilterCapabilityDataDefinition); + .addCapabilities(componentId, componentInstanceId, nodeFilterDataDefinition, requirementNodeFilterCapabilityDataDefinition); } private void unlockComponent(final String componentUniqueId, final ComponentTypeEnum componentType) { @@ -280,64 +265,42 @@ public class ComponentNodeFilterBusinessLogic extends BaseBusinessLogic { return component.getComponentInstanceById(componentInstanceId); } - private Optional<CINodeFilterDataDefinition> getCiNodeFilterDataDefinition(final Optional<ComponentInstance> componentInstance) { - if (componentInstance.isPresent()) { - return Optional.ofNullable(componentInstance.get().getNodeFilter()); - } - return Optional.empty(); - } - - private Optional<CINodeFilterDataDefinition> getCiNodeFilterDataDefinition(final String componentInstanceId, final Component component) + private Optional<CINodeFilterDataDefinition> getComponentInstanceNodeFilter(final String componentInstanceId, final Component component) throws BusinessLogicException { final Either<Boolean, ResponseFormat> response = nodeFilterValidator.validateComponentInstanceExist(component, componentInstanceId); if (response.isRight()) { throw new BusinessLogicException( componentsUtils.getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND, response.right().value().getFormattedMessage())); } - final Optional<ComponentInstance> componentInstance = getComponentInstance(componentInstanceId, component); - if (componentInstance.isPresent()) { - return Optional.ofNullable(componentInstance.get().getNodeFilter()); - } - return Optional.empty(); + return getComponentInstance(componentInstanceId, component).map(ComponentInstance::getNodeFilter); } - private CINodeFilterDataDefinition validateAndReturnNodeFilterDefinition(final String componentInstanceId, - final NodeFilterConstraintAction action, final String constraint, - final Component component, - final NodeFilterConstraintType nodeFilterConstraintType, - final String capabilityName) - throws BusinessLogicException { - validateNodeFilter(component, componentInstanceId, action, constraint, nodeFilterConstraintType, capabilityName); - final Optional<CINodeFilterDataDefinition> cINodeFilterDataDefinition = getCiNodeFilterDataDefinition(componentInstanceId, component); - if (!cINodeFilterDataDefinition.isPresent()) { - throw new BusinessLogicException(componentsUtils.getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND)); - } - return cINodeFilterDataDefinition.get(); + private CINodeFilterDataDefinition getComponentInstanceNodeFilterOrThrow(final String componentInstanceId, + final Component component) throws BusinessLogicException { + return getComponentInstanceNodeFilter(componentInstanceId, component).orElseThrow( + () -> new BusinessLogicException(componentsUtils.getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND))); } - private void validateNodeFilter(final Component component, final String componentInstanceId, final NodeFilterConstraintAction action, - final String constraint, final NodeFilterConstraintType nodeFilterConstraintType, final String capabilityName) throws BusinessLogicException { - final Either<Boolean, ResponseFormat> response = nodeFilterValidator - .validateFilter(component, componentInstanceId, Collections.singletonList(constraint), action, nodeFilterConstraintType, capabilityName); + private void validateNodeFilter(final Component component, final String componentInstanceId, + final FilterConstraintDto constraint) throws BusinessLogicException { + final Either<Boolean, ResponseFormat> response = nodeFilterValidator.validateFilter(component, componentInstanceId, constraint); if (response.isRight()) { - throw new BusinessLogicException( - componentsUtils.getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND, response.right().value().getFormattedMessage())); + throw new BusinessLogicException(response.right().value()); } } public Optional<CINodeFilterDataDefinition> updateNodeFilter(final String componentId, final String componentInstanceId, final UIConstraint uiConstraint, final ComponentTypeEnum componentTypeEnum, - final NodeFilterConstraintType nodeFilterConstraintType, final int index) - throws BusinessLogicException { - final Optional<CINodeFilterDataDefinition> deleteActionResponse = deleteNodeFilter(componentId, componentInstanceId, - NodeFilterConstraintAction.DELETE, null, index, true, componentTypeEnum, nodeFilterConstraintType); - if (!deleteActionResponse.isPresent()) { + final NodeFilterConstraintType nodeFilterConstraintType, + final int index) throws BusinessLogicException { + final Optional<CINodeFilterDataDefinition> deleteActionResponse = + deleteNodeFilter(componentId, componentInstanceId, index, true, componentTypeEnum, nodeFilterConstraintType); + if (deleteActionResponse.isEmpty()) { throw new BusinessLogicException( componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR, "Failed to delete node filter capabilities")); } - return addNodeFilter(componentId.toLowerCase(), componentInstanceId, NodeFilterConstraintAction.ADD, uiConstraint.getServicePropertyName(), - new ConstraintConvertor().convert(uiConstraint), true, componentTypeEnum, nodeFilterConstraintType, - uiConstraint.getCapabilityName()); + return addNodeFilter(componentId.toLowerCase(), componentInstanceId, new FilterConstraintMapper().mapFrom(uiConstraint), true, + componentTypeEnum, nodeFilterConstraintType, uiConstraint.getCapabilityName()); } public StorageOperationStatus associateNodeFilterToComponentInstance(final String componentId, @@ -355,22 +318,12 @@ public class ComponentNodeFilterBusinessLogic extends BaseBusinessLogic { } //associate node filter properties to component instance - List<RequirementNodeFilterPropertyDataDefinition> properties = ciNodeFilterDataDefinition.getProperties() + List<PropertyFilterDataDefinition> properties = ciNodeFilterDataDefinition.getProperties() .getListToscaDataDefinition(); if (!properties.isEmpty()) { - final Component component; - try { - component = getComponent(componentId); - } catch (BusinessLogicException e) { - throw new ComponentException(e.getResponseFormat()); - } properties.forEach(property -> { - String propertyType = getComponentInstancePropertyType(component, componentInstanceId, property.getName()); - RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition = - getRequirementNodeFilterPropertyDataDefinition(property); - requirementNodeFilterPropertyDataDefinition.setType(propertyType); Either<CINodeFilterDataDefinition, StorageOperationStatus> nodeFilterProperty = nodeFilterOperation - .addNewProperty(componentId, componentInstanceId, nodeFilter.left().value(), requirementNodeFilterPropertyDataDefinition); + .addPropertyFilter(componentId, componentInstanceId, nodeFilter.left().value(), property); if (nodeFilterProperty.isRight()) { throw new ComponentException( componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(nodeFilterProperty.right().value()), @@ -389,7 +342,7 @@ public class ComponentNodeFilterBusinessLogic extends BaseBusinessLogic { requirementNodeFilterCapabilityDataDefinition.setName(capability.getName()); requirementNodeFilterCapabilityDataDefinition.setProperties(getProperties(capability.getProperties())); Either<CINodeFilterDataDefinition, StorageOperationStatus> nodeFilterCapability = nodeFilterOperation - .addNewCapabilities(componentId, componentInstanceId, nodeFilter.left().value(), + .addCapabilities(componentId, componentInstanceId, nodeFilter.left().value(), requirementNodeFilterCapabilityDataDefinition); if (nodeFilterCapability.isRight()) { throw new ComponentException( @@ -402,27 +355,10 @@ public class ComponentNodeFilterBusinessLogic extends BaseBusinessLogic { return StorageOperationStatus.OK; } - private List<String> getNodeFilterConstraints(String name, List<String> value) { - List<String> constraints = new ArrayList<>(); - constraints.add(name + ":\n " + value.get(0)); - return constraints; - } - - private ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> getProperties(ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> properties) { - ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> updatedProperties = new ListDataDefinition<>(); - properties.getListToscaDataDefinition().forEach(property -> { - RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition = getRequirementNodeFilterPropertyDataDefinition( - property); - updatedProperties.add(requirementNodeFilterPropertyDataDefinition); - }); + private ListDataDefinition<PropertyFilterDataDefinition> getProperties(ListDataDefinition<PropertyFilterDataDefinition> properties) { + ListDataDefinition<PropertyFilterDataDefinition> updatedProperties = new ListDataDefinition<>(); + properties.getListToscaDataDefinition().forEach(updatedProperties::add); return updatedProperties; } - private RequirementNodeFilterPropertyDataDefinition getRequirementNodeFilterPropertyDataDefinition( - RequirementNodeFilterPropertyDataDefinition property) { - RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition = new RequirementNodeFilterPropertyDataDefinition(); - requirementNodeFilterPropertyDataDefinition.setName(property.getName()); - requirementNodeFilterPropertyDataDefinition.setConstraints(getNodeFilterConstraints(property.getName(), property.getConstraints())); - return requirementNodeFilterPropertyDataDefinition; - } } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentSubstitutionFilterBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentSubstitutionFilterBusinessLogic.java index 74b353ec85..2fed0e2483 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentSubstitutionFilterBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentSubstitutionFilterBusinessLogic.java @@ -23,20 +23,19 @@ import static org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode.BUSINESS_P import fj.data.Either; import java.util.Arrays; -import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException; -import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction; import org.openecomp.sdc.be.components.validation.NodeFilterValidator; import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; -import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterPropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterPropertyDataDefinition; import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.model.Component; import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.dto.FilterConstraintDto; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.SubstitutionFilterOperation; @@ -46,6 +45,7 @@ import org.openecomp.sdc.be.model.operations.api.IGroupOperation; import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation; +import org.openecomp.sdc.be.ui.mapper.FilterConstraintMapper; import org.openecomp.sdc.be.user.Role; import org.openecomp.sdc.common.log.wrappers.Logger; import org.openecomp.sdc.exception.ResponseFormat; @@ -111,12 +111,11 @@ public class ComponentSubstitutionFilterBusinessLogic extends BaseBusinessLogic return substitutionFilterDataDefinition; } - public Optional<SubstitutionFilterDataDefinition> addSubstitutionFilter(final String componentId, final String propertyName, - final String constraint, final boolean shouldLock, + public Optional<SubstitutionFilterDataDefinition> addSubstitutionFilter(final String componentId, + final FilterConstraintDto filterConstraint, final boolean shouldLock, final ComponentTypeEnum componentTypeEnum) throws BusinessLogicException { final Component component = getComponent(componentId); - final Either<Boolean, ResponseFormat> response = nodeFilterValidator - .validateComponentFilter(component, Collections.singletonList(constraint), NodeFilterConstraintAction.ADD); + final Either<Boolean, ResponseFormat> response = nodeFilterValidator.validateSubstitutionFilter(component, filterConstraint); if (response.isRight()) { throw new BusinessLogicException( componentsUtils.getResponseFormat(ActionStatus.SUBSTITUTION_FILTER_NOT_FOUND, response.right().value().getFormattedMessage())); @@ -127,9 +126,9 @@ public class ComponentSubstitutionFilterBusinessLogic extends BaseBusinessLogic lockComponent(component.getUniqueId(), component, "Add Substitution Filter on Component"); wasLocked = true; } - final RequirementSubstitutionFilterPropertyDataDefinition newProperty = new RequirementSubstitutionFilterPropertyDataDefinition(); - newProperty.setName(propertyName); - newProperty.setConstraints(Collections.singletonList(constraint)); + final SubstitutionFilterPropertyDataDefinition newProperty = new SubstitutionFilterPropertyDataDefinition(); + newProperty.setName(filterConstraint.getPropertyName()); + newProperty.setConstraints(List.of(new FilterConstraintMapper().mapTo(filterConstraint))); final Either<SubstitutionFilterDataDefinition, StorageOperationStatus> resultEither = substitutionFilterOperation .addPropertyFilter(componentId, component.getSubstitutionFilter(), newProperty); if (resultEither.isRight()) { @@ -153,12 +152,11 @@ public class ComponentSubstitutionFilterBusinessLogic extends BaseBusinessLogic } } - public Optional<SubstitutionFilterDataDefinition> updateSubstitutionFilter(final String componentId, final List<String> constraints, - final boolean shouldLock, final ComponentTypeEnum componentTypeEnum) - throws BusinessLogicException { + public Optional<SubstitutionFilterDataDefinition> updateSubstitutionFilter(final String componentId, final List<FilterConstraintDto> constraints, + final boolean shouldLock, + final ComponentTypeEnum componentTypeEnum) throws BusinessLogicException { final Component component = getComponent(componentId); - final Either<Boolean, ResponseFormat> response = nodeFilterValidator - .validateComponentFilter(component, constraints, NodeFilterConstraintAction.UPDATE); + final Either<Boolean, ResponseFormat> response = nodeFilterValidator.validateSubstitutionFilter(component, constraints); if (response.isRight()) { throw new BusinessLogicException( componentsUtils.getResponseFormat(ActionStatus.SUBSTITUTION_FILTER_NOT_FOUND, response.right().value().getFormattedMessage())); @@ -173,10 +171,10 @@ public class ComponentSubstitutionFilterBusinessLogic extends BaseBusinessLogic lockComponent(component.getUniqueId(), component, "Update Substitution Filter on Component"); wasLocked = true; } - final List<RequirementSubstitutionFilterPropertyDataDefinition> properties = constraints.stream() - .map(this::getRequirementSubstitutionFilterPropertyDataDefinition).collect(Collectors.toList()); + final List<SubstitutionFilterPropertyDataDefinition> properties = constraints.stream() + .map(this::buildSubstitutionFilterPropertyDataDefinition).collect(Collectors.toList()); final Either<SubstitutionFilterDataDefinition, StorageOperationStatus> result = substitutionFilterOperation - .updateProperties(componentId, substitutionFilterDataDefinition, properties); + .updatePropertyFilters(componentId, substitutionFilterDataDefinition, properties); if (result.isRight()) { janusGraphDao.rollback(); throw new BusinessLogicException(componentsUtils @@ -199,6 +197,51 @@ public class ComponentSubstitutionFilterBusinessLogic extends BaseBusinessLogic return Optional.ofNullable(substitutionFilterDataDefinition); } + public Optional<SubstitutionFilterDataDefinition> updateSubstitutionFilter(final String componentId, final FilterConstraintDto filterConstraint, + final int index, + final boolean shouldLock) throws BusinessLogicException { + final Component component = getComponent(componentId); + final Either<Boolean, ResponseFormat> validationResponse = nodeFilterValidator.validateSubstitutionFilter(component, filterConstraint); + if (validationResponse.isRight()) { + throw new BusinessLogicException(validationResponse.right().value()); + } + final SubstitutionFilterDataDefinition substitutionFilterDataDefinition = component.getSubstitutionFilter(); + if (substitutionFilterDataDefinition == null) { + throw new BusinessLogicException(componentsUtils.getResponseFormat(SUBSTITUTION_FILTER_NOT_FOUND, component.getName())); + } + boolean wasLocked = false; + try { + if (shouldLock) { + lockComponent(component.getUniqueId(), component, "Update Substitution Filter on Component"); + wasLocked = true; + } + final SubstitutionFilterPropertyDataDefinition substitutionFilterProperty = + buildSubstitutionFilterPropertyDataDefinition(filterConstraint); + final Either<SubstitutionFilterDataDefinition, StorageOperationStatus> result = + substitutionFilterOperation.updatePropertyFilter(componentId, substitutionFilterDataDefinition, substitutionFilterProperty, index); + if (result.isRight()) { + janusGraphDao.rollback(); + throw new BusinessLogicException( + componentsUtils.getResponseFormatByResource( + componentsUtils.convertFromStorageResponse(result.right().value()), component.getSystemName() + ) + ); + } + janusGraphDao.commit(); + LOGGER.debug("Substitution filter successfully updated in component {} . ", component.getSystemName()); + return Optional.ofNullable(result.left().value()); + } catch (final Exception e) { + janusGraphDao.rollback(); + LOGGER.error(BUSINESS_PROCESS_ERROR, this.getClass().getName(), + "Exception occurred during update component substitution filter property values: {}", e); + throw e; + } finally { + if (wasLocked) { + unlockComponent(component.getUniqueId(), component.getComponentType()); + } + } + } + public Optional<SubstitutionFilterDataDefinition> deleteSubstitutionFilter(final String componentId, final int position, final boolean shouldLock, final ComponentTypeEnum componentTypeEnum) throws BusinessLogicException { @@ -244,20 +287,21 @@ public class ComponentSubstitutionFilterBusinessLogic extends BaseBusinessLogic return user; } - private RequirementSubstitutionFilterPropertyDataDefinition getRequirementSubstitutionFilterPropertyDataDefinition(final String constraint) { - final RequirementSubstitutionFilterPropertyDataDefinition requirementSubstitutionFilterPropertyDataDefinition = new RequirementSubstitutionFilterPropertyDataDefinition(); - requirementSubstitutionFilterPropertyDataDefinition.setConstraints(Arrays.asList(constraint)); - return requirementSubstitutionFilterPropertyDataDefinition; + private SubstitutionFilterPropertyDataDefinition buildSubstitutionFilterPropertyDataDefinition(final FilterConstraintDto filterConstraint) { + final var substitutionFilterProperty = new SubstitutionFilterPropertyDataDefinition(); + substitutionFilterProperty.setName(filterConstraint.getPropertyName()); + substitutionFilterProperty.setConstraints(List.of(new FilterConstraintMapper().mapTo(filterConstraint))); + return substitutionFilterProperty; } public void addSubstitutionFilterInGraph(String componentId, - ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> substitutionFilterProperties) + ListDataDefinition<SubstitutionFilterPropertyDataDefinition> substitutionFilterProperties) throws BusinessLogicException { Either<SubstitutionFilterDataDefinition, StorageOperationStatus> updateSubstitutionFilter; Optional<SubstitutionFilterDataDefinition> substitutionFilter = createSubstitutionFilterIfNotExist(componentId, true, ComponentTypeEnum.SERVICE); if (substitutionFilter.isPresent()) { - for (RequirementSubstitutionFilterPropertyDataDefinition filter : substitutionFilterProperties.getListToscaDataDefinition()) { + for (SubstitutionFilterPropertyDataDefinition filter : substitutionFilterProperties.getListToscaDataDefinition()) { updateSubstitutionFilter = substitutionFilterOperation.addPropertyFilter(componentId, substitutionFilter.get(), filter); if (updateSubstitutionFilter.isRight()) { throw new BusinessLogicException(componentsUtils diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ImportUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ImportUtils.java index b4f6ee3950..8ad86b3510 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ImportUtils.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ImportUtils.java @@ -63,7 +63,7 @@ import org.openecomp.sdc.be.model.heat.HeatParameterType; import org.openecomp.sdc.be.model.operations.impl.AnnotationTypeOperations; import org.openecomp.sdc.be.model.operations.impl.PropertyOperation.PropertyConstraintDeserialiser; import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; -import org.openecomp.sdc.be.model.tosca.constraints.ConstraintType; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; import org.openecomp.sdc.be.model.tosca.constraints.ValidValuesConstraint; import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException; import org.openecomp.sdc.be.utils.TypeUtils; diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/NodeFilterUploadCreator.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/NodeFilterUploadCreator.java index 9d72eeca87..f34091de0f 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/NodeFilterUploadCreator.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/NodeFilterUploadCreator.java @@ -49,22 +49,26 @@ public class NodeFilterUploadCreator { return uploadNodeFilterInfo; } - private List<UploadNodeFilterPropertyInfo> createNodeFilterProperties(Object o) { - if (!(o instanceof List)) { + private List<UploadNodeFilterPropertyInfo> createNodeFilterProperties(Object propertyNodeFilterYamlObject) { + if (!(propertyNodeFilterYamlObject instanceof List)) { return null; } List<UploadNodeFilterPropertyInfo> retVal = new ArrayList<>(); - List<Map<String, Object>> propertiesList = (List<Map<String, Object>>) o; + List<Map<String, Object>> propertiesList = (List<Map<String, Object>>) propertyNodeFilterYamlObject; for (Map<String, Object> map : propertiesList) { final Map.Entry<String, Object> entry = map.entrySet().iterator().next(); - final Object value = entry.getValue(); - if (value instanceof Map) { - List<String> valueList = new ArrayList<>(); - valueList.add(valueToProperty(entry.getValue())); - retVal.add(new UploadNodeFilterPropertyInfo(entry.getKey(), valueList)); - } else if (value instanceof List) { - List<String> propertiesVals = (List<String>) ((List) value).stream().map(this::valueToProperty).collect(Collectors.toList()); - retVal.add(new UploadNodeFilterPropertyInfo(entry.getKey(), propertiesVals)); + final Object propertyConstraintClauses = entry.getValue(); + if (propertyConstraintClauses instanceof Map) { + final List<String> propertyFilterConstraintList = new ArrayList<>(); + propertyFilterConstraintList.add(valueToProperty(map)); + retVal.add(new UploadNodeFilterPropertyInfo(entry.getKey(), propertyFilterConstraintList)); + } else if (propertyConstraintClauses instanceof List) { + final List<String> propertyFilterConstraintList = ((List<Object>) propertyConstraintClauses).stream() + .map(propertyConstraintClause -> Map.of(entry.getKey(), propertyConstraintClause)) + .map(this::valueToProperty) + .collect(Collectors.toList()); + + retVal.add(new UploadNodeFilterPropertyInfo(entry.getKey(), propertyFilterConstraintList)); } } return retVal; diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogic.java index ab43b4329e..8c46285240 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogic.java @@ -77,7 +77,7 @@ import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition; import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition; import org.openecomp.sdc.be.datatypes.elements.PolicyDataDefinition; import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; -import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterPropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterPropertyDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; @@ -448,7 +448,7 @@ public class ServiceImportBusinessLogic { Map<String, InputDefinition> inputs = parsedToscaYamlInfo.getInputs(); service = serviceImportParseLogic.createInputsOnService(service, inputs); log.trace("************* Finished to add inputs from yaml {}", yamlName); - ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> substitutionFilterProperties = parsedToscaYamlInfo.getSubstitutionFilterProperties(); + ListDataDefinition<SubstitutionFilterPropertyDataDefinition> substitutionFilterProperties = parsedToscaYamlInfo.getSubstitutionFilterProperties(); service = serviceImportParseLogic.createSubstitutionFilterOnService(service, substitutionFilterProperties); log.trace("************* Added Substitution filter from interface yaml {}", yamlName); Map<String, UploadComponentInstanceInfo> uploadComponentInstanceInfoMap = parsedToscaYamlInfo.getInstances(); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportParseLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportParseLogic.java index 8cc5bd6fcb..b97645cc35 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportParseLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportParseLogic.java @@ -40,7 +40,7 @@ import org.openecomp.sdc.be.datatypes.elements.ListRequirementDataDefinition; import org.openecomp.sdc.be.datatypes.elements.MapInterfaceDataDefinition; import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; import org.openecomp.sdc.be.datatypes.elements.RequirementDataDefinition; -import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterPropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterPropertyDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.datatypes.enums.CreatedFrom; import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; @@ -1381,7 +1381,7 @@ public class ServiceImportParseLogic { } public Service createSubstitutionFilterOnService(Service service, - ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> substitutionFilterProperties) + ListDataDefinition<SubstitutionFilterPropertyDataDefinition> substitutionFilterProperties) throws BusinessLogicException { if (substitutionFilterProperties == null || substitutionFilterProperties.isEmpty()) { return service; diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/exceptions/FilterConstraintExceptionSupplier.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/exceptions/FilterConstraintExceptionSupplier.java new file mode 100644 index 0000000000..9f184aa2c2 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/exceptions/FilterConstraintExceptionSupplier.java @@ -0,0 +1,40 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.openecomp.sdc.be.components.impl.exceptions; + +import java.util.function.Supplier; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.openecomp.sdc.be.dao.api.ActionStatus; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class FilterConstraintExceptionSupplier { + + public static Supplier<ByActionStatusComponentException> filterConstraintNotProvided() { + return () -> new ByActionStatusComponentException(ActionStatus.FILTER_CONSTRAINT_MISSING); + } + + public static Supplier<ByActionStatusComponentException> missingField(final String fieldName) { + return () -> new ByActionStatusComponentException(ActionStatus.FILTER_CONSTRAINT_MISSING_FIELD, fieldName); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/utils/CINodeFilterUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/utils/CINodeFilterUtils.java index a7dd5afc10..5ac9bcd2de 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/utils/CINodeFilterUtils.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/utils/CINodeFilterUtils.java @@ -15,37 +15,39 @@ */ package org.openecomp.sdc.be.components.impl.utils; +import java.util.Collection; import java.util.List; import java.util.Map; import java.util.stream.Collectors; +import org.apache.commons.collections4.CollectionUtils; import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyFilterDataDefinition; import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterCapabilityDataDefinition; -import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition; import org.openecomp.sdc.be.model.UploadNodeFilterCapabilitiesInfo; import org.openecomp.sdc.be.model.UploadNodeFilterInfo; import org.openecomp.sdc.be.model.UploadNodeFilterPropertyInfo; -import org.openecomp.sdc.common.log.wrappers.Logger; +import org.openecomp.sdc.be.utils.PropertyFilterConstraintDataDefinitionHelper; public class CINodeFilterUtils { - Logger log = Logger.getLogger(CINodeFilterUtils.class); - - public CINodeFilterDataDefinition getNodeFilterDataDefinition(UploadNodeFilterInfo uploadNodeFilterInfo, String uniqueId) { - CINodeFilterDataDefinition nodeFilterDataDefinition = new CINodeFilterDataDefinition(); + public CINodeFilterDataDefinition getNodeFilterDataDefinition(final UploadNodeFilterInfo uploadNodeFilterInfo, final String uniqueId) { + final var nodeFilterDataDefinition = new CINodeFilterDataDefinition(); nodeFilterDataDefinition.setName(uploadNodeFilterInfo.getName()); - List<RequirementNodeFilterPropertyDataDefinition> collect = uploadNodeFilterInfo.getProperties().stream().map(this::buildProperty) + final List<PropertyFilterDataDefinition> propertyFilterList = uploadNodeFilterInfo.getProperties().stream() + .map(this::buildOnePropertyFilterForEachConstraint) + .flatMap(Collection::stream) .collect(Collectors.toList()); - ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> listDataDefinition = new ListDataDefinition<>(); - listDataDefinition.getListToscaDataDefinition().addAll(collect); + final ListDataDefinition<PropertyFilterDataDefinition> listDataDefinition = new ListDataDefinition<>(); + listDataDefinition.getListToscaDataDefinition().addAll(propertyFilterList); nodeFilterDataDefinition.setProperties(listDataDefinition); - nodeFilterDataDefinition.setCapabilities(converCapabilties(uploadNodeFilterInfo.getCapabilities())); + nodeFilterDataDefinition.setCapabilities(convertCapabilities(uploadNodeFilterInfo.getCapabilities())); nodeFilterDataDefinition.setID(uniqueId); nodeFilterDataDefinition.setTosca_id(uploadNodeFilterInfo.getTosca_id()); return nodeFilterDataDefinition; } - private ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> converCapabilties( + private ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> convertCapabilities( Map<String, UploadNodeFilterCapabilitiesInfo> capabilities) { ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> listDataDefinition = new ListDataDefinition<>(); for (UploadNodeFilterCapabilitiesInfo capability : capabilities.values()) { @@ -58,19 +60,43 @@ public class CINodeFilterUtils { private RequirementNodeFilterCapabilityDataDefinition convertCapability(UploadNodeFilterCapabilitiesInfo capability) { RequirementNodeFilterCapabilityDataDefinition retVal = new RequirementNodeFilterCapabilityDataDefinition(); retVal.setName(capability.getName()); - List<RequirementNodeFilterPropertyDataDefinition> props = capability.getProperties().stream().map(this::buildProperty) + List<PropertyFilterDataDefinition> props = capability.getProperties().stream().map(this::buildProperty) .collect(Collectors.toList()); - ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> propsList = new ListDataDefinition<>(); + ListDataDefinition<PropertyFilterDataDefinition> propsList = new ListDataDefinition<>(); propsList.getListToscaDataDefinition().addAll(props); retVal.setProperties(propsList); return retVal; } - private RequirementNodeFilterPropertyDataDefinition buildProperty(UploadNodeFilterPropertyInfo uploadNodeFilterPropertyInfo) { - RequirementNodeFilterPropertyDataDefinition retVal = new RequirementNodeFilterPropertyDataDefinition(); - retVal.setName(uploadNodeFilterPropertyInfo.getName()); - List<String> propertyConstraints = uploadNodeFilterPropertyInfo.getValues(); - retVal.setConstraints(propertyConstraints); - return retVal; + private PropertyFilterDataDefinition buildProperty(final UploadNodeFilterPropertyInfo uploadNodeFilterPropertyInfo) { + final var propertyFilter = new PropertyFilterDataDefinition(); + propertyFilter.setName(uploadNodeFilterPropertyInfo.getName()); + final List<String> propertyConstraints = uploadNodeFilterPropertyInfo.getValues(); + if (CollectionUtils.isNotEmpty(propertyConstraints)) { + propertyFilter.setConstraints( + propertyConstraints.stream() + .map(PropertyFilterConstraintDataDefinitionHelper::convertLegacyConstraint) + .collect(Collectors.toList()) + ); + } + return propertyFilter; + } + + private List<PropertyFilterDataDefinition> buildOnePropertyFilterForEachConstraint(final UploadNodeFilterPropertyInfo uploadNodeFilterProperty) { + final List<String> propertyConstraints = uploadNodeFilterProperty.getValues(); + if (CollectionUtils.isNotEmpty(propertyConstraints)) { + return propertyConstraints.stream() + .map(PropertyFilterConstraintDataDefinitionHelper::convertLegacyConstraint) + .map(propertyFilterConstraint -> { + final var propertyFilter = new PropertyFilterDataDefinition(); + propertyFilter.setName(uploadNodeFilterProperty.getName()); + propertyFilter.setConstraints(List.of(propertyFilterConstraint)); + return propertyFilter; + }).collect(Collectors.toList()); + } else { + final var propertyFilter = new PropertyFilterDataDefinition(); + propertyFilter.setName(uploadNodeFilterProperty.getName()); + return List.of(propertyFilter); + } } } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/PropertyConstraintsUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/PropertyConstraintsUtils.java index bd2187616c..4bd953fd3d 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/PropertyConstraintsUtils.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/PropertyConstraintsUtils.java @@ -28,7 +28,7 @@ import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentEx import org.openecomp.sdc.be.model.PropertyConstraint; import org.openecomp.sdc.be.model.PropertyDefinition; import org.openecomp.sdc.be.model.Resource; -import org.openecomp.sdc.be.model.tosca.constraints.ConstraintType; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; import org.openecomp.sdc.be.model.tosca.constraints.exception.PropertyConstraintException; /** diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/FilterConstraintValidatorImpl.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/FilterConstraintValidatorImpl.java new file mode 100644 index 0000000000..862b839326 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/FilterConstraintValidatorImpl.java @@ -0,0 +1,64 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.openecomp.sdc.be.components.validation; + +import org.apache.commons.lang3.StringUtils; +import org.openecomp.sdc.be.components.impl.exceptions.FilterConstraintExceptionSupplier; +import org.openecomp.sdc.be.datatypes.enums.PropertyFilterTargetType; +import org.openecomp.sdc.be.model.dto.FilterConstraintDto; +import org.openecomp.sdc.be.model.validation.FilterConstraintValidator; + +@org.springframework.stereotype.Component +public class FilterConstraintValidatorImpl implements FilterConstraintValidator { + + @Override + public void validate(final FilterConstraintDto filterConstraint) { + if (filterConstraint == null) { + throw FilterConstraintExceptionSupplier.filterConstraintNotProvided().get(); + } + + if (StringUtils.isBlank(filterConstraint.getPropertyName())) { + throw FilterConstraintExceptionSupplier.missingField("propertyName").get(); + } + + if (filterConstraint.getValueType() == null) { + throw FilterConstraintExceptionSupplier.missingField("valueType").get(); + } + + if (filterConstraint.getTargetType() == null) { + throw FilterConstraintExceptionSupplier.missingField("targetType").get(); + } + + if (filterConstraint.getTargetType() == PropertyFilterTargetType.CAPABILITY && StringUtils.isBlank(filterConstraint.getCapabilityName())) { + throw FilterConstraintExceptionSupplier.missingField("capabilityName").get(); + } + + if (filterConstraint.getValue() == null) { + throw FilterConstraintExceptionSupplier.missingField("value").get(); + } + + if (filterConstraint.getOperator() == null) { + throw FilterConstraintExceptionSupplier.missingField("operator").get(); + } + + } +} 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 e62893a148..12b58ded4a 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 @@ -19,33 +19,33 @@ */ package org.openecomp.sdc.be.components.validation; -import com.google.common.collect.ImmutableSet; +import com.google.gson.Gson; import fj.data.Either; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; -import java.util.Objects; +import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; -import org.openecomp.sdc.be.components.impl.ResponseFormatManager; -import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction; import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.datamodel.utils.ConstraintConvertor; -import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition; -import org.openecomp.sdc.be.datatypes.enums.NodeFilterConstraintType; +import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; +import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.PropertySource; import org.openecomp.sdc.be.impl.ComponentsUtils; import org.openecomp.sdc.be.model.CapabilityDefinition; import org.openecomp.sdc.be.model.Component; 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.InputDefinition; import org.openecomp.sdc.be.model.PropertyDefinition; -import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade; +import org.openecomp.sdc.be.model.ToscaPropertyData; +import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache; +import org.openecomp.sdc.be.model.dto.FilterConstraintDto; import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; -import org.openecomp.sdc.be.ui.model.UIConstraint; +import org.openecomp.sdc.be.model.tosca.validators.DataTypeValidatorConverter; +import org.openecomp.sdc.be.model.validation.FilterConstraintValidator; import org.openecomp.sdc.exception.ResponseFormat; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -54,128 +54,192 @@ import org.springframework.beans.factory.annotation.Autowired; @org.springframework.stereotype.Component("NodeFilterValidator") public class NodeFilterValidator { + private static final Logger LOGGER = LoggerFactory.getLogger(NodeFilterValidator.class); private static final String SOURCE = "Source"; - public static final Set<String> comparableTypes = ImmutableSet + private static final String TARGET = "Target"; + private static final String INPUT_NOT_FOUND_LOG = "Input '{}' not found in parent component '{}', unique id '{}'"; + private static final Set<String> TYPES_WITH_SCHEMA = Set.of(ToscaPropertyType.MAP.getType(), ToscaPropertyType.LIST.getType()); + private static final Set<String> COMPARABLE_TYPES = Set .of(ToscaPropertyType.STRING.getType(), ToscaPropertyType.INTEGER.getType(), ToscaPropertyType.FLOAT.getType()); - public static final Set<String> schemableTypes = ImmutableSet.of(ToscaPropertyType.MAP.getType(), ToscaPropertyType.LIST.getType()); - public static final Set<String> comparableConstraintsOperators = ImmutableSet - .of(ConstraintConvertor.GREATER_THAN_OPERATOR, ConstraintConvertor.LESS_THAN_OPERATOR); - protected final ToscaOperationFacade toscaOperationFacade; - protected final ComponentsUtils componentsUtils; - private static final Logger LOGGER = LoggerFactory.getLogger(NodeFilterValidator.class); + private final ComponentsUtils componentsUtils; + private final ApplicationDataTypeCache applicationDataTypeCache; + private final FilterConstraintValidator filterConstraintValidator; @Autowired - public NodeFilterValidator(final ToscaOperationFacade toscaOperationFacade, final ComponentsUtils componentsUtils) { - this.toscaOperationFacade = toscaOperationFacade; + public NodeFilterValidator(final ComponentsUtils componentsUtils, final ApplicationDataTypeCache applicationDataTypeCache, + final FilterConstraintValidator filterConstraintValidator) { this.componentsUtils = componentsUtils; + this.applicationDataTypeCache = applicationDataTypeCache; + this.filterConstraintValidator = filterConstraintValidator; } public Either<Boolean, ResponseFormat> validateComponentInstanceExist(final Component component, final String componentInstanceId) { if (component == null || StringUtils.isEmpty(componentInstanceId)) { - LOGGER.error("Input data cannot be empty"); - return getErrorResponse(ActionStatus.FILTER_NOT_FOUND); + LOGGER.error("Expecting a component and a component instance id, given was '{}' and '{}'", component, componentInstanceId); + final String componentName = component == null ? "?" : component.getName(); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND, componentName, componentInstanceId)); } if (CollectionUtils.isEmpty(component.getComponentInstances()) || component.getComponentInstances().stream() .noneMatch(ci -> ci.getUniqueId().equals(componentInstanceId))) { - LOGGER.error("Component Instance list is empty"); - return getErrorResponse(ActionStatus.FILTER_NOT_FOUND); + LOGGER.error("Component '{}' node instance list is empty or component instance '{}' not found", + component.getUniqueId(), componentInstanceId); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND, + component.getName(), componentInstanceId)); } return Either.left(Boolean.TRUE); } - private Either<Boolean, ResponseFormat> getErrorResponse(ActionStatus actionStatus, String... variables) { - ResponseFormat errorResponse = ResponseFormatManager.getInstance().getResponseFormat(actionStatus, variables); - return Either.right(errorResponse); - } - public Either<Boolean, ResponseFormat> validateFilter(final Component parentComponent, final String componentInstanceId, - final List<String> uiConstraints, final NodeFilterConstraintAction action, - final NodeFilterConstraintType nodeFilterConstraintType, - final String capabilityName) { - try { - if (NodeFilterConstraintAction.ADD == action || NodeFilterConstraintAction.UPDATE == action) { - for (final String uiConstraint : uiConstraints) { - final UIConstraint constraint = new ConstraintConvertor().convert(uiConstraint); - if (ConstraintConvertor.PROPERTY_CONSTRAINT.equals(constraint.getSourceType())) { - final Either<Boolean, ResponseFormat> booleanResponseFormatEither = validatePropertyConstraint(parentComponent, - componentInstanceId, constraint, capabilityName); - if (booleanResponseFormatEither.isRight()) { - return booleanResponseFormatEither; - } - } - else if (ConstraintConvertor.SERVICE_INPUT_CONSTRAINT.equals(constraint.getSourceType())) { - final Either<Boolean, ResponseFormat> booleanResponseFormatEither = validateInputConstraint(parentComponent, - componentInstanceId, constraint); - if (booleanResponseFormatEither.isRight()) { - return booleanResponseFormatEither; - } - } - else if (ConstraintConvertor.STATIC_CONSTRAINT.equals(constraint.getSourceType())) { - Either<Boolean, ResponseFormat> booleanResponseFormatEither; - if (NodeFilterConstraintType.PROPERTIES.equals(nodeFilterConstraintType)) { - booleanResponseFormatEither = isComponentPropertyFilterValid(parentComponent, componentInstanceId, constraint); - } else { - booleanResponseFormatEither = isComponentCapabilityPropertyFilterValid(parentComponent, componentInstanceId, constraint); - } - if (booleanResponseFormatEither.isRight()) { - return booleanResponseFormatEither; - } - } - } + final List<FilterConstraintDto> filterConstraint) { + if (CollectionUtils.isEmpty(filterConstraint)) { + return Either.left(true); + } + for (final FilterConstraintDto filterConstraintDto : filterConstraint) { + final Either<Boolean, ResponseFormat> validationEither = + validateFilter(parentComponent, componentInstanceId, filterConstraintDto); + if (validationEither.isRight()) { + return validationEither; } - } catch (final Exception e) { - LOGGER.debug("Provided constraint" + uiConstraints, e); - return Either.right(componentsUtils.getResponseFormat(ActionStatus.CONSTRAINT_FORMAT_INCORRECT)); } return Either.left(true); } - - private Either<Boolean, ResponseFormat> isComponentCapabilityPropertyFilterValid(final Component parentComponent, - final String componentInstanceId, - final UIConstraint uiConstraint) { - return validateStaticValueAndOperatorOfCapabilityProperties(parentComponent, componentInstanceId, uiConstraint); + public Either<Boolean, ResponseFormat> validateFilter(final Component parentComponent, final String componentInstanceId, + final FilterConstraintDto filterConstraint) { + validateFilterConstraint(filterConstraint); + switch (filterConstraint.getValueType()) { + case STATIC: + if (filterConstraint.isCapabilityPropertyFilter()) { + return validateStaticValueAndOperatorOfCapabilityProperties(parentComponent, componentInstanceId, filterConstraint); + } else { + return validateStaticValueAndOperator(parentComponent, componentInstanceId, filterConstraint); + } + case GET_PROPERTY: + return validatePropertyConstraint(parentComponent, componentInstanceId, filterConstraint, filterConstraint.getCapabilityName()); + case GET_INPUT: + return validateInputConstraint(parentComponent, componentInstanceId, filterConstraint); + default: + return Either.left(true); + } } - private Either<Boolean, ResponseFormat> isComponentPropertyFilterValid(Component parentComponent, String componentInstanceId, - UIConstraint constraint) { - return validateStaticValueAndOperator(parentComponent, componentInstanceId, constraint); + private void validateFilterConstraint(final FilterConstraintDto filterConstraint) { + filterConstraintValidator.validate(filterConstraint); } private Either<Boolean, ResponseFormat> validatePropertyConstraint(final Component parentComponent, final String componentInstanceId, - final UIConstraint uiConstraint, final String capabilityName) { + final FilterConstraintDto filterConstraint, final String capabilityName) { String source = SOURCE; - final Optional<ComponentInstance> optionalComponentInstance; - final List<PropertyDefinition> propertyDefinitions = parentComponent.getProperties(); - final var SELF = "SELF"; - List<? extends PropertyDefinition> sourcePropertyDefinition = - SELF.equalsIgnoreCase(uiConstraint.getSourceName()) && propertyDefinitions != null ? propertyDefinitions - : Collections.emptyList(); - if (sourcePropertyDefinition.isEmpty() && !SELF.equalsIgnoreCase(uiConstraint.getSourceName())) { - optionalComponentInstance = parentComponent.getComponentInstances().stream() - .filter(componentInstance -> uiConstraint.getSourceName().equals(componentInstance.getName())).findFirst(); - if (optionalComponentInstance.isPresent()) { - final List<ComponentInstanceProperty> componentInstanceProperties = parentComponent.getComponentInstancesProperties() - .get(optionalComponentInstance.get().getUniqueId()); - sourcePropertyDefinition = componentInstanceProperties == null ? new ArrayList<>() : componentInstanceProperties; - } + final ToscaGetFunctionDataDefinition toscaGetFunction = filterConstraint.getAsToscaGetFunction().orElse(null); + if (toscaGetFunction == null || !(filterConstraint.getValue() instanceof ToscaGetFunctionDataDefinition)) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.TOSCA_FUNCTION_EXPECTED_ERROR)); } - if (CollectionUtils.isNotEmpty(sourcePropertyDefinition)) { - final Optional<? extends PropertyDefinition> sourceSelectedProperty = sourcePropertyDefinition.stream() - .filter(property -> uiConstraint.getValue().equals(property.getName())).findFirst(); - Optional<? extends PropertyDefinition> targetComponentInstanceProperty = getProperty(parentComponent, componentInstanceId, capabilityName, uiConstraint.getServicePropertyName()); - - source = !targetComponentInstanceProperty.isPresent() ? "Target" : SOURCE; - if (sourceSelectedProperty.isPresent() && targetComponentInstanceProperty.isPresent()) { - return validatePropertyData(uiConstraint, sourceSelectedProperty, targetComponentInstanceProperty); + final Optional<? extends ToscaPropertyData> sourceSelectedProperty = findPropertyFromGetFunction(parentComponent, toscaGetFunction); + if (sourceSelectedProperty.isPresent()) { + Optional<? extends PropertyDefinition> targetComponentInstanceProperty = + getInstanceProperties(parentComponent, componentInstanceId, capabilityName, filterConstraint.getPropertyName()); + + source = targetComponentInstanceProperty.isEmpty() ? TARGET : SOURCE; + if (targetComponentInstanceProperty.isPresent()) { + final ResponseFormat responseFormat = validatePropertyData(sourceSelectedProperty.get(), targetComponentInstanceProperty.get()); + if (responseFormat != null) { + return Either.right(responseFormat); + } + return Either.left(true); } } - final String missingProperty = source.equals(SOURCE) ? uiConstraint.getValue().toString() : uiConstraint.getServicePropertyName(); - return Either.right(componentsUtils.getResponseFormat(ActionStatus.MAPPED_PROPERTY_NOT_FOUND, source, missingProperty)); + final String missingProperty = SOURCE.equals(source) ? filterConstraint.getValue().toString() : filterConstraint.getPropertyName(); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.FILTER_PROPERTY_NOT_FOUND, source, missingProperty)); + } + + private Optional<? extends ToscaPropertyData> findPropertyFromGetFunction(final Component parentComponent, + final ToscaGetFunctionDataDefinition toscaGetFunction) { + List<? extends ToscaPropertyData> sourcePropertyDefinitions; + if (PropertySource.SELF == toscaGetFunction.getPropertySource()) { + sourcePropertyDefinitions = getSelfPropertyFromGetFunction(parentComponent, toscaGetFunction); + } else { + sourcePropertyDefinitions = getInstancePropertiesBasedOnGetFunctionSource(parentComponent, toscaGetFunction); + } + final List<String> propertyPath = toscaGetFunction.getPropertyPathFromSource(); + final Optional<? extends ToscaPropertyData> sourceProperty = sourcePropertyDefinitions.stream() + .filter(propertyDefinition -> propertyDefinition.getName().equals(propertyPath.get(0))).findFirst(); + if (sourceProperty.isEmpty() || propertyPath.size() == 1) { + return sourceProperty; + } + final Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> allDataTypesEither = + applicationDataTypeCache.getAll(parentComponent.getModel()); + if (allDataTypesEither.isRight()) { + return Optional.empty(); + } + return findSubProperty(propertyPath.subList(1, propertyPath.size()), sourceProperty.get().getType(), allDataTypesEither.left().value()); + } + + private List<? extends ToscaPropertyData> getInstancePropertiesBasedOnGetFunctionSource(final Component parentComponent, + final ToscaGetFunctionDataDefinition toscaGetFunction) { + final ComponentInstance componentInstance = parentComponent.getComponentInstances().stream() + .filter(componentInstance1 -> componentInstance1.getName().equals(toscaGetFunction.getSourceName())) + .findFirst() + .orElse(null); + if (componentInstance == null) { + return List.of(); + } + final List<? extends ToscaPropertyData> instanceProperties; + switch (toscaGetFunction.getFunctionType()) { + case GET_PROPERTY: + instanceProperties = parentComponent.getComponentInstancesProperties().get(componentInstance.getUniqueId()); + break; + case GET_ATTRIBUTE: + instanceProperties = parentComponent.getComponentInstancesAttributes().get(componentInstance.getUniqueId()); + break; + default: + instanceProperties = List.of(); + } + if (instanceProperties == null) { + return List.of(); + } + return instanceProperties; + } + + private static List<? extends ToscaPropertyData> getSelfPropertyFromGetFunction(final Component component, + final ToscaGetFunctionDataDefinition toscaGetFunction) { + switch (toscaGetFunction.getFunctionType()) { + case GET_INPUT: + if (component.getInputs() != null) { + return component.getInputs(); + } + break; + case GET_PROPERTY: + if (component.getProperties() != null) { + return component.getProperties(); + } + break; + case GET_ATTRIBUTE: + if (component.getAttributes() != null) { + return component.getAttributes(); + } + break; + } + return List.of(); } - - private Optional<ComponentInstanceProperty> getProperty(final Component parentComponent, final String componentInstanceId, - final String capabilityName, final String propertyName) { + private Optional<PropertyDefinition> findSubProperty(final List<String> propertyPath, final String parentPropertyType, + final Map<String, DataTypeDefinition> modelDataTypes) { + final DataTypeDefinition dataTypeDefinition = modelDataTypes.get(parentPropertyType); + if (CollectionUtils.isEmpty(dataTypeDefinition.getProperties())) { + return Optional.empty(); + } + final PropertyDefinition propertyDefinition = dataTypeDefinition.getProperties().stream() + .filter(propertyDefinition1 -> propertyDefinition1.getName().equals(propertyPath.get(0))).findFirst().orElse(null); + if (propertyDefinition == null) { + return Optional.empty(); + } + if (propertyPath.size() == 1) { + return Optional.of(propertyDefinition); + } + return findSubProperty(propertyPath.subList(1, propertyPath.size()), propertyDefinition.getType(), modelDataTypes); + } + + private Optional<ComponentInstanceProperty> getInstanceProperties(final Component parentComponent, final String componentInstanceId, + final String capabilityName, final String propertyName) { if (StringUtils.isEmpty(capabilityName)) { return parentComponent.getComponentInstancesProperties().get(componentInstanceId).stream() .filter(property -> propertyName.equals(property.getName())).findFirst(); @@ -195,80 +259,109 @@ public class NodeFilterValidator { } private Either<Boolean, ResponseFormat> validateInputConstraint(final Component parentComponent, final String componentInstanceId, - final UIConstraint uiConstraint) { + final FilterConstraintDto filterConstraint) { final List<InputDefinition> sourceInputDefinition = parentComponent.getInputs(); - if (CollectionUtils.isNotEmpty(sourceInputDefinition)) { - final Optional<? extends InputDefinition> sourceSelectedProperty = sourceInputDefinition.stream() - .filter(input -> uiConstraint.getValue().equals(input.getName())).findFirst(); - final Optional<? extends PropertyDefinition> targetComponentInstanceProperty = parentComponent.getComponentInstancesProperties() - .get(componentInstanceId).stream().filter(property -> uiConstraint.getServicePropertyName().equals(property.getName())).findFirst(); - if (sourceSelectedProperty.isPresent() && targetComponentInstanceProperty.isPresent()) { - return validatePropertyData(uiConstraint, sourceSelectedProperty, targetComponentInstanceProperty); + if (CollectionUtils.isEmpty(sourceInputDefinition)) { + LOGGER.debug("Parent component '{}', unique id '{}', does not have inputs", parentComponent.getName(), parentComponent.getUniqueId()); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_DOES_NOT_HAVE_INPUTS, parentComponent.getName())); + } + if (!(filterConstraint.getValue() instanceof ToscaGetFunctionDataDefinition)) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.TOSCA_FUNCTION_EXPECTED_ERROR)); + } + final ToscaGetFunctionDataDefinition getFunction = (ToscaGetFunctionDataDefinition) filterConstraint.getValue(); + final List<String> propertyPathFromSource = getFunction.getPropertyPathFromSource(); + Optional<? extends PropertyDefinition> sourceSelectedProperty = + sourceInputDefinition.stream().filter(input -> input.getName().equals(propertyPathFromSource.get(0))).findFirst(); + if (sourceSelectedProperty.isEmpty()) { + LOGGER.debug(INPUT_NOT_FOUND_LOG, + propertyPathFromSource.get(0), parentComponent.getName(), parentComponent.getUniqueId()); + return Either.right( + componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INPUT_NOT_FOUND, propertyPathFromSource.get(0), parentComponent.getName()) + ); + } + if (propertyPathFromSource.size() > 1) { + final Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> allDataTypesEither = + applicationDataTypeCache.getAll(parentComponent.getModel()); + if (allDataTypesEither.isRight()) { + LOGGER.error("Could not load data types for model {}", parentComponent.getModel()); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.DATA_TYPES_NOT_LOADED, parentComponent.getModel())); + } + sourceSelectedProperty = + findSubProperty(propertyPathFromSource.subList(1, propertyPathFromSource.size()), sourceSelectedProperty.get().getType(), + allDataTypesEither.left().value()); + } + final Optional<? extends PropertyDefinition> targetComponentInstanceProperty = + parentComponent.getComponentInstancesProperties() + .get(componentInstanceId).stream() + .filter(property -> filterConstraint.getPropertyName().equals(property.getName())) + .findFirst(); + if (sourceSelectedProperty.isPresent() && targetComponentInstanceProperty.isPresent()) { + final ResponseFormat responseFormat = validatePropertyData(sourceSelectedProperty.get(), targetComponentInstanceProperty.get()); + if (responseFormat != null) { + return Either.right(responseFormat); } + return Either.left(true); } - LOGGER.debug("Parent component does not have inputs", parentComponent); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INPUTS_NOT_FOUND)); } - private Either<Boolean, ResponseFormat> validatePropertyData(UIConstraint uiConstraint, - Optional<? extends PropertyDefinition> sourceSelectedProperty, - Optional<? extends PropertyDefinition> targetComponentInstanceProperty) { - if (sourceSelectedProperty.isPresent() && targetComponentInstanceProperty.isPresent()) { - final PropertyDefinition sourcePropDefinition = sourceSelectedProperty.get(); - final String sourceType = sourcePropDefinition.getType(); - final PropertyDefinition targetPropDefinition = targetComponentInstanceProperty.get(); - final String targetType = targetPropDefinition.getType(); - if (sourceType.equals(targetType)) { - if (schemableTypes.contains(sourceType)) { - final SchemaDefinition sourceSchemaDefinition = sourcePropDefinition.getSchema(); - final SchemaDefinition targetSchemaDefinition = targetPropDefinition.getSchema(); - if (!sourceSchemaDefinition.equals(targetSchemaDefinition)) { - return Either.right(componentsUtils - .getResponseFormat(ActionStatus.SOURCE_TARGET_SCHEMA_MISMATCH, uiConstraint.getServicePropertyName(), - uiConstraint.getValue().toString())); - } + private <T extends ToscaPropertyData> ResponseFormat validatePropertyData(final T sourcePropDefinition, + final T targetPropDefinition) { + final String sourceType = sourcePropDefinition.getType(); + final String targetType = targetPropDefinition.getType(); + if (sourceType.equals(targetType)) { + if (TYPES_WITH_SCHEMA.contains(sourceType)) { + 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 Either.left(Boolean.TRUE); - } else { - return Either.right(componentsUtils - .getResponseFormat(ActionStatus.SOURCE_TARGET_PROPERTY_TYPE_MISMATCH, uiConstraint.getServicePropertyName(), - uiConstraint.getValue().toString())); } - } else { - LOGGER.debug("Null value passed to `validatePropertyData` - sourceSelectedProperty: '{}' - targetComponentInstanceProperty: '{}'", - sourceSelectedProperty, targetComponentInstanceProperty); - return Either.right(componentsUtils - .getResponseFormat(ActionStatus.GENERAL_ERROR, uiConstraint.getServicePropertyName(), uiConstraint.getValue().toString())); + return null; } + return componentsUtils.getResponseFormat(ActionStatus.SOURCE_TARGET_PROPERTY_TYPE_MISMATCH, + sourcePropDefinition.getName(), sourcePropDefinition.getType(), targetPropDefinition.getName(), targetPropDefinition.getType()); } private Either<Boolean, ResponseFormat> validateStaticValueAndOperator(final Component parentComponent, final String componentInstanceId, - final UIConstraint uiConstraint) { - if (!(Objects.nonNull(uiConstraint) && uiConstraint.getValue() instanceof String)) { - return Either.left(false); - } - //TODO: get capabilities properties when constraint type is capabilities - final Optional<ComponentInstanceProperty> componentInstanceProperty = parentComponent.getComponentInstancesProperties() - .get(componentInstanceId).stream().filter(property -> uiConstraint.getServicePropertyName().equals(property.getName())).findFirst(); - if (!componentInstanceProperty.isPresent()) { - return Either.right(componentsUtils.getResponseFormat(ActionStatus.SELECTED_PROPERTY_NOT_PRESENT, uiConstraint.getServicePropertyName())); - } - if (comparableConstraintsOperators.contains(uiConstraint.getConstraintOperator()) && !comparableTypes - .contains(componentInstanceProperty.get().getType())) { - return Either.right(componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_OPERATOR_PROVIDED, uiConstraint.getServicePropertyName(), - uiConstraint.getConstraintOperator())); - } - return isValidValueCheck(componentInstanceProperty.get().getType(), String.valueOf(uiConstraint.getValue()), - uiConstraint.getServicePropertyName()); + final FilterConstraintDto filterConstraint) { + final ComponentInstanceProperty componentInstanceProperty = parentComponent.getComponentInstancesProperties() + .get(componentInstanceId).stream().filter(property -> filterConstraint.getPropertyName().equals(property.getName())) + .findFirst() + .orElse(null); + if (componentInstanceProperty == null) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.SELECTED_PROPERTY_NOT_PRESENT, filterConstraint.getPropertyName())); + } + if (filterConstraint.getOperator().isComparable() && !COMPARABLE_TYPES.contains(componentInstanceProperty.getType())) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_OPERATOR_PROVIDED, filterConstraint.getPropertyName(), + filterConstraint.getOperator().getType())); + } + return isValidValueCheck(componentInstanceProperty.getType(), componentInstanceProperty.getSchemaType(), parentComponent.getModel(), + filterConstraint.getValue(), filterConstraint.getPropertyName()); + } + + private Either<Boolean, ResponseFormat> validateStaticSubstitutionFilter(final Component component, + final FilterConstraintDto filterConstraint) { + + final PropertyDefinition componentProperty = component.getProperties().stream() + .filter(property -> property.getName().equals(filterConstraint.getPropertyName())).findFirst().orElse(null); + if (componentProperty == null) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.SELECTED_PROPERTY_NOT_PRESENT, filterConstraint.getPropertyName())); + } + if (filterConstraint.getOperator().isComparable() && !COMPARABLE_TYPES.contains(componentProperty.getType())) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_OPERATOR_PROVIDED, filterConstraint.getPropertyName(), + filterConstraint.getOperator().getType())); + } + return isValidValueCheck(componentProperty.getType(), componentProperty.getSchemaType(), component.getModel(), + filterConstraint.getValue(), filterConstraint.getPropertyName()); } private Either<Boolean, ResponseFormat> validateStaticValueAndOperatorOfCapabilityProperties(final Component parentComponent, final String componentInstanceId, - final UIConstraint uiConstraint) { - if (!(Objects.nonNull(uiConstraint) && uiConstraint.getValue() instanceof String)) { - return Either.left(false); - } - Optional<ComponentInstanceProperty> optionalComponentInstanceProperty = Optional.empty(); + final FilterConstraintDto filterConstraint) { + ComponentInstanceProperty componentInstanceProperty = null; final Optional<ComponentInstance> optionalComponentInstances = parentComponent.getComponentInstances().stream() .filter(componentInstance -> componentInstanceId.equalsIgnoreCase(componentInstance.getUniqueId())).findFirst(); if (optionalComponentInstances.isPresent()) { @@ -277,99 +370,136 @@ public class NodeFilterValidator { .allMatch(capabilityDefinition -> capabilityDefinition.getProperties() != null)).collect(Collectors.toList()).stream().filter( capabilityDefinitions -> capabilityDefinitions.stream().allMatch( capabilityDefinition -> capabilityDefinition.getProperties().stream().anyMatch( - componentInstanceProperty -> uiConstraint.getServicePropertyName() - .equalsIgnoreCase(componentInstanceProperty.getName())))).findFirst(); + componentInstanceProperty1 -> filterConstraint.getPropertyName() + .equalsIgnoreCase(componentInstanceProperty1.getName())))).findFirst(); if (optionalCapabilityDefinitionList.isPresent() && !optionalCapabilityDefinitionList.get().isEmpty()) { - optionalComponentInstanceProperty = getComponentInstanceProperty(optionalCapabilityDefinitionList.get().get(0), uiConstraint.getServicePropertyName()); + componentInstanceProperty = + getComponentInstanceProperty(optionalCapabilityDefinitionList.get().get(0), filterConstraint.getPropertyName()).orElse(null); } } - if (optionalComponentInstanceProperty.isEmpty()) { - return Either.right(componentsUtils.getResponseFormat(ActionStatus.SELECTED_PROPERTY_NOT_PRESENT, uiConstraint.getServicePropertyName())); + if (componentInstanceProperty == null) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.SELECTED_PROPERTY_NOT_PRESENT, filterConstraint.getPropertyName())); } - if (comparableConstraintsOperators.contains(uiConstraint.getConstraintOperator()) && !comparableTypes - .contains(optionalComponentInstanceProperty.get().getType())) { - return Either.right(componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_OPERATOR_PROVIDED, uiConstraint.getServicePropertyName(), - uiConstraint.getConstraintOperator())); + if (filterConstraint.getOperator().isComparable() && !COMPARABLE_TYPES.contains(componentInstanceProperty.getType())) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_OPERATOR_PROVIDED, filterConstraint.getPropertyName(), + filterConstraint.getOperator().getType())); } - return isValidValueCheck(optionalComponentInstanceProperty.get().getType(), String.valueOf(uiConstraint.getValue()), - uiConstraint.getServicePropertyName()); + return isValidValueCheck(componentInstanceProperty.getType(), componentInstanceProperty.getSchemaType(), parentComponent.getModel(), + filterConstraint.getValue(), filterConstraint.getPropertyName()); } private Optional<ComponentInstanceProperty> getComponentInstanceProperty(CapabilityDefinition capabilityDefinition, final String propertyName){ return capabilityDefinition.getProperties().stream().filter(property -> property.getName().equals(propertyName)).findAny(); } - private Either<Boolean, ResponseFormat> isValidValueCheck(String type, String value, String propertyName) { - ToscaPropertyType toscaPropertyType = ToscaPropertyType.isValidType(type); - if (Objects.isNull(toscaPropertyType)) { + private Either<Boolean, ResponseFormat> isValidValueCheck(final String type, final String schemaType, final String model, + final Object value, final String propertyName) { + final Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> allDataTypesEither = + applicationDataTypeCache.getAll(model); + if (allDataTypesEither.isRight()) { + LOGGER.error("Could not validate filter value. Could not load data types for model {}", model); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.DATA_TYPES_NOT_LOADED, model)); + } + final Map<String, DataTypeDefinition> modelDataTypesMap = allDataTypesEither.left().value(); + final ToscaPropertyType toscaPropertyType = ToscaPropertyType.isValidType(type); + if (toscaPropertyType == null && !modelDataTypesMap.containsKey(type)) { return Either.right(componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_PROPERTY_TYPE, type, propertyName)); } - if (toscaPropertyType.getValidator().isValid(value, null)) { - return Either.left(Boolean.TRUE); + final String valueAsJsonString; + try { + valueAsJsonString = new Gson().toJson(value); + } catch (final Exception e) { + LOGGER.debug("Unsupported property filter value", e); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_VALUE_PROVIDED, type, propertyName, String.valueOf(value))); + } + if (toscaPropertyType != null) { + if (toscaPropertyType.getValidator().isValid(valueAsJsonString, schemaType, modelDataTypesMap)) { + return Either.left(true); + } + } else { + if (DataTypeValidatorConverter.getInstance().isValid(valueAsJsonString, modelDataTypesMap.get(type), modelDataTypesMap)) { + return Either.left(true); + } } - return Either.right(componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_VALUE_PROVIDED, type, propertyName, value)); + + return Either.right(componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_VALUE_PROVIDED, type, propertyName, valueAsJsonString)); } - public Either<Boolean, ResponseFormat> validateComponentFilter(final Component component, final List<String> uiConstraints, - final NodeFilterConstraintAction action) { - try { - if (NodeFilterConstraintAction.ADD == action || NodeFilterConstraintAction.UPDATE == action) { - for (final String uiConstraint : uiConstraints) { - final UIConstraint constraint = new ConstraintConvertor().convert(uiConstraint); - if (ConstraintConvertor.PROPERTY_CONSTRAINT.equals(constraint.getSourceType())) { - final Either<Boolean, ResponseFormat> booleanResponseFormatEither = validateComponentPropertyConstraint(component, - constraint); - if (booleanResponseFormatEither.isRight()) { - return booleanResponseFormatEither; - } - } else if (ConstraintConvertor.STATIC_CONSTRAINT.equals(constraint.getSourceType())) { - final Either<Boolean, ResponseFormat> booleanResponseFormatEither = validateComponentStaticValueAndOperator(component, - constraint); - if (booleanResponseFormatEither.isRight()) { - return booleanResponseFormatEither; - } - } - } - } - } catch (final Exception e) { - LOGGER.debug("Provided constraint" + uiConstraints, e); + public Either<Boolean, ResponseFormat> validateSubstitutionFilter(final Component component, final List<FilterConstraintDto> filterConstraintList) { + if (CollectionUtils.isEmpty(filterConstraintList)) { return Either.right(componentsUtils.getResponseFormat(ActionStatus.CONSTRAINT_FORMAT_INCORRECT)); } + for (final FilterConstraintDto filterConstraintDto : filterConstraintList) { + final Either<Boolean, ResponseFormat> validationEither = validateSubstitutionFilter(component, filterConstraintDto); + if (validationEither.isRight()) { + return validationEither; + } + } return Either.left(true); } - private Either<Boolean, ResponseFormat> validateComponentPropertyConstraint(final Component component, final UIConstraint uiConstraint) { - String source = SOURCE; - final List<PropertyDefinition> propertyDefinitions = component.getProperties(); - if (CollectionUtils.isNotEmpty(propertyDefinitions)) { - final Optional<? extends PropertyDefinition> sourceSelectedProperty = propertyDefinitions.stream() - .filter(property -> uiConstraint.getValue().equals(property.getName())).findFirst(); - final Optional<? extends PropertyDefinition> targetComponentProperty = component.getProperties().stream() - .filter(property -> uiConstraint.getServicePropertyName().equals(property.getName())).findFirst(); - source = !targetComponentProperty.isPresent() ? "Target" : SOURCE; - if (sourceSelectedProperty.isPresent() && targetComponentProperty.isPresent()) { - return validatePropertyData(uiConstraint, sourceSelectedProperty, targetComponentProperty); - } + public Either<Boolean, ResponseFormat> validateSubstitutionFilter(final Component component, final FilterConstraintDto filterConstraint) { + validateFilterConstraint(filterConstraint); + switch (filterConstraint.getValueType()) { + case STATIC: + return validateStaticSubstitutionFilter(component, filterConstraint); + case GET_PROPERTY: + case GET_ATTRIBUTE: + case GET_INPUT: + return validateSubstitutionFilterGetFunctionConstraint(component, filterConstraint); + default: + return Either.left(true); } - final String missingProperty = source.equals(SOURCE) ? uiConstraint.getValue().toString() : uiConstraint.getServicePropertyName(); - return Either.right(componentsUtils.getResponseFormat(ActionStatus.MAPPED_PROPERTY_NOT_FOUND, source, missingProperty)); } - private Either<Boolean, ResponseFormat> validateComponentStaticValueAndOperator(final Component component, final UIConstraint uiConstraint) { - if (!(Objects.nonNull(uiConstraint) && uiConstraint.getValue() instanceof String)) { - return Either.left(false); + private Either<Boolean, ResponseFormat> validateSubstitutionFilterGetFunctionConstraint(final Component component, + final FilterConstraintDto filterConstraint) { + final ToscaGetFunctionDataDefinition toscaGetFunction = filterConstraint.getAsToscaGetFunction().orElse(null); + if (toscaGetFunction == null) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.TOSCA_FUNCTION_EXPECTED_ERROR)); } - final Optional<PropertyDefinition> componentProperty = component.getProperties().stream() - .filter(property -> uiConstraint.getServicePropertyName().equals(property.getName())).findFirst(); - if (componentProperty.isEmpty()) { - return Either.right(componentsUtils.getResponseFormat(ActionStatus.SELECTED_PROPERTY_NOT_PRESENT, uiConstraint.getServicePropertyName())); + + if (CollectionUtils.isEmpty(component.getProperties())) { + return Either.right( + componentsUtils.getResponseFormat(ActionStatus.FILTER_PROPERTY_NOT_FOUND, TARGET, getPropertyType(toscaGetFunction), + filterConstraint.getPropertyName()) + ); + } + + final Optional<? extends PropertyDefinition> targetComponentProperty = component.getProperties().stream() + .filter(property -> property.getName().equals(filterConstraint.getPropertyName())).findFirst(); + if (targetComponentProperty.isEmpty()) { + return Either.right( + componentsUtils.getResponseFormat(ActionStatus.FILTER_PROPERTY_NOT_FOUND, TARGET, getPropertyType(toscaGetFunction), + filterConstraint.getPropertyName()) + ); } - if (comparableConstraintsOperators.contains(uiConstraint.getConstraintOperator()) && !comparableTypes - .contains(componentProperty.get().getType())) { - return Either.right(componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_OPERATOR_PROVIDED, uiConstraint.getServicePropertyName(), - uiConstraint.getConstraintOperator())); + + final Optional<? extends ToscaPropertyData> sourceSelectedProperty = findPropertyFromGetFunction(component, toscaGetFunction); + if (sourceSelectedProperty.isEmpty()) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.FILTER_PROPERTY_NOT_FOUND, SOURCE, getPropertyType(toscaGetFunction), + String.join("->", toscaGetFunction.getPropertyPathFromSource()))); + } + + final ResponseFormat responseFormat = validatePropertyData(sourceSelectedProperty.get(), targetComponentProperty.get()); + if (responseFormat != null) { + return Either.right(responseFormat); } - return isValidValueCheck(componentProperty.get().getType(), String.valueOf(uiConstraint.getValue()), uiConstraint.getServicePropertyName()); + return Either.left(true); } + + private String getPropertyType(final ToscaGetFunctionDataDefinition toscaGetFunction) { + switch (toscaGetFunction.getType()) { + case GET_INPUT: + return "input"; + case GET_PROPERTY: + return "property"; + case GET_ATTRIBUTE: + return "attribute"; + default: + return ""; + } + } + } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/ConstraintConvertor.java b/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/ConstraintConvertor.java index a2c7aa2502..8e823bbe9f 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/ConstraintConvertor.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/ConstraintConvertor.java @@ -19,15 +19,15 @@ */ package org.openecomp.sdc.be.datamodel.utils; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; -import org.openecomp.sdc.be.model.tosca.constraints.ConstraintType; +import org.openecomp.sdc.be.datatypes.elements.ToscaFunctionType; +import org.openecomp.sdc.be.datatypes.enums.PropertySource; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; import org.openecomp.sdc.be.ui.model.UIConstraint; import org.openecomp.sdc.tosca.datatypes.ToscaFunctions; import org.slf4j.Logger; @@ -37,91 +37,92 @@ import org.yaml.snakeyaml.Yaml; public class ConstraintConvertor { - public static final String EQUAL_OPERATOR = ConstraintType.EQUAL.getTypes().get(1); - public static final String GREATER_THAN_OPERATOR = ConstraintType.GREATER_THAN.getTypes().get(1); - public static final String LESS_THAN_OPERATOR = ConstraintType.LESS_THAN.getTypes().get(1); - public static final String GREATER_OR_EQUAL_OPERATOR = ConstraintType.GREATER_OR_EQUAL.getTypes().get(1); - public static final String LESS_OR_EQUAL_OPERATOR = ConstraintType.LESS_OR_EQUAL.getTypes().get(1); public static final String STATIC_CONSTRAINT = "static"; public static final String PROPERTY_CONSTRAINT = "property"; public static final String SERVICE_INPUT_CONSTRAINT = "service_input"; public static final String SELF = "SELF"; private static final Logger logger = LoggerFactory.getLogger(ConstraintConvertor.class); - private static Set<String> SUPPORTED_CONSTRAINT_LIST = ImmutableSet.of(EQUAL_OPERATOR, GREATER_THAN_OPERATOR, LESS_THAN_OPERATOR, GREATER_OR_EQUAL_OPERATOR, LESS_OR_EQUAL_OPERATOR); - private static Set<String> SUPPORTED_FUNCTIONS = ImmutableSet - .of(ToscaFunctions.GET_INPUT.getFunctionName(), ToscaFunctions.GET_PROPERTY.getFunctionName()); + private static final Set<ConstraintType> SUPPORTED_CONSTRAINT_LIST = + Set.of(ConstraintType.EQUAL, ConstraintType.GREATER_THAN, ConstraintType.LESS_THAN, + ConstraintType.GREATER_OR_EQUAL, ConstraintType.LESS_OR_EQUAL); - public UIConstraint convert(String inConstraint) { - return convert(inConstraint, ""); + public UIConstraint convert(final String constraintValue) { + return convert(constraintValue, null); } - public UIConstraint convert(String inConstraint, String valueType) { + public UIConstraint convert(final String inConstraint, final String valueType) { Yaml yamlSource = new Yaml(); UIConstraint uiConstraint = new UIConstraint(); Object content1 = yamlSource.load(inConstraint); if (!(content1 instanceof Map)) { return null; } - Map map1 = (Map) content1; - Object key = map1.keySet().iterator().next(); - uiConstraint.setServicePropertyName(key.toString()); - Object content2 = map1.get(key); - if (!(content2 instanceof Map)) { + Map propertyAndConstraintMap = (Map) content1; + Object propertyNameKey = propertyAndConstraintMap.keySet().iterator().next(); + uiConstraint.setServicePropertyName(propertyNameKey.toString()); + Object operatorMapObj = propertyAndConstraintMap.get(propertyNameKey); + if (!(operatorMapObj instanceof Map)) { return null; } - Map map2 = (Map) content2; - Object key2 = map2.keySet().iterator().next(); - final String operator = key2.toString(); - if (SUPPORTED_CONSTRAINT_LIST.contains(operator)) { + Map operatorMap = (Map) operatorMapObj; + Object operatorKey = operatorMap.keySet().iterator().next(); + final String operator = (String) operatorKey; + final Optional<ConstraintType> constraintType = ConstraintType.findByType(operator); + if (constraintType.isPresent() && SUPPORTED_CONSTRAINT_LIST.contains(constraintType.get())) { uiConstraint.setConstraintOperator(operator); } - Object content3 = map2.get(key2); - if (content3 instanceof String || content3 instanceof Number || content3 instanceof Boolean) { - uiConstraint.setValue(content3); + Object constraintValueObj = operatorMap.get(operatorKey); + if (constraintValueObj instanceof String || constraintValueObj instanceof Number || constraintValueObj instanceof Boolean) { + uiConstraint.setValue(constraintValueObj); uiConstraint.setSourceType(STATIC_CONSTRAINT); uiConstraint.setSourceName(STATIC_CONSTRAINT); return uiConstraint; - } else if (content3 instanceof List) { - List list1 = (List) content3; + } else if (constraintValueObj instanceof List) { uiConstraint.setSourceType(STATIC_CONSTRAINT); uiConstraint.setSourceName(STATIC_CONSTRAINT); - uiConstraint.setValue(list1); + uiConstraint.setValue(constraintValueObj); return uiConstraint; - } else if (valueType != null && valueType.equals("string")) { + } else if ("string".equals(valueType)) { uiConstraint.setSourceType(STATIC_CONSTRAINT); uiConstraint.setSourceName(STATIC_CONSTRAINT); - DumperOptions options = new DumperOptions(); - options.setDefaultFlowStyle(DumperOptions.FlowStyle.FLOW); - Yaml yaml = new Yaml(options); - String yamlString = yaml.dump(content3); - uiConstraint.setValue(yamlString); + uiConstraint.setValue(dumpYamlString(constraintValueObj)); return uiConstraint; - } else if (content3 instanceof Map) { - return handleMap(uiConstraint, content3); + } else if (constraintValueObj instanceof Map) { + return handleMap(uiConstraint, (Map<Object, Object>) constraintValueObj); } return null; } - private UIConstraint handleMap(UIConstraint uiConstraint, Object content3) { - Map map3 = (Map) content3; - Map.Entry entry = (Map.Entry) map3.entrySet().iterator().next(); + private String dumpYamlString(final Object constraintValueObj) { + final var dumperOptions = new DumperOptions(); + dumperOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.FLOW); + return new Yaml(dumperOptions).dump(constraintValueObj); + } + + private UIConstraint handleMap(final UIConstraint uiConstraint, final Map<Object, Object> constraintValueAsMap) { + final Map.Entry<Object, Object> entry = constraintValueAsMap.entrySet().iterator().next(); final String firstKey = entry.getKey().toString().trim(); - if (!SUPPORTED_FUNCTIONS.contains(firstKey)) { - uiConstraint.setValue(content3); + final ToscaFunctionType toscaFunctionType = ToscaFunctionType.findType(firstKey).orElse(null); + if (toscaFunctionType == null) { + uiConstraint.setValue(constraintValueAsMap); return uiConstraint; } - if (ToscaFunctions.GET_INPUT.getFunctionName().equals(firstKey)) { - uiConstraint.setSourceType(SERVICE_INPUT_CONSTRAINT); - uiConstraint.setValue(entry.getValue()); - return uiConstraint; - } else if (ToscaFunctions.GET_PROPERTY.getFunctionName().equals(firstKey)) { - uiConstraint.setSourceType(PROPERTY_CONSTRAINT); - final List<String> value = (List<String>) entry.getValue(); - uiConstraint.setSourceName(value.get(0)); - uiConstraint.setValue(value.get(1)); - return uiConstraint; + uiConstraint.setValue(constraintValueAsMap); + uiConstraint.setSourceType(toscaFunctionType.getName()); + switch (toscaFunctionType) { + case GET_INPUT: + uiConstraint.setSourceName(PropertySource.SELF.getName()); + break; + case GET_PROPERTY: + case GET_ATTRIBUTE: + final List<String> value = (List<String>) entry.getValue(); + uiConstraint.setSourceName(value.get(0)); + break; + default: + break; } - return null; + + return uiConstraint; } public List<String> convertToList(List<UIConstraint> uiConstraints) { @@ -135,29 +136,39 @@ public class ConstraintConvertor { return retVal; } - public String convert(UIConstraint uiConstraint) { + public String convert(final UIConstraint uiConstraint) { try { - Map map1 = new HashMap(); - Map map2 = new HashMap(); - map1.put(uiConstraint.getServicePropertyName(), map2); - if (uiConstraint.getSourceType().equals(STATIC_CONSTRAINT)) { - Object value = uiConstraint.getValue(); - if (value instanceof String) { - value = new Yaml().load(value.toString()); + final Map<String, Object> constraintAsMap = new HashMap<>(); + switch (uiConstraint.getSourceType()) { + case STATIC_CONSTRAINT: { + Object value = uiConstraint.getValue(); + if (value instanceof String) { + value = new Yaml().load(value.toString()); + } + constraintAsMap.put(uiConstraint.getConstraintOperator(), value); + break; + } + case PROPERTY_CONSTRAINT: + constraintAsMap.put(uiConstraint.getConstraintOperator(), + Map.of(ToscaFunctions.GET_PROPERTY.getFunctionName(), List.of(uiConstraint.getSourceName(), uiConstraint.getValue())) + ); + break; + case SERVICE_INPUT_CONSTRAINT: + constraintAsMap.put(uiConstraint.getConstraintOperator(), Map.of(ToscaFunctions.GET_INPUT.getFunctionName(), uiConstraint.getValue())); + break; + default: { + if (ToscaFunctionType.findType(uiConstraint.getSourceType()).isPresent()) { + Object value = uiConstraint.getValue(); + if (value instanceof String) { + value = new Yaml().load((String) value); + } + constraintAsMap.put(uiConstraint.getConstraintOperator(), value); + } } - map2.put(uiConstraint.getConstraintOperator(), value); - } else if (uiConstraint.getSourceType().equals(PROPERTY_CONSTRAINT)) { - List list1 = Arrays.asList(uiConstraint.getSourceName(), uiConstraint.getValue()); - Map map3 = ImmutableMap.of(ToscaFunctions.GET_PROPERTY.getFunctionName(), list1); - map2.put(uiConstraint.getConstraintOperator(), map3); - } else if (uiConstraint.getSourceType().equals(SERVICE_INPUT_CONSTRAINT)) { - Map map3 = ImmutableMap.of(ToscaFunctions.GET_INPUT.getFunctionName(), uiConstraint.getValue()); - map2.put(uiConstraint.getConstraintOperator(), map3); } - Yaml yamlSource = new Yaml(); - return yamlSource.dump(map1); - } catch (NullPointerException ex) { - logger.error(ex.getMessage(), ex); + return new Yaml().dump(Map.of(uiConstraint.getServicePropertyName(), constraintAsMap)); + } catch (final Exception ex) { + logger.error("Could not convert constraint", ex); } return null; } @@ -187,13 +198,12 @@ public class ConstraintConvertor { uiConstraint.setSourceName(STATIC_CONSTRAINT); return uiConstraint; } else if (constraintValue instanceof List) { - final List constraintValueList = (List) constraintValue; uiConstraint.setSourceType(STATIC_CONSTRAINT); uiConstraint.setSourceName(STATIC_CONSTRAINT); - uiConstraint.setValue(constraintValueList); + uiConstraint.setValue(constraintValue); return uiConstraint; } else if (constraintValue instanceof Map) { - return handleMap(uiConstraint, constraintValue); + return handleMap(uiConstraint, (Map<Object, Object>) constraintValue); } return null; } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java index 7d58687bfd..313a303b61 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java @@ -80,9 +80,7 @@ import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.dao.cassandra.CassandraOperationStatus; import org.openecomp.sdc.be.dao.graph.datatype.AdditionalInformationEnum; import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; -import org.openecomp.sdc.be.datamodel.utils.ConstraintConvertor; import org.openecomp.sdc.be.datatypes.elements.AdditionalInfoParameterInfo; -import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ToscaFunction; import org.openecomp.sdc.be.datatypes.elements.ToscaFunctionJsonDeserializer; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; @@ -138,7 +136,7 @@ public class ComponentsUtils { private static final String CONVERT_JSON_TO_OBJECT = "convertJsonToObject"; private static final Logger log = Logger.getLogger(ComponentsUtils.class); private static final String PARTNER_NAME = "UNKNOWN"; - private static LoggerSdcAudit audit = new LoggerSdcAudit(DmaapConsumer.class); + private static final LoggerSdcAudit audit = new LoggerSdcAudit(DmaapConsumer.class); private final AuditingManager auditingManager; private final ResponseFormatManager responseFormatManager; @@ -174,27 +172,7 @@ public class ComponentsUtils { return false; } return componentInstance.getNodeFilter().getProperties().getListToscaDataDefinition().stream() - .anyMatch(property -> isPropertyConstraintChangedByCi(property, componentInstanceName)); - } - - private static boolean isPropertyConstraintChangedByCi( - final RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition, final String componentInstanceName) { - final List<String> constraints = requirementNodeFilterPropertyDataDefinition.getConstraints(); - if (constraints == null) { - return false; - } - return constraints.stream().anyMatch(constraint -> isConstraintChangedByCi(constraint, componentInstanceName)); - } - - private static boolean isConstraintChangedByCi(final String constraint, final String componentInstanceName) { - final UIConstraint uiConstraint = new ConstraintConvertor().convert(constraint); - if (uiConstraint == null || uiConstraint.getSourceType() == null) { - return false; - } - if (!uiConstraint.getSourceType().equals(ConstraintConvertor.PROPERTY_CONSTRAINT)) { - return false; - } - return uiConstraint.getSourceName().equals(componentInstanceName); + .anyMatch(property -> ServiceFilterUtils.isPropertyConstraintChangedByCi(property, componentInstanceName)); } public AuditingManager getAuditingManager() { @@ -1554,7 +1532,7 @@ public class ComponentsUtils { log.error(EcompLoggerErrorCode.DATA_ERROR, FAILED_TO_PARSE_CONSTRAINT_DATA, constraintData); return Collections.emptyList(); } - return uiConstraintsMaps.stream().map(dataMap -> new com.fasterxml.jackson.databind.ObjectMapper().convertValue(dataMap, UIConstraint.class)) + return uiConstraintsMaps.stream().map(dataMap -> new ObjectMapper().convertValue(dataMap, UIConstraint.class)) .collect(Collectors.toList()); } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ServiceFilterUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ServiceFilterUtils.java index 866affc509..c3fdaa6bed 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ServiceFilterUtils.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ServiceFilterUtils.java @@ -24,11 +24,18 @@ import org.apache.commons.collections.CollectionUtils; import org.javatuples.Pair; import org.openecomp.sdc.be.datamodel.utils.ConstraintConvertor; import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition; -import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyFilterConstraintDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyFilterDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ToscaConcatFunction; +import org.openecomp.sdc.be.datatypes.elements.ToscaFunction; +import org.openecomp.sdc.be.datatypes.elements.ToscaFunctionParameter; +import org.openecomp.sdc.be.datatypes.elements.ToscaFunctionType; +import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.FilterValueType; import org.openecomp.sdc.be.model.ComponentInstance; import org.openecomp.sdc.be.model.InputDefinition; import org.openecomp.sdc.be.model.Service; -import org.openecomp.sdc.be.ui.model.UIConstraint; +import org.openecomp.sdc.be.ui.mapper.FilterConstraintMapper; public class ServiceFilterUtils { @@ -48,12 +55,19 @@ public class ServiceFilterUtils { || ci.getNodeFilter().getProperties().getListToscaDataDefinition() == null) { return false; } - return ci.getNodeFilter().getProperties().getListToscaDataDefinition().stream().flatMap(prop -> prop.getConstraints().stream()) - .map(String::new) - .filter(constraint -> new ConstraintConvertor().convert(constraint).getSourceType().equals(ConstraintConvertor.PROPERTY_CONSTRAINT)) - .anyMatch(constraintStr -> { - UIConstraint uiConstraint = new ConstraintConvertor().convert(constraintStr); - return uiConstraint.getSourceName().equals(ciName) && uiConstraint.getValue().equals(propertyName); + return ci.getNodeFilter().getProperties().getListToscaDataDefinition().stream() + .flatMap(prop -> prop.getConstraints().stream()) + .filter(constraint -> + List.of(ConstraintConvertor.PROPERTY_CONSTRAINT, ToscaFunctionType.GET_PROPERTY.getName()) + .contains(constraint.getValueType().getName()) + ) + .map(new FilterConstraintMapper()::mapFrom) + .anyMatch(constraint -> { + final ToscaGetFunctionDataDefinition toscaGetFunction = constraint.getAsToscaGetFunction().orElse(null); + if (toscaGetFunction == null) { + return false; + } + return toscaGetFunction.getSourceName().equals(ciName) && toscaGetFunction.getPropertyPathFromSource().contains(propertyName); }); } @@ -69,22 +83,59 @@ public class ServiceFilterUtils { return new Pair<>(ci.getUniqueId(), ci.getNodeFilter()); } - private static void renamePropertyCiNames(RequirementNodeFilterPropertyDataDefinition property, String oldName, String newName) { - final List<String> constraints = property.getConstraints().stream().map(getConstraintString(oldName, newName)).collect(Collectors.toList()); - property.setConstraints(constraints); + private static void renamePropertyCiNames(final PropertyFilterDataDefinition propertyFilter, final String oldInstanceName, + final String newInstanceName) { + final List<FilterValueType> instanceValueTypes = + List.of(FilterValueType.GET_PROPERTY, FilterValueType.GET_ATTRIBUTE, FilterValueType.CONCAT); + final List<PropertyFilterConstraintDataDefinition> constraints = propertyFilter.getConstraints().stream() + .filter(propertyFilter1 -> instanceValueTypes.contains(propertyFilter1.getValueType())) + .map(replaceConstraintsInstanceSource(oldInstanceName, newInstanceName)) + .collect(Collectors.toList()); + propertyFilter.setConstraints(constraints); } - private static Function<String, String> getConstraintString(String oldName, String newName) { + private static Function<PropertyFilterConstraintDataDefinition, PropertyFilterConstraintDataDefinition> replaceConstraintsInstanceSource( + final String oldInstanceName, final String newInstanceName) { + return constraint -> { - final ConstraintConvertor constraintConvertor = new ConstraintConvertor(); - UIConstraint uiConstraint = constraintConvertor.convert(constraint); - if (uiConstraint.getSourceName().equals(oldName)) { - uiConstraint.setSourceName(newName); + final ToscaFunction toscaFunction = new FilterConstraintMapper().parseValueToToscaFunction(constraint.getValue()).orElse(null); + if (toscaFunction == null) { + return constraint; } - return constraintConvertor.convert(uiConstraint); + renameToscaFunctionComponentInstance(toscaFunction, oldInstanceName, newInstanceName); + return constraint; }; } + private static void renameToscaFunctionComponentInstance(final ToscaFunction toscaFunction, final String oldInstanceName, + final String newInstanceName) { + switch (toscaFunction.getType()) { + case GET_PROPERTY: + case GET_ATTRIBUTE: { + final ToscaGetFunctionDataDefinition toscaGetFunctionDataDefinition = (ToscaGetFunctionDataDefinition) toscaFunction; + if (toscaGetFunctionDataDefinition.getSourceName().equals(oldInstanceName)) { + toscaGetFunctionDataDefinition.setSourceName(newInstanceName); + } + break; + } + case CONCAT: { + final ToscaConcatFunction toscaConcatFunction = (ToscaConcatFunction) toscaFunction; + for (final ToscaFunctionParameter parameter : toscaConcatFunction.getParameters()) { + switch (parameter.getType()) { + case GET_PROPERTY: + case GET_ATTRIBUTE: + case CONCAT: + renameToscaFunctionComponentInstance((ToscaFunction) parameter, oldInstanceName, newInstanceName); + break; + default: + } + } + break; + } + default: + } + } + public static Set<String> getNodesFiltersToBeDeleted(Service service, String ciName) { return service.getComponentInstances().stream().filter(ci -> isNodeFilterUsingChangedCi(ci, ciName)).map(ComponentInstance::getName) .collect(Collectors.toSet()); @@ -106,24 +157,24 @@ public class ServiceFilterUtils { .anyMatch(property -> isPropertyConstraintChangedByCi(property, name)); } - private static boolean isPropertyConstraintChangedByCi(RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition, + public static boolean isPropertyConstraintChangedByCi(PropertyFilterDataDefinition propertyFilterDataDefinition, String name) { - List<String> constraints = requirementNodeFilterPropertyDataDefinition.getConstraints(); - if (constraints == null) { + List<PropertyFilterConstraintDataDefinition> constraints = propertyFilterDataDefinition.getConstraints(); + if (CollectionUtils.isEmpty(constraints)) { return false; } return constraints.stream().anyMatch(constraint -> isConstraintChangedByCi(constraint, name)); } - private static boolean isConstraintChangedByCi(String constraint, String name) { - UIConstraint uiConstraint = new ConstraintConvertor().convert(constraint); - if (uiConstraint == null || uiConstraint.getSourceType() == null) { - return false; - } - if (!uiConstraint.getSourceType().equals(ConstraintConvertor.PROPERTY_CONSTRAINT)) { - return false; + private static boolean isConstraintChangedByCi(final PropertyFilterConstraintDataDefinition constraint, final String name) { + if (constraint.getValueType() == FilterValueType.GET_PROPERTY || constraint.getValueType() == FilterValueType.GET_ATTRIBUTE) { + final ToscaFunction toscaFunction = new FilterConstraintMapper().parseValueToToscaFunction(constraint.getValue()).orElse(null); + if (toscaFunction != null) { + final ToscaGetFunctionDataDefinition toscaGetFunction = (ToscaGetFunctionDataDefinition) toscaFunction; + return toscaGetFunction.getSourceName().equals(name); + } } - return uiConstraint.getSourceName().equals(name); + return false; } public static Set<String> getNodesFiltersToBeDeleted(Service service, InputDefinition changedInput) { @@ -139,17 +190,20 @@ public class ServiceFilterUtils { .anyMatch(property -> isPropertyConstraintChangedByInput(property, changedInput)); } - private static boolean isPropertyConstraintChangedByInput(RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition, - InputDefinition changedInput) { - List<String> constraints = requirementNodeFilterPropertyDataDefinition.getConstraints(); + private static boolean isPropertyConstraintChangedByInput(final PropertyFilterDataDefinition propertyFilterDataDefinition, + final InputDefinition changedInput) { + final List<PropertyFilterConstraintDataDefinition> constraints = propertyFilterDataDefinition.getConstraints(); return constraints.stream().anyMatch(constraint -> isConstraintChangedByInput(constraint, changedInput)); } - private static boolean isConstraintChangedByInput(String constraint, InputDefinition changedInput) { - UIConstraint uiConstraint = new ConstraintConvertor().convert(constraint); - if (!uiConstraint.getSourceType().equals(ConstraintConvertor.SERVICE_INPUT_CONSTRAINT)) { - return false; + private static boolean isConstraintChangedByInput(final PropertyFilterConstraintDataDefinition constraint, final InputDefinition changedInput) { + if (constraint.getValueType() == FilterValueType.GET_INPUT) { + final ToscaFunction toscaFunction = new FilterConstraintMapper().parseValueToToscaFunction(constraint.getValue()).orElse(null); + if (toscaFunction != null) { + final ToscaGetFunctionDataDefinition toscaGetFunction = (ToscaGetFunctionDataDefinition) toscaFunction; + return toscaGetFunction.getPropertyPathFromSource().contains(changedInput.getName()); + } } - return uiConstraint.getValue().equals(changedInput.getName()); + return false; } } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentNodeFilterServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentNodeFilterServlet.java index c66bb8a8ec..87de704750 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentNodeFilterServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentNodeFilterServlet.java @@ -25,7 +25,6 @@ import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.tags.Tags; import java.util.Optional; import javax.inject.Inject; import javax.inject.Singleton; @@ -47,17 +46,19 @@ import org.openecomp.sdc.be.components.impl.ComponentNodeFilterBusinessLogic; import org.openecomp.sdc.be.components.impl.ResourceImportManager; import org.openecomp.sdc.be.components.impl.aaf.AafPermission; import org.openecomp.sdc.be.components.impl.aaf.PermissionAllowed; -import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction; +import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException; +import org.openecomp.sdc.be.components.impl.exceptions.ComponentException; import org.openecomp.sdc.be.config.BeEcompErrorManager; import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.datamodel.utils.ConstraintConvertor; import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.datatypes.enums.NodeFilterConstraintType; import org.openecomp.sdc.be.impl.ComponentsUtils; import org.openecomp.sdc.be.impl.ServletUtils; import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.dto.FilterConstraintDto; import org.openecomp.sdc.be.tosca.utils.NodeFilterConverter; +import org.openecomp.sdc.be.ui.mapper.FilterConstraintMapper; import org.openecomp.sdc.be.ui.model.UIConstraint; import org.openecomp.sdc.be.user.UserBusinessLogic; import org.openecomp.sdc.common.api.Constants; @@ -65,7 +66,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Path("/v1/catalog") -@Tags({@Tag(name = "SDCE-2 APIs")}) +@Tag(name = "SDCE-2 APIs") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Singleton @@ -122,21 +123,20 @@ public class ComponentNodeFilterServlet extends AbstractValidationsServlet { final User userModifier = componentNodeFilterBusinessLogic.validateUser(userId); final ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); try { - final Optional<UIConstraint> convertResponse = componentsUtils.parseToConstraint(constraintData, userModifier, componentTypeEnum); - if (convertResponse.isEmpty()) { - LOGGER.error(FAILED_TO_PARSE_COMPONENT); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } final Optional<NodeFilterConstraintType> nodeFilterConstraintType = NodeFilterConstraintType.parse(constraintType); if (nodeFilterConstraintType.isEmpty()) { return buildErrorResponse( getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT_PARAM, INVALID_NODE_FILTER_CONSTRAINT_TYPE, constraintType)); } - final UIConstraint uiConstraint = convertResponse.get(); - final String constraint = new ConstraintConvertor().convert(uiConstraint); + final UIConstraint uiConstraint = componentsUtils.parseToConstraint(constraintData, userModifier, componentTypeEnum).orElse(null); + if (uiConstraint == null) { + LOGGER.error(FAILED_TO_PARSE_COMPONENT); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + final FilterConstraintDto filterConstraintDto = new FilterConstraintMapper().mapFrom(uiConstraint); final Optional<CINodeFilterDataDefinition> actionResponse = componentNodeFilterBusinessLogic - .addNodeFilter(componentId.toLowerCase(), componentInstanceId, NodeFilterConstraintAction.ADD, uiConstraint.getServicePropertyName(), - constraint, true, componentTypeEnum, nodeFilterConstraintType.get(), + .addNodeFilter(componentId.toLowerCase(), componentInstanceId, + filterConstraintDto, true, componentTypeEnum, nodeFilterConstraintType.get(), StringUtils.isEmpty(uiConstraint.getCapabilityName()) ? "" : uiConstraint.getCapabilityName()); if (actionResponse.isEmpty()) { LOGGER.error(FAILED_TO_CREATE_NODE_FILTER); @@ -144,6 +144,10 @@ public class ComponentNodeFilterServlet extends AbstractValidationsServlet { } return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), new NodeFilterConverter().convertToUi(actionResponse.get())); + } catch (final ComponentException e) { + throw e; + } catch (final BusinessLogicException e) { + return buildErrorResponse(e.getResponseFormat()); } catch (final Exception e) { BeEcompErrorManager.getInstance().logBeRestApiGeneralError(NODE_FILTER_CREATION); LOGGER.error(CREATE_NODE_FILTER_WITH_AN_ERROR, e); @@ -236,7 +240,7 @@ public class ComponentNodeFilterServlet extends AbstractValidationsServlet { getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT_PARAM, INVALID_NODE_FILTER_CONSTRAINT_TYPE, constraintType)); } final Optional<CINodeFilterDataDefinition> actionResponse = componentNodeFilterBusinessLogic - .deleteNodeFilter(componentId.toLowerCase(), componentInstanceId, NodeFilterConstraintAction.DELETE, null, index, true, + .deleteNodeFilter(componentId.toLowerCase(), componentInstanceId, index, true, ComponentTypeEnum.findByParamName(componentType), nodeFilterConstraintType.get()); if (actionResponse.isEmpty()) { LOGGER.debug(FAILED_TO_DELETE_NODE_FILTER); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentSubstitutionFilterServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentSubstitutionFilterServlet.java index 067e68bcb8..596237065f 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentSubstitutionFilterServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentSubstitutionFilterServlet.java @@ -25,9 +25,9 @@ import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.tags.Tags; import java.util.List; import java.util.Optional; +import java.util.stream.Collectors; import javax.inject.Inject; import javax.inject.Singleton; import javax.servlet.http.HttpServletRequest; @@ -48,16 +48,18 @@ import org.openecomp.sdc.be.components.impl.ComponentSubstitutionFilterBusinessL import org.openecomp.sdc.be.components.impl.ResourceImportManager; import org.openecomp.sdc.be.components.impl.aaf.AafPermission; import org.openecomp.sdc.be.components.impl.aaf.PermissionAllowed; +import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException; import org.openecomp.sdc.be.config.BeEcompErrorManager; import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.datamodel.utils.ConstraintConvertor; import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.datatypes.enums.NodeFilterConstraintType; import org.openecomp.sdc.be.impl.ComponentsUtils; import org.openecomp.sdc.be.impl.ServletUtils; import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.dto.FilterConstraintDto; import org.openecomp.sdc.be.tosca.utils.SubstitutionFilterConverter; +import org.openecomp.sdc.be.ui.mapper.FilterConstraintMapper; import org.openecomp.sdc.be.ui.model.UIConstraint; import org.openecomp.sdc.be.ui.model.UINodeFilter; import org.openecomp.sdc.be.user.UserBusinessLogic; @@ -66,7 +68,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Path("/v1/catalog/{componentType}/{componentId}/substitutionFilter/{constraintType}") -@Tags({@Tag(name = "SDCE-2 APIs")}) +@Tag(name = "SDCE-2 APIs") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Singleton @@ -79,13 +81,17 @@ public class ComponentSubstitutionFilterServlet extends AbstractValidationsServl private static final String INVALID_CONSTRAINTYPE_ENUM = "Invalid value for NodeFilterConstraintType enum %s"; private static final String FAILED_TO_ADD_SUBSTITUTION_FILTER = "Failed to add substitution filter"; private static final String ADD_SUBSTITUTION_FILTER = "Add Substitution Filter"; - private static final String ADD_SUBSTITUTION_FILTER_WITH_AN_ERROR = "Add substitution filter with an error"; + private static final String ADD_SUBSTITUTION_FILTER_WITH_AN_ERROR = "An unexpected error has occurred while adding a substitution filter"; private static final String FAILED_TO_UPDATE_SUBSTITUTION_FILTER = "Failed to update substitution filter"; private static final String SUBSTITUTION_FILTER_UPDATE = "Substitution Filter Update"; private static final String UPDATE_SUBSTITUTION_FILTER_WITH_AN_ERROR = "Update substitution filter with an error {}"; private static final String FAILED_TO_DELETE_SUBSTITUTION_FILTER = "Failed to delete substitution filter"; private static final String SUBSTITUTION_FILTER_DELETE = "Substitution Filter Delete"; private static final String DELETE_SUBSTITUTION_FILTER_WITH_AN_ERROR = "Delete substitution filter with an error"; + private static final List<ComponentTypeEnum> EXPECTED_COMPONENT_TYPES = List.of(ComponentTypeEnum.SERVICE, ComponentTypeEnum.RESOURCE); + private static final String EXPECTED_COMPONENT_TYPES_AS_STRING = EXPECTED_COMPONENT_TYPES.stream() + .map(ComponentTypeEnum::findParamByType) + .collect(Collectors.joining(", ")); private final ComponentSubstitutionFilterBusinessLogic componentSubstitutionFilterBusinessLogic; @Inject @@ -125,21 +131,22 @@ public class ComponentSubstitutionFilterServlet extends AbstractValidationsServl LOGGER.error(FAILED_TO_PARSE_COMPONENT); return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); } - final UIConstraint uiConstraint = convertResponse.get(); - final String constraint = new ConstraintConvertor().convert(uiConstraint); + final FilterConstraintDto filterConstraintDto = new FilterConstraintMapper().mapFrom(convertResponse.get()); final Optional<NodeFilterConstraintType> nodeFilterConstraintType = NodeFilterConstraintType.parse(constraintType); if (nodeFilterConstraintType.isEmpty()) { return buildErrorResponse( getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT_PARAM, INVALID_CONSTRAINTYPE_ENUM, constraintType)); } final Optional<SubstitutionFilterDataDefinition> actionResponse = componentSubstitutionFilterBusinessLogic - .addSubstitutionFilter(componentId.toLowerCase(), uiConstraint.getServicePropertyName(), constraint, true, componentTypeEnum); + .addSubstitutionFilter(componentId.toLowerCase(), filterConstraintDto, true, componentTypeEnum); if (actionResponse.isEmpty()) { LOGGER.error(FAILED_TO_ADD_SUBSTITUTION_FILTER); return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); } final UINodeFilter uiFilter = new SubstitutionFilterConverter().convertToUi(actionResponse.get()); return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), uiFilter); + } catch (final BusinessLogicException e) { + return buildErrorResponse(e.getResponseFormat()); } catch (final Exception e) { BeEcompErrorManager.getInstance().logBeRestApiGeneralError(ADD_SUBSTITUTION_FILTER); LOGGER.error(ADD_SUBSTITUTION_FILTER_WITH_AN_ERROR, e); @@ -156,11 +163,67 @@ public class ComponentSubstitutionFilterServlet extends AbstractValidationsServl @ApiResponse(responseCode = "403", description = "Restricted operation"), @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE) - public Response updateSubstitutionFilter(@Parameter(description = "UIConstraint data", required = true) String constraintData, + public Response updateSubstitutionFilters(@Parameter(description = "UIConstraint data", required = true) String constraintData, + @Parameter(description = "Component Id") @PathParam("componentId") String componentId, + @Parameter(description = "valid value: resources / services", schema = @Schema(allowableValues = { + ComponentTypeEnum.SERVICE_PARAM_NAME, + ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("componentType") final String componentType, + @Parameter(description = "Constraint type. Valid values: properties / capabilities", schema = @Schema(allowableValues = { + NodeFilterConstraintType.PROPERTIES_PARAM_NAME, + NodeFilterConstraintType.CAPABILITIES_PARAM_NAME})) @PathParam("constraintType") final String constraintType, + @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + LOGGER.debug(START_HANDLE_REQUEST_OF, request.getMethod(), request.getRequestURI()); + LOGGER.debug(MODIFIER_ID_IS, userId); + final User userModifier = componentSubstitutionFilterBusinessLogic.validateUser(userId); + try { + final ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); + final List<UIConstraint> uiConstraints = componentsUtils.validateAndParseConstraint(componentTypeEnum, constraintData, userModifier); + if (CollectionUtils.isEmpty(uiConstraints)) { + LOGGER.error("Failed to Parse Constraint data {} when executing {} ", constraintData, SUBSTITUTION_FILTER_UPDATE); + return buildErrorResponse(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR, "Failed to parse constraint data")); + } + final List<FilterConstraintDto> filterConstraintList = uiConstraints.stream() + .map(uiConstraint -> new FilterConstraintMapper().mapFrom(uiConstraint)) + .collect(Collectors.toList()); + final Optional<NodeFilterConstraintType> nodeFilterConstraintType = NodeFilterConstraintType.parse(constraintType); + if (nodeFilterConstraintType.isEmpty()) { + return buildErrorResponse( + getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT_PARAM, INVALID_CONSTRAINTYPE_ENUM, constraintType)); + } + final Optional<SubstitutionFilterDataDefinition> actionResponse = componentSubstitutionFilterBusinessLogic + .updateSubstitutionFilter(componentId.toLowerCase(), filterConstraintList, true, componentTypeEnum); + if (actionResponse.isEmpty()) { + LOGGER.error(FAILED_TO_UPDATE_SUBSTITUTION_FILTER); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), + new SubstitutionFilterConverter().convertToUi(actionResponse.get())); + } catch (final BusinessLogicException e) { + return buildErrorResponse(e.getResponseFormat()); + } catch (final Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(SUBSTITUTION_FILTER_UPDATE); + LOGGER.error(UPDATE_SUBSTITUTION_FILTER_WITH_AN_ERROR, e.getMessage(), e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @PUT + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/{constraintIndex}") + @Operation(description = "Update Component Substitution Filter Constraint", method = "PUT", summary = "Update Component Substitution Filter Constraint", responses = { + @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))), + @ApiResponse(responseCode = "201", description = "Update Substitution Filter Constraint"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")}) + @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE) + public Response updateSubstitutionFilter(@Parameter(description = "Filter constraint information", required = true) UIConstraint uiConstraint, + @Parameter(description = "Constraint Index") @PathParam("constraintIndex") int index, @Parameter(description = "Component Id") @PathParam("componentId") String componentId, - @Parameter(description = "valid value: resources / services", schema = @Schema(allowableValues = { + @Parameter(description = "The component type", schema = @Schema(allowableValues = { ComponentTypeEnum.SERVICE_PARAM_NAME, - ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("componentType") final String componentType, + ComponentTypeEnum.RESOURCE_PARAM_NAME})) @PathParam("componentType") final String componentType, @Parameter(description = "Constraint type. Valid values: properties / capabilities", schema = @Schema(allowableValues = { NodeFilterConstraintType.PROPERTIES_PARAM_NAME, NodeFilterConstraintType.CAPABILITIES_PARAM_NAME})) @PathParam("constraintType") final String constraintType, @@ -168,28 +231,32 @@ public class ComponentSubstitutionFilterServlet extends AbstractValidationsServl @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { LOGGER.debug(START_HANDLE_REQUEST_OF, request.getMethod(), request.getRequestURI()); LOGGER.debug(MODIFIER_ID_IS, userId); - final User userModifier = componentSubstitutionFilterBusinessLogic.validateUser(userId); + componentSubstitutionFilterBusinessLogic.validateUser(userId); try { final ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); - final List<UIConstraint> uiConstraints = componentsUtils.validateAndParseConstraint(componentTypeEnum, constraintData, userModifier); - if (CollectionUtils.isEmpty(uiConstraints)) { - LOGGER.error("Failed to Parse Constraint data {} when executing {} ", constraintData, SUBSTITUTION_FILTER_UPDATE); - return buildErrorResponse(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR, "Failed to parse constraint data")); + if (componentTypeEnum == null || !EXPECTED_COMPONENT_TYPES.contains(componentTypeEnum)) { + return buildErrorResponse( + getComponentsUtils().getResponseFormat(ActionStatus.INVALID_COMPONENT_TYPE, componentType, EXPECTED_COMPONENT_TYPES_AS_STRING)); } - final List<String> constraints = new ConstraintConvertor().convertToList(uiConstraints); final Optional<NodeFilterConstraintType> nodeFilterConstraintType = NodeFilterConstraintType.parse(constraintType); - if (!nodeFilterConstraintType.isPresent()) { + if (nodeFilterConstraintType.isEmpty()) { return buildErrorResponse( getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT_PARAM, INVALID_CONSTRAINTYPE_ENUM, constraintType)); } + final FilterConstraintDto filterConstraintDto = new FilterConstraintMapper().mapFrom(uiConstraint); + final Optional<SubstitutionFilterDataDefinition> actionResponse = componentSubstitutionFilterBusinessLogic - .updateSubstitutionFilter(componentId.toLowerCase(), constraints, true, componentTypeEnum); - if (!actionResponse.isPresent()) { + .updateSubstitutionFilter(componentId.toLowerCase(), filterConstraintDto, index , true); + if (actionResponse.isEmpty()) { LOGGER.error(FAILED_TO_UPDATE_SUBSTITUTION_FILTER); return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); } return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), new SubstitutionFilterConverter().convertToUi(actionResponse.get())); + } catch (final BusinessLogicException e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(SUBSTITUTION_FILTER_UPDATE); + LOGGER.error(UPDATE_SUBSTITUTION_FILTER_WITH_AN_ERROR, e.getMessage(), e); + return buildErrorResponse(e.getResponseFormat()); } catch (final Exception e) { BeEcompErrorManager.getInstance().logBeRestApiGeneralError(SUBSTITUTION_FILTER_UPDATE); LOGGER.error(UPDATE_SUBSTITUTION_FILTER_WITH_AN_ERROR, e.getMessage(), e); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java index 25d0287d54..f3327d7206 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java @@ -71,11 +71,13 @@ import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition; import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyFilterConstraintDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyFilterDataDefinition; import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterCapabilityDataDefinition; -import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition; -import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterPropertyDataDefinition; import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterPropertyDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ToscaArtifactDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ToscaFunction; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields; import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum; @@ -1044,11 +1046,10 @@ public class ToscaExportHandler { private Object convertToToscaObject(String value) { try { ToscaMapValueConverter mapConverterInst = ToscaMapValueConverter.getInstance(); - JsonParser jsonParser = new JsonParser(); StringReader reader = new StringReader(value); JsonReader jsonReader = new JsonReader(reader); jsonReader.setLenient(true); - JsonElement jsonElement = jsonParser.parse(jsonReader); + JsonElement jsonElement = JsonParser.parseReader(jsonReader); if (jsonElement.isJsonObject()) { JsonObject jsonObj = jsonElement.getAsJsonObject(); if (jsonObj.entrySet().size() == 1 && jsonObj.has(ToscaFunctions.GET_INPUT.getFunctionName())) { @@ -1613,14 +1614,13 @@ public class ToscaExportHandler { } NodeFilter nodeFilter = new NodeFilter(); ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> origCapabilities = inNodeFilter.getCapabilities(); - ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> origProperties = inNodeFilter.getProperties(); + ListDataDefinition<PropertyFilterDataDefinition> origProperties = inNodeFilter.getProperties(); List<Map<String, CapabilityFilter>> capabilitiesCopy = new ArrayList<>(); - List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>(); copyNodeFilterCapabilitiesTemplate(origCapabilities, capabilitiesCopy); - copyNodeFilterProperties(origProperties, propertiesCopy); if (CollectionUtils.isNotEmpty(capabilitiesCopy)) { nodeFilter.setCapabilities(capabilitiesCopy); } + final List<Map<String, List<Object>>> propertiesCopy = copyNodeFilterProperties(origProperties); if (CollectionUtils.isNotEmpty(propertiesCopy)) { nodeFilter.setProperties(propertiesCopy); } @@ -1634,10 +1634,8 @@ public class ToscaExportHandler { return null; } NodeFilter nodeFilter = new NodeFilter(); - ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> origProperties = substitutionFilterDataDefinition.getProperties(); - List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>(); - copySubstitutionFilterProperties(origProperties, propertiesCopy); - if (CollectionUtils.isNotEmpty(propertiesCopy)) { + final List<Map<String, List<Object>>> propertiesCopy = copySubstitutionPropertiesFilter(substitutionFilterDataDefinition.getProperties()); + if (!propertiesCopy.isEmpty()) { nodeFilter.setProperties(propertiesCopy); } nodeFilter.setTosca_id(cloneToscaId(substitutionFilterDataDefinition.getTosca_id())); @@ -1661,81 +1659,71 @@ public class ToscaExportHandler { } for (RequirementNodeFilterCapabilityDataDefinition capability : origCapabilities.getListToscaDataDefinition()) { Map<String, CapabilityFilter> capabilityFilterCopyMap = new HashMap<>(); - CapabilityFilter capabilityFilter = new CapabilityFilter(); - List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>(); - copyNodeFilterProperties(capability.getProperties(), propertiesCopy); - capabilityFilter.setProperties(propertiesCopy); + final var capabilityFilter = new CapabilityFilter(); + capabilityFilter.setProperties(copyNodeFilterProperties(capability.getProperties())); capabilityFilterCopyMap.put(capability.getName(), capabilityFilter); capabilitiesCopy.add(capabilityFilterCopyMap); } } - private void copyNodeFilterProperties(ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> origProperties, - List<Map<String, List<Object>>> propertiesCopy) { + private List<Map<String, List<Object>>> copyNodeFilterProperties(final ListDataDefinition<PropertyFilterDataDefinition> origProperties) { if (origProperties == null || origProperties.getListToscaDataDefinition() == null || origProperties.isEmpty()) { - return; + return Collections.emptyList(); } - Map<String, List<Object>> propertyMapCopy = new HashMap<>(); - for (RequirementNodeFilterPropertyDataDefinition propertyDataDefinition : origProperties.getListToscaDataDefinition()) { - for (String propertyInfoEntry : propertyDataDefinition.getConstraints()) { - Map<String, List<Object>> propertyValObj = new YamlUtil().yamlToObject(propertyInfoEntry, Map.class); - String propertyName = propertyDataDefinition.getName(); - if (propertyMapCopy.containsKey(propertyName)) { - addPropertyConstraintValueToList(propertyName, propertyValObj, propertyMapCopy.get(propertyName)); - } else { - if (propertyName != null) { - List<Object> propsList = new ArrayList<>(); - addPropertyConstraintValueToList(propertyName, propertyValObj, propsList); - propertyMapCopy.put(propertyName, propsList); - } else { - propertyMapCopy.putAll(propertyValObj); + List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>(); + Map<String, List<Object>> propertyFilterDefinitionMap = new HashMap<>(); + for (final PropertyFilterDataDefinition propertyFilter : origProperties.getListToscaDataDefinition()) { + final String propertyName = propertyFilter.getName(); + for (final PropertyFilterConstraintDataDefinition filterConstraint : propertyFilter.getConstraints()) { + propertyFilterDefinitionMap.compute(propertyName, (propertyName1, constraints) -> { + if (constraints == null) { + constraints = new ArrayList<>(); } - } + constraints.add(buildNodeFilterValue(filterConstraint)); + return constraints; + }); } } - propertyMapCopy.entrySet().stream().forEach(entry -> addCalculatedConstraintsIntoPropertiesList(propertiesCopy, entry)); + propertyFilterDefinitionMap.entrySet().stream() + .map(entry -> Map.of(entry.getKey(), entry.getValue())) + .forEach(propertiesCopy::add); + return propertiesCopy; } - private void copySubstitutionFilterProperties(final ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> origProperties, - final List<Map<String, List<Object>>> propertiesCopy) { + private List<Map<String, List<Object>>> copySubstitutionPropertiesFilter( + final ListDataDefinition<SubstitutionFilterPropertyDataDefinition> origProperties) { + if (origProperties == null || origProperties.getListToscaDataDefinition() == null || origProperties.isEmpty()) { - return; + return Collections.emptyList(); } - final Map<String, List<Object>> propertyMapCopy = new HashMap<>(); - for (final RequirementSubstitutionFilterPropertyDataDefinition propertyDataDefinition : origProperties.getListToscaDataDefinition()) { - for (final String propertyInfoEntry : propertyDataDefinition.getConstraints()) { - final Map<String, List<Object>> propertyValObj = new YamlUtil().yamlToObject(propertyInfoEntry, Map.class); - final String propertyName = propertyDataDefinition.getName(); - if (propertyMapCopy.containsKey(propertyName)) { - addPropertyConstraintValueToList(propertyName, propertyValObj, propertyMapCopy.get(propertyName)); - } else { - if (propertyName != null) { - final List<Object> propsList = new ArrayList<>(); - addPropertyConstraintValueToList(propertyName, propertyValObj, propsList); - propertyMapCopy.put(propertyName, propsList); - } else { - propertyMapCopy.putAll(propertyValObj); + List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>(); + Map<String, List<Object>> propertyFilterDefinitionMap = new HashMap<>(); + for (final SubstitutionFilterPropertyDataDefinition propertyFilter : origProperties.getListToscaDataDefinition()) { + final String propertyName = propertyFilter.getName(); + for (final PropertyFilterConstraintDataDefinition filterConstraint : propertyFilter.getConstraints()) { + propertyFilterDefinitionMap.compute(propertyName, (propertyName1, constraints) -> { + if (constraints == null) { + constraints = new ArrayList<>(); } - } + constraints.add(buildNodeFilterValue(filterConstraint)); + return constraints; + }); } } - propertyMapCopy.entrySet().forEach(entry -> addCalculatedConstraintsIntoPropertiesList(propertiesCopy, entry)); + propertyFilterDefinitionMap.entrySet().stream() + .map(entry -> Map.of(entry.getKey(), entry.getValue())) + .forEach(propertiesCopy::add); + return propertiesCopy; } - private void addPropertyConstraintValueToList(String propertyName, Map<String, List<Object>> propertyValObj, List<Object> propsList) { - if (propertyValObj.containsKey(propertyName)) { - propsList.add(propertyValObj.get(propertyName)); + private static Object buildNodeFilterValue(final PropertyFilterConstraintDataDefinition filterConstraint) { + if (filterConstraint.getValue() instanceof ToscaFunction) { + return Map.of(filterConstraint.getOperator().getType(), ((ToscaFunction) filterConstraint.getValue()).getJsonObjectValue()); } else { - propsList.add(propertyValObj); + return Map.of(filterConstraint.getOperator().getType(), filterConstraint.getValue()); } } - private void addCalculatedConstraintsIntoPropertiesList(List<Map<String, List<Object>>> propertiesCopy, Entry<String, List<Object>> entry) { - Map<String, List<Object>> tempMap = new HashMap<>(); - tempMap.put(entry.getKey(), entry.getValue()); - propertiesCopy.add(tempMap); - } - private Map<String, String[]> buildSubstitutionMappingPropertyMapping(final Component component) { if (component == null || CollectionUtils.isEmpty(component.getInputs())) { return Collections.emptyMap(); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaPropertyConstraint.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaPropertyConstraint.java index ab1137342d..6049be2fd6 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaPropertyConstraint.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaPropertyConstraint.java @@ -18,7 +18,7 @@ */ package org.openecomp.sdc.be.tosca.model; -import org.openecomp.sdc.be.model.tosca.constraints.ConstraintType; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; /** * Represents a Tosca Property Constraint diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaPropertyConstraintValidValues.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaPropertyConstraintValidValues.java index e7bade9421..8e73f6985b 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaPropertyConstraintValidValues.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaPropertyConstraintValidValues.java @@ -22,7 +22,7 @@ import java.util.List; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; -import org.openecomp.sdc.be.model.tosca.constraints.ConstraintType; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; /** * Represents a tosca valid_values constraint diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/NodeFilterConverter.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/NodeFilterConverter.java index 48932fefd7..6ef6c0dc3c 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/NodeFilterConverter.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/NodeFilterConverter.java @@ -19,11 +19,12 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; -import org.openecomp.sdc.be.datamodel.utils.ConstraintConvertor; import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyFilterDataDefinition; import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterCapabilityDataDefinition; -import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition; +import org.openecomp.sdc.be.model.dto.FilterConstraintDto; +import org.openecomp.sdc.be.ui.mapper.FilterConstraintMapper; import org.openecomp.sdc.be.ui.model.UIConstraint; import org.openecomp.sdc.be.ui.model.UINodeFilter; @@ -35,36 +36,38 @@ public class NodeFilterConverter { public UINodeFilter convertToUi(final CINodeFilterDataDefinition inNodeFilter) { final UINodeFilter uiNodeFilter = new UINodeFilter(); - final ConstraintConvertor constraintConvertor = new ConstraintConvertor(); - final ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> nodeFilterProperties = inNodeFilter.getProperties(); + + final ListDataDefinition<PropertyFilterDataDefinition> nodeFilterProperties = inNodeFilter.getProperties(); if (nodeFilterProperties != null && !nodeFilterProperties.isEmpty()) { - final List<UIConstraint> propertiesConstraint = nodeFilterProperties.getListToscaDataDefinition().stream().map(property -> { - if(property.getType() != null) { - return constraintConvertor.convert(property.getConstraints().iterator().next(), property.getType()); - } else { - return constraintConvertor.convert(property.getConstraints().iterator().next()); - }}).collect(Collectors.toList()); + final var filterConstraintMapper = new FilterConstraintMapper(); + final List<UIConstraint> propertiesConstraint = nodeFilterProperties.getListToscaDataDefinition().stream() + .map(property -> property.getConstraints().iterator().next()) + .map(filterConstraintMapper::mapFrom) + .map(filterConstraintMapper::mapToUiConstraint) + .collect(Collectors.toList()); uiNodeFilter.setProperties(propertiesConstraint); } final ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> nodeFilterCapabilities = inNodeFilter.getCapabilities(); if (nodeFilterCapabilities != null && !nodeFilterCapabilities.isEmpty()) { final List<UIConstraint> capabilitiesConstraint = new ArrayList<>(); - nodeFilterCapabilities.getListToscaDataDefinition().forEach( - requirementNodeFilterCapabilityDataDefinition -> convertCapabilityConstraint(requirementNodeFilterCapabilityDataDefinition, - capabilitiesConstraint)); + nodeFilterCapabilities.getListToscaDataDefinition() + .forEach(requirementNodeFilterCapabilityDataDefinition -> + capabilitiesConstraint.addAll(convertCapabilityConstraint(requirementNodeFilterCapabilityDataDefinition)) + ); uiNodeFilter.setCapabilities(capabilitiesConstraint); } return uiNodeFilter; } - private void convertCapabilityConstraint(final RequirementNodeFilterCapabilityDataDefinition requirementNodeFilterCapabilityDataDefinition, - final List<UIConstraint> capabilitiesConstraint) { - final ConstraintConvertor constraintConvertor = new ConstraintConvertor(); - requirementNodeFilterCapabilityDataDefinition.getProperties().getListToscaDataDefinition().forEach(property -> { + private List<UIConstraint> convertCapabilityConstraint(final RequirementNodeFilterCapabilityDataDefinition nodeFilterCapability) { + final var filterConstraintMapper = new FilterConstraintMapper(); + final List<UIConstraint> uiConstraints = new ArrayList<>(); + nodeFilterCapability.getProperties().getListToscaDataDefinition().forEach(property -> { final UIConstraint uiConstraint = new UIConstraint(); - uiConstraint.setCapabilityName(requirementNodeFilterCapabilityDataDefinition.getName()); - capabilitiesConstraint.add( - constraintConvertor.getUiConstraint(property.getConstraints().iterator().next(), uiConstraint)); + uiConstraint.setCapabilityName(nodeFilterCapability.getName()); + final FilterConstraintDto filterConstraintDto = filterConstraintMapper.mapFrom(property.getConstraints().iterator().next()); + uiConstraints.add(filterConstraintMapper.mapToUiConstraint(filterConstraintDto)); }); + return uiConstraints; } } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/SubstitutionFilterConverter.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/SubstitutionFilterConverter.java index c083099629..562e4ea8fd 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/SubstitutionFilterConverter.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/SubstitutionFilterConverter.java @@ -22,11 +22,11 @@ import java.util.Collections; import java.util.List; import java.util.stream.Collectors; import org.apache.commons.collections.CollectionUtils; -import org.openecomp.sdc.be.datamodel.utils.ConstraintConvertor; import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterCapabilityDataDefinition; -import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterPropertyDataDefinition; import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterPropertyDataDefinition; +import org.openecomp.sdc.be.ui.mapper.FilterConstraintMapper; import org.openecomp.sdc.be.ui.model.UIConstraint; import org.openecomp.sdc.be.ui.model.UINodeFilter; @@ -34,39 +34,45 @@ public class SubstitutionFilterConverter { public UINodeFilter convertToUi(final SubstitutionFilterDataDefinition inSubstitutionFilter) { final UINodeFilter uiNodeFilter = new UINodeFilter(); - final ConstraintConvertor constraintConvertor = new ConstraintConvertor(); - final List<UIConstraint> uiPropertyFilters = extractPropertyFilter(inSubstitutionFilter, constraintConvertor); + + final List<UIConstraint> uiPropertyFilters = extractPropertyFilter(inSubstitutionFilter); if (!uiPropertyFilters.isEmpty()) { uiNodeFilter.setProperties(uiPropertyFilters); } - final List<UIConstraint> uiCapabilityFilters = extractCapabilitiesFilter(inSubstitutionFilter, constraintConvertor); + final List<UIConstraint> uiCapabilityFilters = extractCapabilitiesFilter(inSubstitutionFilter); if (!uiCapabilityFilters.isEmpty()) { uiNodeFilter.setCapabilities(uiCapabilityFilters); } return uiNodeFilter; } - private List<UIConstraint> extractPropertyFilter(final SubstitutionFilterDataDefinition substitutionFilter, - final ConstraintConvertor constraintConvertor) { - final ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> substitutionFilterProperties = substitutionFilter + private List<UIConstraint> extractPropertyFilter(final SubstitutionFilterDataDefinition substitutionFilter) { + final ListDataDefinition<SubstitutionFilterPropertyDataDefinition> substitutionFilterProperties = substitutionFilter .getProperties(); if (substitutionFilterProperties != null && !substitutionFilterProperties.isEmpty() && CollectionUtils .isNotEmpty(substitutionFilterProperties.getListToscaDataDefinition())) { - return substitutionFilterProperties.getListToscaDataDefinition().stream().map(property -> property.getConstraints().iterator().next()) - .map(constraintConvertor::convert).collect(Collectors.toList()); + final var filterConstraintMapper = new FilterConstraintMapper(); + return substitutionFilterProperties.getListToscaDataDefinition().stream() + .map(property -> property.getConstraints().iterator().next()) + .map(filterConstraintMapper::mapFrom) + .map(filterConstraintMapper::mapToUiConstraint) + .collect(Collectors.toList()); } return Collections.emptyList(); } - private List<UIConstraint> extractCapabilitiesFilter(final SubstitutionFilterDataDefinition substitutionFilter, - final ConstraintConvertor constraintConvertor) { + private List<UIConstraint> extractCapabilitiesFilter(final SubstitutionFilterDataDefinition substitutionFilter) { final ListDataDefinition<RequirementSubstitutionFilterCapabilityDataDefinition> substitutionFilterCapabilities = substitutionFilter .getCapabilities(); if (substitutionFilterCapabilities != null && !substitutionFilterCapabilities.isEmpty() && CollectionUtils .isNotEmpty(substitutionFilterCapabilities.getListToscaDataDefinition())) { + final var filterConstraintMapper = new FilterConstraintMapper(); return substitutionFilterCapabilities.getListToscaDataDefinition().stream() .map(capabilities -> capabilities.getProperties().getListToscaDataDefinition().iterator().next()) - .map(property -> property.getConstraints().iterator().next()).map(constraintConvertor::convert).collect(Collectors.toList()); + .map(property -> property.getConstraints().iterator().next()) + .map(filterConstraintMapper::mapFrom) + .map(filterConstraintMapper::mapToUiConstraint) + .collect(Collectors.toList()); } return Collections.emptyList(); } diff --git a/catalog-be/src/main/resources/config/error-configuration.yaml b/catalog-be/src/main/resources/config/error-configuration.yaml index 96bfa245e3..81e302f8bd 100644 --- a/catalog-be/src/main/resources/config/error-configuration.yaml +++ b/catalog-be/src/main/resources/config/error-configuration.yaml @@ -111,7 +111,7 @@ errors: message: "Error: Invalid userId '%1'.", messageId: "SVC4008" } -#---------SVC4009----------------------------- + #---------SVC4009----------------------------- USER_DEFINED: { code: 400, message: "Error: User Defined '%1'.", @@ -1436,10 +1436,10 @@ errors: message: "Error: artifact %1 is defined in CSAR %2 manifest but is not provided", messageId: "SVC4618" } -#---------SVC4619------------------------------ -# %1 - artifact name -# %2 - artifact type -# %3 - existing artifact type + #---------SVC4619------------------------------ + # %1 - artifact name + # %2 - artifact type + # %3 - existing artifact type ARTIFACT_ALREADY_EXIST_IN_DIFFERENT_TYPE_IN_CSAR: { code: 400, message: "Error: artifact %1 in type %2 already exists in type %3.", @@ -1803,9 +1803,11 @@ errors: messageId: "SVC4669" } #---------SVC4670------------------------------ + # %1 - artifactname + # %2 - validname ARTIFACT_NAME_INVALID: { code: 400, - message: "Error: Artifact name is invalid.", + message: "Error: Artifact name '%1' is invalid. Only the following characters are allowed in the Artifact Name: '%2'.", messageId: "SVC4670" } #---------SVC4671------------------------------ @@ -2010,29 +2012,29 @@ errors: #---------SVC4695----------------------------- # %1 - Interface Operation Name INTERFACE_OPERATION_NAME_ALREADY_IN_USE: { - code: 409, - message: "Error: Interface Operation name '%1' already in use, Your current changes will not be saved.", - messageId: "SVC4695" + code: 409, + message: "Error: Interface Operation name '%1' already in use, Your current changes will not be saved.", + messageId: "SVC4695" } #---------SVC4696----------------------------- # %1 - Interface Operation Name INTERFACE_OPERATION_NAME_INVALID: { - code: 400, - message: "Error: Interface Operation name '%1' is Invalid, Operation name should not contain special character, space and should not be greater than 200 characters.", - messageId: "SVC4696" + code: 400, + message: "Error: Interface Operation name '%1' is Invalid, Operation name should not contain special character, space and should not be greater than 200 characters.", + messageId: "SVC4696" } #---------SVC4697----------------------------- INTERFACE_OPERATION_NAME_MANDATORY: { - code: 400, - message: "Error: Interface Operation name is mandatory, Operation name can't be empty.", - messageId: "SVC4697" + code: 400, + message: "Error: Interface Operation name is mandatory, Operation name can't be empty.", + messageId: "SVC4697" } -#---------SVC4698----------------------------- -# %1 - Interface type + #---------SVC4698----------------------------- + # %1 - Interface type INTERFACE_OPERATION_INVALID_FOR_LOCAL_TYPE: { - code: 400, - message: "Error: Invalid input, only one operation is allowed in local interface type '%1'.", - messageId: "SVC4698" + code: 400, + message: "Error: Invalid input, only one operation is allowed in local interface type '%1'.", + messageId: "SVC4698" } #---------SVC4699----------------------------- # %1 - Interface Operation input parameter name @@ -2047,18 +2049,18 @@ errors: message: "Error: Interface operation input parameter name should not be empty.", messageId: "SVC4700" } -#---------SVC4701----------------------------- -# %1 - component Id + #---------SVC4701----------------------------- + # %1 - component Id INTERFACE_OPERATION_NOT_FOUND: { - code: 404, - message: "Error: Interface operation not found in the component '%1'.", - messageId: "SVC4701" + code: 404, + message: "Error: Interface operation not found in the component '%1'.", + messageId: "SVC4701" } #---------SVC4702----------------------------- INTERFACE_OPERATION_NOT_DELETED: { - code: 400, - message: "Error: Failed to delete interface operation.", - messageId: "SVC4702" + code: 400, + message: "Error: Failed to delete interface operation.", + messageId: "SVC4702" } #SVC4732 INTERFACE_UNKNOWN: { @@ -2129,32 +2131,32 @@ errors: message: "Error: CSAR packaging failed for %1 %2.", messageId: "SVC4706" } -#---------SVC4708----------------------------- -# %1 - Interface Operation input property name, component type + #---------SVC4708----------------------------- + # %1 - Interface Operation input property name, component type INTERFACE_OPERATION_INPUT_PROPERTY_NOT_FOUND_IN_COMPONENT: { code: 404, message: "Error: Interface operation input parameter property '%1' not found in '%2' input properties, capability properties or outputs of other operations.", messageId: "SVC4708" } -#---------SVC4709----------------------------- -# %1 - Interface Operation output parameter name + #---------SVC4709----------------------------- + # %1 - Interface Operation output parameter name INTERFACE_OPERATION_OUTPUT_NAME_ALREADY_IN_USE: { code: 400, message: "Error: Interface Operation output parameter name '%1' already in use, Your current changes will not be saved.", messageId: "SVC4708" } -#---------SVC4710----------------------------- + #---------SVC4710----------------------------- INTERFACE_OPERATION_OUTPUT_NAME_MANDATORY: { code: 400, message: "Error: Interface operation output parameter name should not be empty.", messageId: "SVC4710" } -#---------SVC4711----------------------------- -# %1 - interface Id + #---------SVC4711----------------------------- + # %1 - interface Id INTERFACE_NOT_FOUND_IN_COMPONENT: { - code: 404, - message: "Error: Interface not found in the component '%1'.", - messageId: "SVC4711" + code: 404, + message: "Error: Interface not found in the component '%1'.", + messageId: "SVC4711" } #---------SVC4709----------------------------- INVALID_PROPERTY_CONSTRAINTS: { @@ -2266,18 +2268,18 @@ errors: message: "Error: Missing value for the mandatory %1 property" , messageId: "SVC4721" } -#---------SVC4712----------------------------- + #---------SVC4712----------------------------- INTERFACE_LIFECYCLE_TYPES_NOT_FOUND: { - code: 404, - message: "Error: Interface Lifecycle types not found.", - messageId: "SVC4712" + code: 404, + message: "Error: Interface Lifecycle types not found.", + messageId: "SVC4712" } -#---------SVC4713----------------------------- -# %1 - Interface Operation Name + #---------SVC4713----------------------------- + # %1 - Interface Operation Name INTERFACE_OPERATION_INVALID_FOR_GLOBAL_TYPE: { - code: 400, - message: "Error: Invalid input, only pre-defined operation names are allowed in global interface type '%1'", - messageId: "SVC4713" + code: 400, + message: "Error: Invalid input, only pre-defined operation names are allowed in global interface type '%1'", + messageId: "SVC4713" } #---------SVC4714----------------------------- @@ -2300,13 +2302,14 @@ errors: messageId: "SVC4716" } - #---------SVC4717---------------------------- - # %1 - Property Name - MAPPED_PROPERTY_NOT_FOUND: { - code: 400, - message: "Error: %1 property does not exist.", - messageId: "SVC4717" - } + #---------SVC4184---------------------------- + # %1 - Source type + # %2 - Property Type + # %3 - Property Name + FILTER_PROPERTY_NOT_FOUND: + code: 400 + message: "%1 %2 %3 does not exist." + messageId: "SVC4184" #---------SVC4718---------------------------- # %1 - Property Name @@ -2324,13 +2327,13 @@ errors: messageId: "SVC4719" } - #---------SVC4720---------------------------- + #---------SVC4182---------------------------- # %1 - Property Name # %2 - Operator Type SOURCE_TARGET_PROPERTY_TYPE_MISMATCH: { code: 400, - message: "Error: %1 property and %2 property type is not same.", - messageId: "SVC4720" + message: "Error: Property '%1' type '%2' does not match with property '%3' type '%4'.", + messageId: "SVC4182" } #---------SVC4721---------------------------- @@ -2342,78 +2345,471 @@ errors: messageId: "SVC4721" } - #---------SVC4722------------------------------ - # %1 Directive value set + #---------SVC4722------------------------------ + # %1 Directive value set DIRECTIVES_INVALID_VALUE: { - code: 404, - message: "Error: Invalid directive value : '%1' .", - messageId: "SVC4722" + code: 404, + message: "Error: Invalid directive value : '%1' .", + messageId: "SVC4722" } -#---------SVC4723----------------------------- -# %1 - Interface Operation output name + #---------SVC4723----------------------------- + # %1 - Interface Operation output name INTERFACE_OPERATION_MAPPED_OUTPUT_MODIFIED: { code: 400, message: "Error: Cannot update or delete interface operation output(s) '%1' mapped to an operation input", messageId: "SVC4723" } -#---------SVC4724----------------------------- -# %1 - Interface Operation output name + #---------SVC4724----------------------------- + # %1 - Interface Operation output name INTERFACE_OPERATION_DELETE_WITH_MAPPED_OUTPUT: { code: 400, message: "Error: Cannot delete interface operation with output(s) '%1' mapped to another operation input", messageId: "SVC4724" } -#---------SVC4725----------------------------- + #---------SVC4725----------------------------- INVALID_CONSUMPTION_TYPE: { code: 400, message: "Error: Given value is different than input type. Needs to be %1", messageId: "SVC4725" } -#---------SVC4726----------------------------- + #---------SVC4726----------------------------- INVALID_PROPERTY_VALUES: { code: 400, message: "Error: Invalid property values provided:\n %1", messageId: "SVC4726" } -#---------SVC4727------------------------------ + #---------SVC4727------------------------------ INVALID_PROPERTY_NAME: { code: 400, message: "Error: Property name contains invalid characters. It should have only letters, numbers and underscores.", messageId: "SVC4727" } -#---------SVC4728------------------------------ + #---------SVC4728------------------------------ FAILED_TO_CREATE_OR_UPDATE_CAPABILITY_PROPERTIES: { code: 500, message: "Error: Failed to create or update capabilities properties", messageId: "SVC4728" } -#---------SVC4729------------------------------ + #---------SVC4729------------------------------ # %1 - resource Id CAPABILITY_PROPERTIES_NOT_FOUND: { code: 400, message: "Error: Capability properties not found in the resource '%1'.", messageId: "SVC4729" } -#---------SVC4730------------------------------ + #---------SVC4730------------------------------ # %1 - property name PROPERTY_EXCEEDS_LIMIT: { - code: 400, - message: "Error: Invalid Content. %1 exceeds limit.", - messageId: "SVC4722" + code: 400, + message: "Error: Invalid Content. %1 exceeds limit.", + messageId: "SVC4722" } -#---------SVC4731------------------------------ + #---------SVC4731------------------------------ INVALID_PROPERY: { # %1 - property name - code: 400, - message: 'Error: Invalid Content. %1 has invalid format.', - messageId: "SVC4723" + code: 400, + message: 'Error: Invalid Content. %1 has invalid format.', + messageId: "SVC4723" } -#---------SVC4732------------------------------ + #---------SVC4734------------------------------ # %1 - list of validation errors INVALID_PM_DICTIONARY_FILE: { code: 400, message: 'Error: Invalid PM Dictionary File. %1', - messageId: "SVC4732" - }
\ No newline at end of file + messageId: "SVC4734" + } + #-----------SVC4735--------------------------- + #%1 - input name + INPUT_ALREADY_EXIST: { + code: 409, + message: "Error: Input with '%1' name already exists.", + messageId: "SVC4735" + } + #---------SVC4736------------------------------ + INVALID_INPUT_NAME: { + code: 400, + message: "Error: Input name contains invalid characters. It should have only letters, numbers and underscores.", + messageId: "SVC4736" + } + #---------SVC4139------------------------------ + # %1 - The action that is not supported + NOT_SUPPORTED: { + code: 400, + message: '%1 is not yet supported', + messageId: "SVC4139" + } + #---------SVC4140------------------------------ + # %1 - Component uid + COMPONENT_FIND_ERROR: { + code: 500, + message: "An unexpected error occurred while retrieving the component '%1'.", + messageId: "SVC4140" + } + #---------SVC4141------------------------------ + # %1 - Component uid + COMPONENT_CAPABILITIES_FIND_ERROR: { + code: 500, + message: "An unexpected error occurred while retrieving the component '%1' capabilities.", + messageId: "SVC4141" + } + #---------SVC4142------------------------------ + # %1 - Component uid or name + COMPONENT_NOT_FOUND: { + code: 404, + message: "Component '%1' was not found.", + messageId: "SVC4142" + } + #---------SVC4143------------------------------ + # %1 - Capability name + COMPONENT_INSTANCE_CAPABILITY_UPDATE_ERROR: { + code: 500, + message: "An unexpected error occurred while updating the capability '%1'.", + messageId: "SVC4143" + } + + #---------SVC4144------------------------------ + # %1 - "Model name" + MODEL_ALREADY_EXISTS: { + code: 409, + message: "Error: Model name '%1' already exists.", + messageId: "SVC4144" + } + + #---------SVC4145------------------------------ + # %1 - "Model name" + INVALID_MODEL: { + code: 400, + message: "Invalid model '%1'.", + messageId: "SVC4145" + } + + #---------SVC4146------------------------------ + MODEL_IMPORTS_IS_EMPTY: { + code: 400, + message: "Given model imports zip is empty.", + messageId: "SVC4146" + } + + #---------SVC4147------------------------------ + COULD_NOT_READ_MODEL_IMPORTS: { + code: 400, + message: "Could not read imports zip.", + messageId: "SVC4147" + } + + #---------SVC4148------------------------------ + # %1 - "Model name" + MODEL_NOT_FOUND: { + code: 404, + message: "Error: Model name '%1' not found. Please, make sure the model is created.", + messageId: "SVC4148" + } + + #---------SVC4149------------------------------ + MODEL_NAME_CANNOT_BE_EMPTY: { + code: 409, + message: "Error: Model name cannot be empty.", + messageId: "SVC4149" + } + + #-----------SVC4150--------------------------- + # %1 - "Component name" + # %2 - "Model name" + COMPONENT_WITH_MODEL_ALREADY_EXIST: { + code: 409, + message: "Error: Component %1 with Model %2 already exist.", + messageId: "SVC4150" + } + #-----------SVC4151--------------------------- + # %1 - "Component name" + # %2 - "Vendor release" + # %3 - "Model name" + COMPONENT_WITH_VENDOR_RELEASE_ALREADY_EXISTS_IN_MODEL: { + code: 409, + message: "Error: Component '%1' with Vendor Release '%2' already exists in Model '%3'.", + messageId: "SVC4151" + } + #-----------SVC4152--------------------------- + # %1 - "Component name" + # %2 - "Vendor release" + COMPONENT_WITH_VENDOR_RELEASE_ALREADY_EXISTS: { + code: 409, + message: "Error: Component '%1' with Vendor Release '%2' already exists.", + messageId: "SVC4152" + } + + #-----------SVC4153--------------------------- + # %1 - "Model name" + DATA_TYPES_NOT_LOADED: { + code: 500, + message: "Could not fetch data types from data base with model %1", + messageId: "SVC4153" + } + + #-----------SVC4154--------------------------- + # %1 - "Model name" + UNKNOWN_MODEL_TYPE: { + code: 400, + message: "Error: Model type %1 not known in the system", + messageId: "SVC4154" + } + + #-----------SVC4154--------------------------- + CSAR_TOSCA_IMPORTS_ERROR: { + code: 500, + message: "Error: An error has occurred while including the default TOSCA imports in the CSAR", + messageId: "SVC4154" + } + + #-----------SVC4155--------------------------- + # %1 - "VSP id" + # %2 - "VSP version id" + VSP_FIND_ERROR: { + code: 500, + message: "An error has occurred while retrieving the Vendor Software Product of id '%1', version id '%2'", + messageId: "SVC4155" + } + + #-----------SVC4156--------------------------- + # %1 - "VSP id" + # %2 - "VSP version id" + VSP_NOT_FOUND: { + code: 404, + message: "Could not find Vendor Software Product of id '%1', version id '%2'", + messageId: "SVC4156" + } + + #-----------SVC4157--------------------------- + # %1 - "The model name" + # %2 - "List of allowed models" + VSP_MODEL_NOT_ALLOWED: { + code: 400, + message: "The Model '%1' is not allowed for the imported Vendor Software Product. Allowed Models: '%2'", + messageId: "SVC4157" + } + + #---------SVC4158----------------------------- + # %1 - Valid artifact label name + INVALID_ARTIFACT_LABEL_NAME: { + code: 400, + message: "Invalid label name. Only the following characters are allowed in label name: '%1'", + messageId: "SVC4158" + } + + #---------SVC4159----------------------------- + # %1 - The model name + COULD_NOT_DELETE_MODEL: { + code: 500, + message: "Could not delete the model '%1'.", + messageId: "SVC4159" + } + + #---------SVC4160----------------------------- + # %1 - The model name + COULD_NOT_DELETE_MODEL_ELEMENTS: { + code: 500, + message: "Could not delete the model '%1' elements.", + messageId: "SVC4160" + } + #---------SVC4161----------------------------- + INVALID_NODE_TYPES_YAML: { + code: 400, + message: "Invalid node_types TOSCA yaml", + messageId: "SVC4161" + } + + #---------SVC4162----------------------------- + # %1 - The janusgraph status + FAILED_CREATE_ARTIFACTS_TYPES: { + code: 500, + message: "Failed to create artifact types with status '%1'.", + messageId: "SVC4162" + } + + #---------SVC4163----------------------------- + # %1 - The janusgraph status + ARTIFACT_TYPE_ALREADY_EXIST: { + code: 409, + message: "Artifact type '%1' already exist.", + messageId: "SVC4163" + } + + #---------SVC4692----------------------------- + # %1 - Component name + COMPONENT_NOT_ARCHIVED: { + code: 403, + message: "Component '%1' is not archived", + messageId: "SVC4692" + } + + #---------SVC4693----------------------------- + # %1 - List of services + COMPONENT_IN_USE_BY_ANOTHER_COMPONENT: { + code: 403, + message: "Component is in use by '%1'", + messageId: "SVC4693" + } + + #---------SVC4164----------------------------- + # %1 - componentType + # %2 - component name + CANNOT_DELETE_SYSTEM_DEPLOYED_RESOURCES: { + code: 409, + message: "System deployed '%1' cannot be deleted '%2'", + messageId: "SVC4164" + } + + #---------SVC4165----------------------------- + # %1 - input origin + TOSCA_GET_FUNCTION_INPUTS_ONLY_SELF_ERROR: { + code: 400, + message: "Invalid get_input definition. Inputs can only be get from SELF, the given origin was '%1'", + messageId: "SVC4165" + } + + #---------SVC4166----------------------------- + # %1 - input name + # %2 - input origin + TOSCA_GET_FUNCTION_INPUTS_NOT_FOUND: { + code: 404, + message: "The given input '%1' was not found on '%2'.", + messageId: "SVC4166" + } + + #---------SVC4167----------------------------- + # %1 - Tosca function + # %2 - Referred input type + # %3 - Selected property type + TOSCA_GET_FUNCTION_TYPE_DIVERGE: { + code: 400, + message: "Could not set %1. Referred input type '%2' diverges from the selected property type '%3'.", + messageId: "SVC4167" + } + + #---------SVC4168----------------------------- + # %1 - Tosca function + # %2 - Referred input schema + # %3 - Selected property schema + TOSCA_GET_FUNCTION_SCHEMA_DIVERGE: { + code: 400, + message: "Could not set %1. Referred input schema '%2' diverges from the selected property schema '%3'.", + messageId: "SVC4168" + } + + #---------SVC4169----------------------------- + # %1 - Property type (property|input|attribute) + # %1 - Property name + # %2 - Property origin + TOSCA_GET_FUNCTION_PROPERTY_NOT_FOUND: { + code: 404, + message: "The given %1 '%2' was not found on '%3'.", + messageId: "SVC4169" + } + + #---------SVC4170----------------------------- + # %1 - Property type (property|input|attribute) + # %2 - Property name/path + # %3 - Property data type + TOSCA_GET_FUNCTION_PROPERTY_DATA_TYPE_NOT_FOUND: { + code: 404, + message: "The %1 '%2' type '%3' was not found.", + messageId: "SVC4170" + } + + #---------SVC4171----------------------------- + # %1 - Instance name + TOSCA_GET_FUNCTION_INSTANCE_NOT_FOUND: { + code: 404, + message: "The instance '%1' was not found.", + messageId: "SVC4171" + } + + #-----------SVC4172--------------------------- + #%1 - TOSCA function attribute + TOSCA_FUNCTION_MISSING_ATTRIBUTE: { + code: 400, + message: "Missing TOSCA function '%1'.", + messageId: "SVC4172" + } + + #-----------SVC4173--------------------------- + RELATIONSHIP_TEMPLATE_NOT_FOUND: { + code: 404, + message: "Relationship_templates entry not found in TOSCA CSAR.", + messageId: "SVC4173" + } + + #-----------SVC4174--------------------------- + RELATIONSHIP_TEMPLATE_DEFINITION_NOT_FOUND: { + code: 404, + message: "Relationship_templates definition not found in TOSCA CSAR.", + messageId: "SVC4174" + } + + #-----------SVC4175--------------------------- + TOSCA_FUNCTION_EXPECTED_ERROR: { + code: 400, + message: "Expecting a Tosca Function value.", + messageId: "SVC4175" + } + + #-----------SVC4176--------------------------- + FILTER_CONSTRAINT_MISSING: { + code: 400, + message: "The filter constraint was not provided.", + messageId: "SVC4176" + } + + #-----------SVC4177--------------------------- + #%1 - The missing field + FILTER_CONSTRAINT_MISSING_FIELD: { + code: 400, + message: "Required field '%1' is missing in the filter constraint.", + messageId: "SVC4177" + } + + #%1 - the component id + SUBSTITUTION_FILTER_NOT_FOUND: { + code: 404, + message: 'Substitution filter not found in the component "%1"', + messageId: "SVC4178" + } + + # %1 - Component name + COMPONENT_DOES_NOT_HAVE_INPUTS: { + code: 400, + message: "Component '%1' does not have inputs.", + messageId: "SVC4179" + } + + # %1 - Input name + # %2 - Component name + COMPONENT_INPUT_NOT_FOUND: { + code: 400, + message: "Input '%1' does not exist in '%2'.", + messageId: "SVC4180" + } + + # %1 - Target property name + # %2 - Source property name + SOURCE_TARGET_SCHEMA_MISMATCH: { + code: 400, + message: "Target property '%1' schema '%2' does not match with source property '%3' schema '%4'.", + messageId: "SVC4181" + } + + # %1 - Property name + # %2 - Component name + COMPONENT_PROPERTY_NOT_FOUND: + code: 400 + message: "Property '%1' does not exist in '%2'." + messageId: "SVC4183" + + # %1 - The component type + # %2 - The expected component types + INVALID_COMPONENT_TYPE: + code: 400 + message: "Invalid component type '%1'. Expected types are: %2" + messageId: "SVC4185" diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentNodeFilterBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentNodeFilterBusinessLogicTest.java index aae88ab153..1bf075e2f6 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentNodeFilterBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentNodeFilterBusinessLogicTest.java @@ -25,47 +25,42 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.isNull; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; 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; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Optional; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.ArgumentMatchers; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.junit.jupiter.MockitoExtension; import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException; import org.openecomp.sdc.be.components.impl.exceptions.ComponentException; -import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction; import org.openecomp.sdc.be.components.validation.NodeFilterValidator; import org.openecomp.sdc.be.components.validation.UserValidations; import org.openecomp.sdc.be.config.ConfigurationManager; import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.dao.janusgraph.JanusGraphGenericDao; import org.openecomp.sdc.be.dao.janusgraph.JanusGraphDao; -import org.openecomp.sdc.be.datamodel.utils.ConstraintConvertor; +import org.openecomp.sdc.be.dao.janusgraph.JanusGraphGenericDao; import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyFilterConstraintDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyFilterDataDefinition; import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterCapabilityDataDefinition; -import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.datatypes.enums.NodeFilterConstraintType; import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; @@ -78,15 +73,18 @@ import org.openecomp.sdc.be.model.Resource; import org.openecomp.sdc.be.model.UploadNodeFilterInfo; import org.openecomp.sdc.be.model.UploadNodeFilterPropertyInfo; import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.dto.FilterConstraintDto; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.NodeFilterOperation; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.model.operations.impl.GraphLockOperation; +import org.openecomp.sdc.be.ui.mapper.FilterConstraintMapper; import org.openecomp.sdc.be.ui.model.UIConstraint; import org.openecomp.sdc.be.user.Role; +import org.openecomp.sdc.exception.ResponseFormat; @ExtendWith(MockitoExtension.class) -public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock { +class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock { private static final String servicePropertyName = "resourceType"; private static final String constraintOperator = "equal"; @@ -119,9 +117,8 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock private Resource resource; private ComponentInstance componentInstance; private CINodeFilterDataDefinition ciNodeFilterDataDefinition; - private RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition; - private String constraint; private UIConstraint uiConstraint; + private FilterConstraintDto filterConstraintDto; @BeforeEach public void init() { @@ -141,7 +138,7 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock } @Test - public void createWhenNodeFilterExistsTest() throws BusinessLogicException { + void createWhenNodeFilterExistsTest() throws BusinessLogicException { componentInstance.setNodeFilter(ciNodeFilterDataDefinition); when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(resource)); @@ -155,7 +152,7 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock } @Test - public void createNodeFilterFailTest() { + void createNodeFilterFailTest() { when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(resource)); when(graphLockOperation.lockComponent(componentId, NodeTypeEnum.Resource)) .thenReturn(StorageOperationStatus.OK); @@ -175,7 +172,7 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock } @Test - public void createNodeFilterIfNotExist() throws BusinessLogicException { + void createNodeFilterIfNotExist() throws BusinessLogicException { when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(resource)); when(graphLockOperation.lockComponent(componentId, NodeTypeEnum.Resource)) .thenReturn(StorageOperationStatus.OK); @@ -197,7 +194,7 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock } @Test - public void deleteNodeFilterIfExistsTest() throws BusinessLogicException { + void deleteNodeFilterIfExistsTest() throws BusinessLogicException { when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(resource)); when(nodeFilterValidator.validateComponentInstanceExist(resource, componentInstanceId)) .thenReturn(Either.left(true)); @@ -211,7 +208,7 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock } @Test - public void deleteWhenNodeFilterExistsTest() throws BusinessLogicException { + void deleteWhenNodeFilterExistsTest() throws BusinessLogicException { componentInstance.setNodeFilter(ciNodeFilterDataDefinition); when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(resource)); @@ -236,7 +233,7 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock } @Test - public void deleteNodeFilterIfExistsFailTest() { + void deleteNodeFilterIfExistsFailTest() { componentInstance.setNodeFilter(ciNodeFilterDataDefinition); when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(resource)); @@ -260,129 +257,130 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock } @Test - public void addNodeFilterPropertiesTest() throws BusinessLogicException { + void addNodeFilterPropertiesTest() throws BusinessLogicException { componentInstance.setNodeFilter(ciNodeFilterDataDefinition); when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(resource)); - when(nodeFilterValidator - .validateFilter(resource, componentInstanceId, - requirementNodeFilterPropertyDataDefinition.getConstraints(), - NodeFilterConstraintAction.ADD, NodeFilterConstraintType.PROPERTIES, "")).thenReturn(Either.left(true)); + when(nodeFilterValidator.validateFilter(resource, componentInstanceId, filterConstraintDto)) + .thenReturn(Either.left(true)); when(nodeFilterValidator.validateComponentInstanceExist(resource, componentInstanceId)) .thenReturn(Either.left(true)); when(graphLockOperation.lockComponent(componentId, NodeTypeEnum.Resource)) .thenReturn(StorageOperationStatus.OK); - when(nodeFilterOperation.addNewProperty(anyString(), anyString(), any(CINodeFilterDataDefinition.class), - any(RequirementNodeFilterPropertyDataDefinition.class))).thenReturn(Either.left(ciNodeFilterDataDefinition)); + when(nodeFilterOperation.addPropertyFilter(anyString(), anyString(), any(CINodeFilterDataDefinition.class), + any(PropertyFilterDataDefinition.class))).thenReturn(Either.left(ciNodeFilterDataDefinition)); when(graphLockOperation.unlockComponent(componentId, NodeTypeEnum.Resource)) .thenReturn(StorageOperationStatus.OK); final Optional<CINodeFilterDataDefinition> result = componentNodeFilterBusinessLogic - .addNodeFilter(componentId, componentInstanceId, NodeFilterConstraintAction.ADD, - "MyPropertyName", constraint, true, ComponentTypeEnum.RESOURCE, - NodeFilterConstraintType.PROPERTIES, ""); + .addNodeFilter(componentId, componentInstanceId, filterConstraintDto, true, ComponentTypeEnum.RESOURCE, + NodeFilterConstraintType.PROPERTIES, null); assertThat(result).isPresent(); assertThat(result.get().getProperties().getListToscaDataDefinition()).hasSize(1); verify(toscaOperationFacade, times(1)).getToscaElement(componentId); - verify(nodeFilterValidator, times(1)).validateFilter(resource, componentInstanceId, - Collections.singletonList(constraint), NodeFilterConstraintAction.ADD, NodeFilterConstraintType.PROPERTIES, ""); + verify(nodeFilterValidator, times(1)) + .validateFilter(resource, componentInstanceId, filterConstraintDto); verify(graphLockOperation, times(1)).lockComponent(componentId, NodeTypeEnum.Resource); verify(nodeFilterOperation, times(1)) - .addNewProperty(anyString(), anyString(), any(CINodeFilterDataDefinition.class), - any(RequirementNodeFilterPropertyDataDefinition.class)); + .addPropertyFilter(anyString(), anyString(), any(CINodeFilterDataDefinition.class), + any(PropertyFilterDataDefinition.class)); verify(graphLockOperation, times(1)).unlockComponent(componentId, NodeTypeEnum.Resource); } @Test - public void addNodeFilterCapabilitiesTest() throws BusinessLogicException { + void addNodeFilterCapabilitiesTest() throws BusinessLogicException { componentInstance.setNodeFilter(ciNodeFilterDataDefinition); - when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(resource)); - when(nodeFilterValidator - .validateFilter(resource, componentInstanceId, - requirementNodeFilterPropertyDataDefinition.getConstraints(), - NodeFilterConstraintAction.ADD, NodeFilterConstraintType.CAPABILITIES, capabilityName)).thenReturn(Either.left(true)); + when(nodeFilterValidator.validateFilter(resource, componentInstanceId, filterConstraintDto)) + .thenReturn(Either.left(true)); when(nodeFilterValidator.validateComponentInstanceExist(resource, componentInstanceId)) .thenReturn(Either.left(true)); when(graphLockOperation.lockComponent(componentId, NodeTypeEnum.Resource)) .thenReturn(StorageOperationStatus.OK); - when(nodeFilterOperation.addNewCapabilities(anyString(), anyString(), any(CINodeFilterDataDefinition.class), + when(nodeFilterOperation.addCapabilities(anyString(), anyString(), any(CINodeFilterDataDefinition.class), any(RequirementNodeFilterCapabilityDataDefinition.class))).thenReturn(Either.left(ciNodeFilterDataDefinition)); when(graphLockOperation.unlockComponent(componentId, NodeTypeEnum.Resource)) .thenReturn(StorageOperationStatus.OK); final Optional<CINodeFilterDataDefinition> result = componentNodeFilterBusinessLogic - .addNodeFilter(componentId, componentInstanceId, NodeFilterConstraintAction.ADD, - "MyPropertyName", constraint, true, ComponentTypeEnum.RESOURCE, - NodeFilterConstraintType.CAPABILITIES, capabilityName); + .addNodeFilter(componentId, componentInstanceId, filterConstraintDto, true, ComponentTypeEnum.RESOURCE, + NodeFilterConstraintType.CAPABILITIES, capabilityName + ); assertThat(result).isPresent(); assertThat(result.get().getProperties().getListToscaDataDefinition()).hasSize(1); verify(toscaOperationFacade, times(1)).getToscaElement(componentId); - verify(nodeFilterValidator, times(1)).validateFilter(resource, componentInstanceId, - Collections.singletonList(constraint), NodeFilterConstraintAction.ADD, NodeFilterConstraintType.CAPABILITIES, capabilityName); + verify(nodeFilterValidator, times(1)) + .validateFilter(resource, componentInstanceId, filterConstraintDto); verify(graphLockOperation, times(1)).lockComponent(componentId, NodeTypeEnum.Resource); verify(nodeFilterOperation, times(1)) - .addNewCapabilities(anyString(), anyString(), any(CINodeFilterDataDefinition.class), + .addCapabilities(anyString(), anyString(), any(CINodeFilterDataDefinition.class), any(RequirementNodeFilterCapabilityDataDefinition.class)); verify(graphLockOperation, times(1)).unlockComponent(componentId, NodeTypeEnum.Resource); } @Test - public void addNodeFilterFailTest() { + void addNodeFilterFailTest() { componentInstance.setNodeFilter(ciNodeFilterDataDefinition); when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(resource)); when(nodeFilterValidator - .validateFilter(resource, componentInstanceId, - requirementNodeFilterPropertyDataDefinition.getConstraints(), - NodeFilterConstraintAction.ADD, NodeFilterConstraintType.PROPERTIES, capabilityName)).thenReturn(Either.left(true)); + .validateFilter(resource, componentInstanceId, filterConstraintDto)).thenReturn(Either.left(true)); when(nodeFilterValidator.validateComponentInstanceExist(resource, componentInstanceId)) .thenReturn(Either.left(true)); when(graphLockOperation.lockComponent(componentId, NodeTypeEnum.Resource)) .thenReturn(StorageOperationStatus.OK); when(graphLockOperation.unlockComponent(componentId, NodeTypeEnum.Resource)) .thenReturn(StorageOperationStatus.OK); - - final List<String> constraints = requirementNodeFilterPropertyDataDefinition.getConstraints(); - assertThrows(BusinessLogicException.class, () -> componentNodeFilterBusinessLogic - .addNodeFilter(componentId, componentInstanceId, NodeFilterConstraintAction.ADD, - "MyPropertyName", constraint, true, ComponentTypeEnum.RESOURCE, + when(nodeFilterOperation + .addPropertyFilter(eq(componentId), eq(componentInstanceId), eq(ciNodeFilterDataDefinition), any(PropertyFilterDataDefinition.class))) + .thenReturn(Either.right(StorageOperationStatus.COMPONENT_IS_IN_USE)); + when(componentsUtils.convertFromStorageResponse(StorageOperationStatus.COMPONENT_IS_IN_USE)).thenReturn(ActionStatus.COMPONENT_IN_USE); + final ResponseFormat expectedResponse = new ResponseFormat(); + when(componentsUtils.getResponseFormatByResource(ActionStatus.COMPONENT_IN_USE, resource.getSystemName())).thenReturn(expectedResponse); + + final BusinessLogicException businessLogicException = assertThrows(BusinessLogicException.class, () -> componentNodeFilterBusinessLogic + .addNodeFilter(componentId, componentInstanceId, filterConstraintDto, true, ComponentTypeEnum.RESOURCE, NodeFilterConstraintType.PROPERTIES, capabilityName)); + assertEquals(expectedResponse, businessLogicException.getResponseFormat()); verify(toscaOperationFacade, times(1)).getToscaElement(componentId); verify(graphLockOperation, times(1)).lockComponent(componentId, NodeTypeEnum.Resource); - verify(nodeFilterValidator, times(1)).validateFilter(resource, componentInstanceId, - constraints, NodeFilterConstraintAction.ADD, NodeFilterConstraintType.PROPERTIES, capabilityName); - verify(nodeFilterOperation, times(0)) - .addNewProperty(componentId, componentInstanceId, ciNodeFilterDataDefinition, - requirementNodeFilterPropertyDataDefinition); + + verify(nodeFilterValidator, times(1)) + .validateFilter(resource, componentInstanceId, filterConstraintDto); + verify(nodeFilterOperation, times(1)) + .addPropertyFilter(eq(componentId), eq(componentInstanceId), eq(ciNodeFilterDataDefinition), + any(PropertyFilterDataDefinition.class)); verify(graphLockOperation, times(1)).unlockComponent(componentId, NodeTypeEnum.Resource); + verify(janusGraphDao, times(1)).rollback(); + verify(janusGraphDao, never()).commit(); } @Test - public void addNodeFilterFailFetchComponentTest() { + void addNodeFilterFailFetchComponentTest() { componentInstance.setNodeFilter(ciNodeFilterDataDefinition); when(toscaOperationFacade.getToscaElement(componentId)) - .thenReturn(Either.right(StorageOperationStatus.GENERAL_ERROR)); + .thenReturn(Either.right(StorageOperationStatus.NOT_FOUND)); + when(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND)).thenReturn(ActionStatus.COMPONENT_NOT_FOUND); + final ResponseFormat expectedResponse = new ResponseFormat(); + when(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_NOT_FOUND)).thenReturn(expectedResponse); - assertThrows(BusinessLogicException.class, () -> componentNodeFilterBusinessLogic - .addNodeFilter(componentId, componentInstanceId, NodeFilterConstraintAction.ADD, - "MyPropertyName", constraint, true, ComponentTypeEnum.RESOURCE, + final BusinessLogicException businessLogicException = assertThrows(BusinessLogicException.class, () -> componentNodeFilterBusinessLogic + .addNodeFilter(componentId, componentInstanceId, filterConstraintDto, true, ComponentTypeEnum.RESOURCE, NodeFilterConstraintType.PROPERTIES, capabilityName)); + assertEquals(expectedResponse, businessLogicException.getResponseFormat()); } @Test - public void deleteNodeFilterTest() throws BusinessLogicException { + void deleteNodeFilterTest() throws BusinessLogicException { componentInstance.setNodeFilter(ciNodeFilterDataDefinition); when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(resource)); when(nodeFilterValidator.validateComponentInstanceExist(resource, componentInstanceId)) .thenReturn(Either.left(true)); - when(nodeFilterValidator.validateFilter(resource, componentInstanceId, singletonList(constraint), - NodeFilterConstraintAction.DELETE, NodeFilterConstraintType.PROPERTIES, "")).thenReturn(Either.left(true)); when(graphLockOperation.lockComponent(componentId, NodeTypeEnum.Resource)) .thenReturn(StorageOperationStatus.OK); @@ -395,8 +393,7 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock .thenReturn(StorageOperationStatus.OK); final Optional<CINodeFilterDataDefinition> deleteNodeFilterResult = componentNodeFilterBusinessLogic - .deleteNodeFilter(componentId, componentInstanceId, NodeFilterConstraintAction.DELETE, constraint, - 0, true, ComponentTypeEnum.RESOURCE, NodeFilterConstraintType.PROPERTIES); + .deleteNodeFilter(componentId, componentInstanceId, 0, true, ComponentTypeEnum.RESOURCE, NodeFilterConstraintType.PROPERTIES); assertThat(deleteNodeFilterResult).isPresent(); @@ -404,9 +401,6 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock verify(graphLockOperation, times(1)).lockComponent(componentId, NodeTypeEnum.Resource); verify(nodeFilterValidator, times(1)) .validateComponentInstanceExist(resource, componentInstanceId); - verify(nodeFilterValidator, times(1)) - .validateFilter(resource, componentInstanceId, singletonList(constraint), - NodeFilterConstraintAction.DELETE, NodeFilterConstraintType.PROPERTIES, ""); verify(nodeFilterOperation, times(1)) .deleteConstraint(componentId, componentInstanceId, ciNodeFilterDataDefinition, 0, NodeFilterConstraintType.PROPERTIES); @@ -414,14 +408,12 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock } @Test - public void deleteNodeFilterFailTest() { + void deleteNodeFilterFailTest() { componentInstance.setNodeFilter(ciNodeFilterDataDefinition); when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(resource)); when(nodeFilterValidator.validateComponentInstanceExist(resource, componentInstanceId)) .thenReturn(Either.left(true)); - when(nodeFilterValidator.validateFilter(resource, componentInstanceId, singletonList(constraint), - NodeFilterConstraintAction.DELETE, NodeFilterConstraintType.PROPERTIES, "")).thenReturn(Either.left(true)); when(graphLockOperation.lockComponent(componentId, NodeTypeEnum.Resource)) .thenReturn(StorageOperationStatus.OK); @@ -434,64 +426,48 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock .thenReturn(StorageOperationStatus.OK); assertThrows(BusinessLogicException.class, () -> componentNodeFilterBusinessLogic - .deleteNodeFilter(componentId, componentInstanceId, NodeFilterConstraintAction.DELETE, constraint, - 0, true, ComponentTypeEnum.RESOURCE, NodeFilterConstraintType.PROPERTIES)); + .deleteNodeFilter(componentId, componentInstanceId, 0, true, ComponentTypeEnum.RESOURCE, NodeFilterConstraintType.PROPERTIES)); verify(toscaOperationFacade, times(1)).getToscaElement(componentId); verify(graphLockOperation, times(1)).lockComponent(componentId, NodeTypeEnum.Resource); verify(nodeFilterValidator, times(1)) - .validateFilter(resource, componentInstanceId, singletonList(constraint), - NodeFilterConstraintAction.DELETE, NodeFilterConstraintType.PROPERTIES, ""); - verify(nodeFilterValidator, times(1)) .validateComponentInstanceExist(resource, componentInstanceId); verify(graphLockOperation, times(1)).unlockComponent(componentId, NodeTypeEnum.Resource); } @Test - public void deleteNodeFilterFailValidationTest() { + void deleteNodeFilterFailValidationTest() { when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(resource)); when(nodeFilterValidator.validateComponentInstanceExist(resource, componentInstanceId)) .thenReturn(Either.left(true)); - when(nodeFilterValidator.validateFilter(resource, componentInstanceId, singletonList(constraint), - NodeFilterConstraintAction.DELETE, NodeFilterConstraintType.PROPERTIES, "")).thenReturn(Either.left(true)); assertThrows(BusinessLogicException.class, () -> componentNodeFilterBusinessLogic - .deleteNodeFilter(componentId, componentInstanceId, NodeFilterConstraintAction.DELETE, constraint, - 0, true, ComponentTypeEnum.RESOURCE, NodeFilterConstraintType.PROPERTIES)); + .deleteNodeFilter(componentId, componentInstanceId, 0, true, ComponentTypeEnum.RESOURCE, NodeFilterConstraintType.PROPERTIES)); verify(toscaOperationFacade, times(1)).getToscaElement(componentId); verify(nodeFilterValidator, times(1)) - .validateFilter(resource, componentInstanceId, singletonList(constraint), - NodeFilterConstraintAction.DELETE, NodeFilterConstraintType.PROPERTIES, ""); - verify(nodeFilterValidator, times(1)) .validateComponentInstanceExist(resource, componentInstanceId); } @Test - public void updateNodeFilterTest() throws BusinessLogicException { + void updateNodeFilterTest() throws BusinessLogicException { componentInstance.setNodeFilter(ciNodeFilterDataDefinition); when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(resource)); when(nodeFilterValidator.validateComponentInstanceExist(resource, componentInstanceId)) .thenReturn(Either.left(true)); when(nodeFilterValidator - .validateFilter(ArgumentMatchers.any(Component.class), anyString(), anyList(), - ArgumentMatchers.any(NodeFilterConstraintAction.class), - ArgumentMatchers.any(NodeFilterConstraintType.class), anyString())).thenReturn(Either.left(true)); + .validateFilter(any(Component.class), anyString(), any(FilterConstraintDto.class)) + ).thenReturn(Either.left(true)); - when(nodeFilterValidator - .validateFilter(ArgumentMatchers.any(Component.class), anyString(), anyList(), - ArgumentMatchers.any(NodeFilterConstraintAction.class), - ArgumentMatchers.any(NodeFilterConstraintType.class), isNull())).thenReturn(Either.left(true)); - when(graphLockOperation.lockComponent(componentId, NodeTypeEnum.Resource)) .thenReturn(StorageOperationStatus.OK); when(nodeFilterOperation.deleteConstraint(componentId, componentInstanceId, ciNodeFilterDataDefinition, 0, NodeFilterConstraintType.PROPERTIES)).thenReturn(Either.left(ciNodeFilterDataDefinition)); - when(nodeFilterOperation.addNewProperty(anyString(), anyString(), any(CINodeFilterDataDefinition.class), - any(RequirementNodeFilterPropertyDataDefinition.class))).thenReturn(Either.left(ciNodeFilterDataDefinition)); + when(nodeFilterOperation.addPropertyFilter(anyString(), anyString(), any(CINodeFilterDataDefinition.class), + any(PropertyFilterDataDefinition.class))).thenReturn(Either.left(ciNodeFilterDataDefinition)); when(graphLockOperation.unlockComponent(componentId, NodeTypeEnum.Resource)) .thenReturn(StorageOperationStatus.OK); @@ -505,20 +481,16 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock } @Test - public void updateNodeFilterFailTest() throws BusinessLogicException { + void updateNodeFilterFailTest() { componentInstance.setNodeFilter(ciNodeFilterDataDefinition); when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(resource)); when(nodeFilterValidator.validateComponentInstanceExist(resource, componentInstanceId)) .thenReturn(Either.left(true)); when(nodeFilterValidator - .validateFilter(ArgumentMatchers.any(Component.class), anyString(), anyList(), - ArgumentMatchers.any(NodeFilterConstraintAction.class), - ArgumentMatchers.any(NodeFilterConstraintType.class), anyString())).thenReturn(Either.left(true)); - when(nodeFilterValidator - .validateFilter(ArgumentMatchers.any(Component.class), anyString(), anyList(), - ArgumentMatchers.any(NodeFilterConstraintAction.class), - ArgumentMatchers.any(NodeFilterConstraintType.class), isNull())).thenReturn(Either.left(true)); + .validateFilter(any(Component.class), anyString(), any(FilterConstraintDto.class)) + ).thenReturn(Either.left(true)); + when(graphLockOperation.lockComponent(componentId, NodeTypeEnum.Resource)) .thenReturn(StorageOperationStatus.OK); @@ -526,8 +498,8 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock when(nodeFilterOperation.deleteConstraint(componentId, componentInstanceId, ciNodeFilterDataDefinition, 0, NodeFilterConstraintType.PROPERTIES)).thenReturn(Either.left(ciNodeFilterDataDefinition)); - when(nodeFilterOperation.addNewProperty(anyString(), anyString(), any(CINodeFilterDataDefinition.class), - any(RequirementNodeFilterPropertyDataDefinition.class))).thenReturn(Either.right(StorageOperationStatus.GENERAL_ERROR)); + when(nodeFilterOperation.addPropertyFilter(anyString(), anyString(), any(CINodeFilterDataDefinition.class), + any(PropertyFilterDataDefinition.class))).thenReturn(Either.right(StorageOperationStatus.GENERAL_ERROR)); when(graphLockOperation.unlockComponent(componentId, NodeTypeEnum.Resource)) .thenReturn(StorageOperationStatus.OK); @@ -538,14 +510,10 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock } @Test - public void updateNodeFilterFailValidationTest() { + void updateNodeFilterFailValidationTest() { when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(resource)); when(nodeFilterValidator.validateComponentInstanceExist(resource, componentInstanceId)) .thenReturn(Either.left(true)); - when(nodeFilterValidator - .validateFilter(ArgumentMatchers.any(Component.class), anyString(), anyList(), - ArgumentMatchers.any(NodeFilterConstraintAction.class), - ArgumentMatchers.any(NodeFilterConstraintType.class), anyString())).thenReturn(Either.left(true)); assertThrows(BusinessLogicException.class, () -> componentNodeFilterBusinessLogic .updateNodeFilter(componentId, componentInstanceId, uiConstraint, ComponentTypeEnum.RESOURCE, @@ -555,55 +523,49 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock } @Test - public void testAssociateNodeFilterToComponentInstance() { + void testAssociateNodeFilterToComponentInstance() { CINodeFilterDataDefinition ciNodeFilterDataDefinition = new CINodeFilterDataDefinition(); UploadNodeFilterInfo filter = new UploadNodeFilterInfo(); UploadNodeFilterPropertyInfo propertyDataDefinition = new UploadNodeFilterPropertyInfo(); propertyDataDefinition.setName("order"); - propertyDataDefinition.setValues(Collections.singletonList("order: {equal: 2")); - List<UploadNodeFilterPropertyInfo> propertyList = new LinkedList<>(); - propertyList.add(propertyDataDefinition); + propertyDataDefinition.setValues(Collections.singletonList("order: {equal: 2}")); filter.setProperties(Collections.singletonList(propertyDataDefinition)); Map<String, UploadNodeFilterInfo> nodeFilterMap = new HashMap<>(); nodeFilterMap.put(componentInstanceId, filter); when(nodeFilterOperation.createNodeFilter(componentId, componentInstanceId)).thenReturn(Either.left(ciNodeFilterDataDefinition)); - when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(resource)); - when(nodeFilterOperation.addNewProperty(anyString(), anyString(), any(CINodeFilterDataDefinition.class), - any(RequirementNodeFilterPropertyDataDefinition.class))).thenReturn(Either.left(ciNodeFilterDataDefinition)); + when(nodeFilterOperation.addPropertyFilter(anyString(), anyString(), any(CINodeFilterDataDefinition.class), + any(PropertyFilterDataDefinition.class))).thenReturn(Either.left(ciNodeFilterDataDefinition)); StorageOperationStatus status = componentNodeFilterBusinessLogic.associateNodeFilterToComponentInstance(componentId, nodeFilterMap); assertEquals(StorageOperationStatus.OK, status); } @Test - public void testAssociateNodeFilterToComponentInstanceFail() { + void testAssociateNodeFilterToComponentInstanceFail() { CINodeFilterDataDefinition ciNodeFilterDataDefinition = new CINodeFilterDataDefinition(); UploadNodeFilterInfo filter = new UploadNodeFilterInfo(); UploadNodeFilterPropertyInfo propertyDataDefinition = new UploadNodeFilterPropertyInfo(); propertyDataDefinition.setName("order"); - propertyDataDefinition.setValues(Collections.singletonList("order: {equal: 2")); - List<UploadNodeFilterPropertyInfo> propertyList = new LinkedList<>(); - propertyList.add(propertyDataDefinition); + propertyDataDefinition.setValues(Collections.singletonList("order: {equal: 2}")); filter.setProperties(Collections.singletonList(propertyDataDefinition)); Map<String, UploadNodeFilterInfo> nodeFilterMap = new HashMap<>(); nodeFilterMap.put(componentInstanceId, filter); when(nodeFilterOperation.createNodeFilter(componentId, componentInstanceId)).thenReturn(Either.left(ciNodeFilterDataDefinition)); - when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(resource)); - when(nodeFilterOperation.addNewProperty(anyString(), anyString(), any(CINodeFilterDataDefinition.class), - any(RequirementNodeFilterPropertyDataDefinition.class))).thenReturn(Either.right(StorageOperationStatus.GENERAL_ERROR)); + when(nodeFilterOperation.addPropertyFilter(anyString(), anyString(), any(CINodeFilterDataDefinition.class), + any(PropertyFilterDataDefinition.class))).thenReturn(Either.right(StorageOperationStatus.GENERAL_ERROR)); - Assertions.assertThrows(ComponentException.class, () -> componentNodeFilterBusinessLogic.associateNodeFilterToComponentInstance(componentId, + assertThrows(ComponentException.class, () -> componentNodeFilterBusinessLogic.associateNodeFilterToComponentInstance(componentId, nodeFilterMap)); } @Test - public void validateUserTes() { + void validateUserTes() { final String USER_ID = "jh0003"; final User user = new User(); user.setUserId(USER_ID); @@ -615,54 +577,54 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock assertTrue(Role.ADMIN.name().equalsIgnoreCase(result.getRole())); } - public void initResource() { - try { - resource = new Resource(); - resource.setName("MyResource"); - resource.setUniqueId(componentId); - resource.setToscaResourceName("My_Resource_Tosca_Name"); - resource.addCategory("Network Layer 2-3", "Router"); - resource.setDescription("My short description"); - - componentInstance = new ComponentInstance(); - componentInstance.setUniqueId(componentInstanceId); - componentInstance.setName("myComponentInstance"); - componentInstance.setDirectives(ConfigurationManager.getConfigurationManager().getConfiguration() - .getDirectives()); - - uiConstraint = new UIConstraint(servicePropertyName, constraintOperator, sourceType, sourceName, propertyValue); - constraint = new ConstraintConvertor().convert(uiConstraint); - - requirementNodeFilterPropertyDataDefinition = new RequirementNodeFilterPropertyDataDefinition(); - requirementNodeFilterPropertyDataDefinition.setName(uiConstraint.getServicePropertyName()); - requirementNodeFilterPropertyDataDefinition.setConstraints(new LinkedList<>(Arrays.asList(constraint))); - - final ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> listDataDefinition = - new ListDataDefinition<>(new LinkedList<>(Arrays.asList(requirementNodeFilterPropertyDataDefinition))); - - ciNodeFilterDataDefinition = new CINodeFilterDataDefinition(); - ciNodeFilterDataDefinition.setProperties(listDataDefinition); - ciNodeFilterDataDefinition.setID("NODE_FILTER_UID"); - - resource.setComponentInstances(singletonList(componentInstance)); - - final PropertyDefinition property = new PropertyDefinition(); - property.setName(uiConstraint.getServicePropertyName()); - - final List<ComponentInstanceProperty> origProperties = new ArrayList<>(); - final ComponentInstanceProperty origProperty = new ComponentInstanceProperty(); - origProperty.setName(uiConstraint.getServicePropertyName()); - origProperty.setValue(propertyValue); - origProperty.setType(uiConstraint.getSourceType()); - origProperties.add(origProperty); - - final Map<String, List<ComponentInstanceProperty>> componentInstanceProps = new HashMap<>(); - componentInstanceProps.put(componentInstanceId, origProperties); - - resource.setComponentInstancesProperties(componentInstanceProps); - resource.setProperties(new LinkedList<>(Arrays.asList(property))); - } catch (final Exception e) { - fail(e.getMessage()); - } + private void initResource() { + resource = new Resource(); + resource.setName("MyResource"); + resource.setUniqueId(componentId); + resource.setToscaResourceName("My_Resource_Tosca_Name"); + resource.addCategory("Network Layer 2-3", "Router"); + resource.setDescription("My short description"); + + componentInstance = new ComponentInstance(); + componentInstance.setUniqueId(componentInstanceId); + componentInstance.setName("myComponentInstance"); + componentInstance.setDirectives(ConfigurationManager.getConfigurationManager().getConfiguration() + .getDirectives()); + + uiConstraint = new UIConstraint(servicePropertyName, constraintOperator, sourceType, sourceName, propertyValue); + final FilterConstraintMapper filterConstraintMapper = new FilterConstraintMapper(); + filterConstraintDto = filterConstraintMapper.mapFrom(uiConstraint); + + PropertyFilterDataDefinition propertyFilterDataDefinition = new PropertyFilterDataDefinition(); + propertyFilterDataDefinition.setName(uiConstraint.getServicePropertyName()); + final PropertyFilterConstraintDataDefinition propertyFilterConstraint = + filterConstraintMapper.mapTo(filterConstraintDto); + propertyFilterDataDefinition.setConstraints(new LinkedList<>(List.of(propertyFilterConstraint))); + + final ListDataDefinition<PropertyFilterDataDefinition> listDataDefinition = + new ListDataDefinition<>(new LinkedList<>(singletonList(propertyFilterDataDefinition))); + + ciNodeFilterDataDefinition = new CINodeFilterDataDefinition(); + ciNodeFilterDataDefinition.setProperties(listDataDefinition); + ciNodeFilterDataDefinition.setID("NODE_FILTER_UID"); + + resource.setComponentInstances(singletonList(componentInstance)); + + final PropertyDefinition property = new PropertyDefinition(); + property.setName(uiConstraint.getServicePropertyName()); + + final List<ComponentInstanceProperty> origProperties = new ArrayList<>(); + final ComponentInstanceProperty origProperty = new ComponentInstanceProperty(); + origProperty.setName(uiConstraint.getServicePropertyName()); + origProperty.setValue(propertyValue); + origProperty.setType(uiConstraint.getSourceType()); + origProperties.add(origProperty); + + final Map<String, List<ComponentInstanceProperty>> componentInstanceProps = new HashMap<>(); + componentInstanceProps.put(componentInstanceId, origProperties); + + resource.setComponentInstancesProperties(componentInstanceProps); + resource.setProperties(new LinkedList<>(List.of(property))); } + } diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentSubstitutionFilterBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentSubstitutionFilterBusinessLogicTest.java index 7435a8b6e2..c8692634c4 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentSubstitutionFilterBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentSubstitutionFilterBusinessLogicTest.java @@ -36,7 +36,6 @@ import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Optional; - import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -45,29 +44,30 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.junit.jupiter.MockitoExtension; import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException; -import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction; import org.openecomp.sdc.be.components.validation.NodeFilterValidator; import org.openecomp.sdc.be.components.validation.UserValidations; -import org.openecomp.sdc.be.dao.janusgraph.JanusGraphGenericDao; import org.openecomp.sdc.be.dao.janusgraph.JanusGraphDao; +import org.openecomp.sdc.be.dao.janusgraph.JanusGraphGenericDao; import org.openecomp.sdc.be.datamodel.utils.ConstraintConvertor; import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; -import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterPropertyDataDefinition; import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterPropertyDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; import org.openecomp.sdc.be.impl.ComponentsUtils; import org.openecomp.sdc.be.model.Component; -import org.openecomp.sdc.be.model.Service; import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.dto.FilterConstraintDto; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.SubstitutionFilterOperation; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.model.operations.impl.GraphLockOperation; +import org.openecomp.sdc.be.ui.mapper.FilterConstraintMapper; import org.openecomp.sdc.be.ui.model.UIConstraint; @ExtendWith(MockitoExtension.class) -public class ComponentSubstitutionFilterBusinessLogicTest extends BaseBusinessLogicMock { +class ComponentSubstitutionFilterBusinessLogicTest extends BaseBusinessLogicMock { private static final String servicePropertyName = "controller_actor"; private static final String constraintOperator = "equal"; @@ -97,8 +97,9 @@ public class ComponentSubstitutionFilterBusinessLogicTest extends BaseBusinessLo private Component component; private SubstitutionFilterDataDefinition substitutionFilterDataDefinition; - private RequirementSubstitutionFilterPropertyDataDefinition requirementSubstitutionFilterPropertyDataDefinition; + private SubstitutionFilterPropertyDataDefinition substitutionFilterPropertyDataDefinition; private String constraint; + private FilterConstraintDto filterConstraintDto; @BeforeEach public void init() { @@ -118,7 +119,7 @@ public class ComponentSubstitutionFilterBusinessLogicTest extends BaseBusinessLo } @Test - public void doNotCreateSubstitutionFilterAsExistsTest() throws BusinessLogicException { + void doNotCreateSubstitutionFilterAsExistsTest() throws BusinessLogicException { component.setSubstitutionFilter(substitutionFilterDataDefinition); when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(component)); @@ -131,7 +132,7 @@ public class ComponentSubstitutionFilterBusinessLogicTest extends BaseBusinessLo } @Test - public void createSubstitutionFilterIfNotExistTest() throws BusinessLogicException { + void createSubstitutionFilterIfNotExistTest() throws BusinessLogicException { when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(component)); when(graphLockOperation.lockComponent(componentId, NodeTypeEnum.Service)) .thenReturn(StorageOperationStatus.OK); @@ -151,7 +152,7 @@ public class ComponentSubstitutionFilterBusinessLogicTest extends BaseBusinessLo } @Test - public void createSubstitutionFilterIfNotExistFailTest() { + void createSubstitutionFilterIfNotExistFailTest() { when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(component)); when(graphLockOperation.lockComponent(componentId, NodeTypeEnum.Service)) .thenReturn(StorageOperationStatus.OK); @@ -170,124 +171,111 @@ public class ComponentSubstitutionFilterBusinessLogicTest extends BaseBusinessLo } @Test - public void addSubstitutionFilterTest() throws BusinessLogicException { + void addSubstitutionFilterTest() throws BusinessLogicException { component.setSubstitutionFilter(substitutionFilterDataDefinition); when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(component)); when(graphLockOperation.lockComponent(componentId, NodeTypeEnum.Service)) .thenReturn(StorageOperationStatus.OK); - when(nodeFilterValidator.validateComponentFilter(component, Collections.singletonList(constraint), - NodeFilterConstraintAction.ADD)).thenReturn(Either.left(true)); + when(nodeFilterValidator.validateSubstitutionFilter(component, filterConstraintDto)).thenReturn(Either.left(true)); when(substitutionFilterOperation .addPropertyFilter(anyString(), any(SubstitutionFilterDataDefinition.class), - any(RequirementSubstitutionFilterPropertyDataDefinition.class))) + any(SubstitutionFilterPropertyDataDefinition.class))) .thenReturn(Either.left(substitutionFilterDataDefinition)); when(graphLockOperation.unlockComponent(componentId, NodeTypeEnum.Service)) .thenReturn(StorageOperationStatus.OK); final Optional<SubstitutionFilterDataDefinition> result = componentSubstitutionFilterBusinessLogic - .addSubstitutionFilter(componentId, servicePropertyName, constraint, true, - ComponentTypeEnum.SERVICE); + .addSubstitutionFilter(componentId, filterConstraintDto, true, ComponentTypeEnum.SERVICE); assertThat(result).isPresent(); assertThat(result.get().getProperties().getListToscaDataDefinition()).hasSize(1); verify(toscaOperationFacade, times(1)).getToscaElement(componentId); verify(graphLockOperation, times(1)).lockComponent(componentId, NodeTypeEnum.Service); - verify(nodeFilterValidator, times(1)).validateComponentFilter(component, - Collections.singletonList(constraint), NodeFilterConstraintAction.ADD); + verify(nodeFilterValidator, times(1)).validateSubstitutionFilter(component, filterConstraintDto); verify(substitutionFilterOperation, times(1)) .addPropertyFilter(anyString(), any(SubstitutionFilterDataDefinition.class), - any(RequirementSubstitutionFilterPropertyDataDefinition.class)); + any(SubstitutionFilterPropertyDataDefinition.class)); verify(graphLockOperation, times(1)).unlockComponent(componentId, NodeTypeEnum.Service); } @Test - public void addSubstitutionFilterFailTest() { + void addSubstitutionFilterFailTest() { component.setSubstitutionFilter(substitutionFilterDataDefinition); when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(component)); when(graphLockOperation.lockComponent(componentId, NodeTypeEnum.Service)) .thenReturn(StorageOperationStatus.OK); - when(nodeFilterValidator.validateComponentFilter(component, Collections.singletonList(constraint), - NodeFilterConstraintAction.ADD)).thenReturn(Either.left(true)); + when(nodeFilterValidator.validateSubstitutionFilter(component, filterConstraintDto)).thenReturn(Either.left(true)); when(substitutionFilterOperation .addPropertyFilter(componentId, substitutionFilterDataDefinition, - requirementSubstitutionFilterPropertyDataDefinition)) + substitutionFilterPropertyDataDefinition)) .thenReturn(Either.right(StorageOperationStatus.GENERAL_ERROR)); when(graphLockOperation.unlockComponent(componentId, NodeTypeEnum.Service)) .thenReturn(StorageOperationStatus.OK); assertThrows(BusinessLogicException.class, () -> componentSubstitutionFilterBusinessLogic - .addSubstitutionFilter(componentId, servicePropertyName, constraint, true, - ComponentTypeEnum.SERVICE)); + .addSubstitutionFilter(componentId, filterConstraintDto, true, ComponentTypeEnum.SERVICE)); verify(toscaOperationFacade, times(1)).getToscaElement(componentId); verify(graphLockOperation, times(1)).lockComponent(componentId, NodeTypeEnum.Service); - verify(nodeFilterValidator, times(1)).validateComponentFilter(component, - Collections.singletonList(constraint), NodeFilterConstraintAction.ADD); + verify(nodeFilterValidator, times(1)).validateSubstitutionFilter(component, filterConstraintDto); verify(substitutionFilterOperation, times(0)) .addPropertyFilter(componentId, substitutionFilterDataDefinition, - requirementSubstitutionFilterPropertyDataDefinition); + substitutionFilterPropertyDataDefinition); verify(graphLockOperation, times(1)).unlockComponent(componentId, NodeTypeEnum.Service); } @Test - public void updateSubstitutionFilterTest() throws BusinessLogicException { + void updateSubstitutionFilterTest() throws BusinessLogicException { component.setSubstitutionFilter(substitutionFilterDataDefinition); - final List<String> constraints = requirementSubstitutionFilterPropertyDataDefinition.getConstraints(); when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(component)); when(graphLockOperation.lockComponent(componentId, NodeTypeEnum.Service)) .thenReturn(StorageOperationStatus.OK); - when(nodeFilterValidator.validateComponentFilter(component, Collections.singletonList(constraint), - NodeFilterConstraintAction.UPDATE)).thenReturn(Either.left(true)); - when(substitutionFilterOperation.updateProperties(anyString(), any(SubstitutionFilterDataDefinition.class), anyList())) + when(nodeFilterValidator.validateSubstitutionFilter(component, List.of(filterConstraintDto))).thenReturn(Either.left(true)); + when(substitutionFilterOperation.updatePropertyFilters(anyString(), any(SubstitutionFilterDataDefinition.class), anyList())) .thenReturn(Either.left(substitutionFilterDataDefinition)); when(graphLockOperation.unlockComponent(componentId, NodeTypeEnum.Service)) .thenReturn(StorageOperationStatus.OK); final Optional<SubstitutionFilterDataDefinition> result = componentSubstitutionFilterBusinessLogic - .updateSubstitutionFilter(componentId, Collections.singletonList(constraint), - true, ComponentTypeEnum.SERVICE); + .updateSubstitutionFilter(componentId, List.of(filterConstraintDto), true, ComponentTypeEnum.SERVICE); assertThat(result).isPresent(); assertThat(result.get().getProperties().getListToscaDataDefinition()).hasSize(1); verify(substitutionFilterOperation, times(1)) - .updateProperties(anyString(), any(SubstitutionFilterDataDefinition.class), anyList()); - verify(nodeFilterValidator, times(1)).validateComponentFilter(component, - Collections.singletonList(constraint), NodeFilterConstraintAction.UPDATE); + .updatePropertyFilters(anyString(), any(SubstitutionFilterDataDefinition.class), anyList()); + verify(nodeFilterValidator, times(1)).validateSubstitutionFilter(component, List.of(filterConstraintDto)); verify(toscaOperationFacade, times(1)).getToscaElement(componentId); verify(graphLockOperation, times(1)).lockComponent(componentId, NodeTypeEnum.Service); verify(graphLockOperation, times(1)).unlockComponent(componentId, NodeTypeEnum.Service); } @Test - public void updateSubstitutionFilterFailTest() { + void updateSubstitutionFilterFailTest() { component.setSubstitutionFilter(substitutionFilterDataDefinition); when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(component)); when(graphLockOperation.lockComponent(componentId, NodeTypeEnum.Service)) .thenReturn(StorageOperationStatus.OK); - when(nodeFilterValidator.validateComponentFilter(component, Collections.singletonList(constraint), - NodeFilterConstraintAction.UPDATE)).thenReturn(Either.left(true)); + when(nodeFilterValidator.validateSubstitutionFilter(component, List.of(filterConstraintDto))).thenReturn(Either.left(true)); when(graphLockOperation.unlockComponent(componentId, NodeTypeEnum.Service)) .thenReturn(StorageOperationStatus.OK); - final List<String> constraints = requirementSubstitutionFilterPropertyDataDefinition.getConstraints(); assertThrows(BusinessLogicException.class, () -> componentSubstitutionFilterBusinessLogic - .updateSubstitutionFilter(componentId, constraints, true, ComponentTypeEnum.SERVICE)); + .updateSubstitutionFilter(componentId, List.of(filterConstraintDto), true, ComponentTypeEnum.SERVICE)); verify(toscaOperationFacade, times(1)).getToscaElement(componentId); verify(graphLockOperation, times(1)).lockComponent(componentId, NodeTypeEnum.Service); - verify(nodeFilterValidator, times(1)).validateComponentFilter(component, - Collections.singletonList(constraint), NodeFilterConstraintAction.UPDATE); + verify(nodeFilterValidator, times(1)).validateSubstitutionFilter(component, List.of(filterConstraintDto)); verify(graphLockOperation, times(1)).unlockComponent(componentId, NodeTypeEnum.Service); } @Test - public void deleteSubstitutionFilterTest() throws BusinessLogicException { + void deleteSubstitutionFilterTest() throws BusinessLogicException { substitutionFilterDataDefinition.setProperties(new ListDataDefinition<>()); component.setSubstitutionFilter(substitutionFilterDataDefinition); @@ -310,7 +298,7 @@ public class ComponentSubstitutionFilterBusinessLogicTest extends BaseBusinessLo } @Test - public void deleteSubstitutionFilterFailTest() { + void deleteSubstitutionFilterFailTest() { component.setSubstitutionFilter(substitutionFilterDataDefinition); when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(component)); @@ -322,7 +310,6 @@ public class ComponentSubstitutionFilterBusinessLogicTest extends BaseBusinessLo when(graphLockOperation.unlockComponent(componentId, NodeTypeEnum.Service)) .thenReturn(StorageOperationStatus.OK); - final List<String> constraints = requirementSubstitutionFilterPropertyDataDefinition.getConstraints(); assertThrows(BusinessLogicException.class, () -> componentSubstitutionFilterBusinessLogic .deleteSubstitutionFilter(componentId, anyInt(),true, ComponentTypeEnum.SERVICE)); @@ -341,16 +328,18 @@ public class ComponentSubstitutionFilterBusinessLogicTest extends BaseBusinessLo final UIConstraint uiConstraint = new UIConstraint(servicePropertyName, constraintOperator, sourceType, sourceName, propertyValue); + final FilterConstraintMapper filterConstraintMapper = new FilterConstraintMapper(); + filterConstraintDto = filterConstraintMapper.mapFrom(uiConstraint); constraint = new ConstraintConvertor().convert(uiConstraint); - requirementSubstitutionFilterPropertyDataDefinition = new RequirementSubstitutionFilterPropertyDataDefinition(); - requirementSubstitutionFilterPropertyDataDefinition.setName(uiConstraint.getServicePropertyName()); - requirementSubstitutionFilterPropertyDataDefinition - .setConstraints(Collections.singletonList(constraint)); + substitutionFilterPropertyDataDefinition = new SubstitutionFilterPropertyDataDefinition(); + substitutionFilterPropertyDataDefinition.setName(uiConstraint.getServicePropertyName()); + substitutionFilterPropertyDataDefinition + .setConstraints(List.of(filterConstraintMapper.mapTo(filterConstraintDto))); - final ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> listDataDefinition = + final ListDataDefinition<SubstitutionFilterPropertyDataDefinition> listDataDefinition = new ListDataDefinition<>( - Collections.singletonList(requirementSubstitutionFilterPropertyDataDefinition)); + Collections.singletonList(substitutionFilterPropertyDataDefinition)); substitutionFilterDataDefinition = new SubstitutionFilterDataDefinition(); substitutionFilterDataDefinition.setProperties(listDataDefinition); diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/utils/CINodeFilterUtilsTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/utils/CINodeFilterUtilsTest.java index b5baca1b98..eaefe42bdc 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/utils/CINodeFilterUtilsTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/utils/CINodeFilterUtilsTest.java @@ -22,26 +22,25 @@ package org.openecomp.sdc.be.components.impl.utils; -import org.junit.Test; -import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition; -import org.openecomp.sdc.be.model.UploadNodeFilterCapabilitiesInfo; -import org.openecomp.sdc.be.model.UploadNodeFilterInfo; -import org.openecomp.sdc.be.model.UploadNodeFilterPropertyInfo; +import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import org.junit.jupiter.api.Test; +import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition; +import org.openecomp.sdc.be.model.UploadNodeFilterCapabilitiesInfo; +import org.openecomp.sdc.be.model.UploadNodeFilterInfo; +import org.openecomp.sdc.be.model.UploadNodeFilterPropertyInfo; -import static org.junit.Assert.assertEquals; -public class CINodeFilterUtilsTest { +class CINodeFilterUtilsTest { - private CINodeFilterUtils ciNodeFilterUtils; + private final CINodeFilterUtils ciNodeFilterUtils = new CINodeFilterUtils(); @Test - public void testNodeFilterDataDefinition(){ - ciNodeFilterUtils = new CINodeFilterUtils(); + void testNodeFilterDataDefinition() { UploadNodeFilterInfo uNodeFilterInfo = new UploadNodeFilterInfo(); UploadNodeFilterPropertyInfo propertyInfo = new UploadNodeFilterPropertyInfo(); diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/property/PropertyConstraintsUtilsTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/property/PropertyConstraintsUtilsTest.java index 8095a6d3e7..1f1cc5e1eb 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/property/PropertyConstraintsUtilsTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/property/PropertyConstraintsUtilsTest.java @@ -29,7 +29,7 @@ import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.model.PropertyConstraint; import org.openecomp.sdc.be.model.PropertyDefinition; import org.openecomp.sdc.be.model.Resource; -import org.openecomp.sdc.be.model.tosca.constraints.ConstraintType; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; import org.openecomp.sdc.be.model.tosca.constraints.InRangeConstraint; import org.openecomp.sdc.be.model.tosca.constraints.PatternConstraint; import org.openecomp.sdc.be.model.tosca.constraints.ValidValuesConstraint; diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/FilterConstraintValidatorImplTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/FilterConstraintValidatorImplTest.java new file mode 100644 index 0000000000..afa339f95e --- /dev/null +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/FilterConstraintValidatorImplTest.java @@ -0,0 +1,125 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.openecomp.sdc.be.components.validation; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.stream.Stream; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException; +import org.openecomp.sdc.be.components.impl.exceptions.ComponentException; +import org.openecomp.sdc.be.components.impl.exceptions.FilterConstraintExceptionSupplier; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; +import org.openecomp.sdc.be.datatypes.enums.FilterValueType; +import org.openecomp.sdc.be.datatypes.enums.PropertyFilterTargetType; +import org.openecomp.sdc.be.model.dto.FilterConstraintDto; +import org.openecomp.sdc.be.model.validation.FilterConstraintValidator; +import org.openecomp.sdc.common.api.ConfigurationSource; +import org.openecomp.sdc.common.impl.ExternalConfiguration; +import org.openecomp.sdc.common.impl.FSConfigurationSource; + +class FilterConstraintValidatorImplTest { + + private final FilterConstraintValidator filterConstraintValidator = new FilterConstraintValidatorImpl(); + + @BeforeAll + static void setUp() { + String appConfigDir = "src/test/resources/config/catalog-be"; + ConfigurationSource configurationSource = new FSConfigurationSource(ExternalConfiguration.getChangeListener(), appConfigDir); + new ConfigurationManager(configurationSource); + } + + @Test + void validatePropertyFilterSuccess() { + final FilterConstraintDto filterConstraintDto = buildFilterConstraintDto("aProperty", null, ConstraintType.EQUAL, FilterValueType.STATIC, + PropertyFilterTargetType.PROPERTY, "any"); + assertDoesNotThrow(() -> filterConstraintValidator.validate(filterConstraintDto)); + } + + @Test + void validateCapabilityFilterSuccess() { + final var filterConstraintDto = new FilterConstraintDto(); + filterConstraintDto.setCapabilityName("aCapability"); + filterConstraintDto.setPropertyName("aProperty"); + filterConstraintDto.setTargetType(PropertyFilterTargetType.CAPABILITY); + filterConstraintDto.setOperator(ConstraintType.EQUAL); + filterConstraintDto.setValueType(FilterValueType.STATIC); + filterConstraintDto.setValue("any"); + assertDoesNotThrow(() -> filterConstraintValidator.validate(filterConstraintDto)); + } + + @ParameterizedTest + @MethodSource("provideMissingFieldParameters") + void missingFieldError(FilterConstraintDto filterConstraintDto, ComponentException expectedException) { + final ByActionStatusComponentException actualException = + assertThrows(ByActionStatusComponentException.class, () -> filterConstraintValidator.validate(filterConstraintDto)); + assertEquals(actualException.getActionStatus(), expectedException.getActionStatus()); + assertArrayEquals(actualException.getParams(), expectedException.getParams()); + } + + public static Stream<Arguments> provideMissingFieldParameters() { + final var filterConstraintMissingValue = buildFilterConstraintDto("aProperty", null, ConstraintType.EQUAL, FilterValueType.STATIC, PropertyFilterTargetType.PROPERTY, null); + final var filterConstraintMissingValueType = buildFilterConstraintDto("aProperty", null, ConstraintType.EQUAL, null, PropertyFilterTargetType.PROPERTY, "any"); + final var filterConstraintMissingPropertyName = buildFilterConstraintDto(null, null, ConstraintType.EQUAL, FilterValueType.STATIC, PropertyFilterTargetType.PROPERTY, "any"); + final var filterConstraintMissingCapabilityName = buildFilterConstraintDto("aProperty", null, ConstraintType.EQUAL, FilterValueType.STATIC, PropertyFilterTargetType.CAPABILITY, "any"); + final var filterConstraintMissingOperator = buildFilterConstraintDto("aProperty", null, null, FilterValueType.STATIC, PropertyFilterTargetType.PROPERTY, "any"); + final var filterConstraintMissingTargetType = buildFilterConstraintDto("aProperty", null, ConstraintType.EQUAL, FilterValueType.STATIC, null, "any"); + + return Stream.of( + Arguments.of(filterConstraintMissingValue, FilterConstraintExceptionSupplier.missingField("value").get()), + Arguments.of(filterConstraintMissingValueType, FilterConstraintExceptionSupplier.missingField("valueType").get()), + Arguments.of(filterConstraintMissingPropertyName, FilterConstraintExceptionSupplier.missingField("propertyName").get()), + Arguments.of(filterConstraintMissingCapabilityName, FilterConstraintExceptionSupplier.missingField("capabilityName").get()), + Arguments.of(filterConstraintMissingOperator, FilterConstraintExceptionSupplier.missingField("operator").get()), + Arguments.of(filterConstraintMissingTargetType, FilterConstraintExceptionSupplier.missingField("targetType").get()) + ); + } + + @Test + void validateNullFilterConstraint() { + final ByActionStatusComponentException actualException = assertThrows(ByActionStatusComponentException.class, + () -> filterConstraintValidator.validate(null)); + final ByActionStatusComponentException expectedException = FilterConstraintExceptionSupplier.filterConstraintNotProvided().get(); + assertEquals(actualException.getActionStatus(), expectedException.getActionStatus()); + assertArrayEquals(actualException.getParams(), expectedException.getParams()); + } + + private static FilterConstraintDto buildFilterConstraintDto(String propertyName, String capabilityName, ConstraintType constraintType, + FilterValueType filterValueType, PropertyFilterTargetType targetType, Object value) { + final var filterConstraintMissingValueType = new FilterConstraintDto(); + filterConstraintMissingValueType.setPropertyName(propertyName); + filterConstraintMissingValueType.setCapabilityName(capabilityName); + filterConstraintMissingValueType.setTargetType(targetType); + filterConstraintMissingValueType.setOperator(constraintType); + filterConstraintMissingValueType.setValueType(filterValueType); + filterConstraintMissingValueType.setValue(value); + return filterConstraintMissingValueType; + } +}
\ No newline at end of file diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/NodeFilterValidationTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/NodeFilterValidationTest.java deleted file mode 100644 index 621b14102f..0000000000 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/NodeFilterValidationTest.java +++ /dev/null @@ -1,391 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * 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. - * ============LICENSE_END========================================================= - */ - -package org.openecomp.sdc.be.components.validation; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import fj.data.Either; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import org.junit.Assert; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.InjectMocks; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; -import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction; -import org.openecomp.sdc.be.config.ConfigurationManager; -import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; -import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition; -import org.openecomp.sdc.be.datatypes.enums.NodeFilterConstraintType; -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.PropertyDefinition; -import org.openecomp.sdc.be.model.Service; -import org.openecomp.sdc.common.impl.ExternalConfiguration; -import org.openecomp.sdc.common.impl.FSConfigurationSource; -import org.openecomp.sdc.exception.ResponseFormat; - -public class NodeFilterValidationTest { - - private static final String EMPTY_STR = ""; - private static final String UI_CONSTRAINT_STATIC = "Prop1: {equal: 'value'}"; - private static final String INNER_SERVICE = "innerService"; - private static final String PROPERTY_NAME = "Prop1"; - private static final String VALUE = "value"; - private static final String FLOAT_TYPE = "float"; - private static final String STRING_TYPE = "string"; - private static final String LIST_TYPE = "list"; - private static final String COMPONENT1_ID = "component1"; - private static final String INTEGER_TYPE = "integer"; - private static final String PARENTSERVICE_ID = "parentservice"; - private static final String COMPONENT2_ID = "component2"; - private ComponentsUtils componentsUtils; - - @InjectMocks - private NodeFilterValidator nodeFilterValidator; - - @BeforeEach - public void setup() { - componentsUtils = Mockito.mock(ComponentsUtils.class); - MockitoAnnotations.openMocks(this); - new ConfigurationManager(new FSConfigurationSource(ExternalConfiguration.getChangeListener(), "src/test/resources/config/catalog-be")); - } - - @Test - public void testValidateComponentInstanceExist() { - Either<Boolean, ResponseFormat> either = - nodeFilterValidator.validateComponentInstanceExist(null, INNER_SERVICE); - assertTrue(either.isRight()); - assertEquals("Error: Internal Server Error. Please try again later.", either.right().value().getText()); - assertEquals(500, either.right().value().getStatus()); - - Service service = createService("booleanIncorrect"); - either = nodeFilterValidator.validateComponentInstanceExist(service, INNER_SERVICE); - assertTrue(either.isRight()); - assertEquals("Error: Internal Server Error. Please try again later.", either.right().value().getText()); - assertEquals(500, either.right().value().getStatus()); - - List<ComponentInstance> list = new LinkedList<>(); - ComponentInstance instance = new ComponentInstance(); - instance.setUniqueId("uniqueId"); - list.add(instance); - service.setComponentInstances(list); - either = nodeFilterValidator.validateComponentInstanceExist(service, "uniqueId"); - assertTrue(either.isLeft()); - } - - @Test - public void testValidateNodeFilterStaticIncorrectPropertyTypeProvided() { - Service service = createService("booleanIncorrect"); - Either<Boolean, ResponseFormat> either = - nodeFilterValidator.validateFilter(service, INNER_SERVICE, - Collections.singletonList(UI_CONSTRAINT_STATIC.replace(VALUE, "true")), - NodeFilterConstraintAction.ADD, NodeFilterConstraintType.PROPERTIES, EMPTY_STR); - assertTrue(either.isRight()); - - either = - nodeFilterValidator.validateFilter(service, INNER_SERVICE, - Collections.singletonList(UI_CONSTRAINT_STATIC.replace(VALUE, "true")), - NodeFilterConstraintAction.ADD, NodeFilterConstraintType.CAPABILITIES, EMPTY_STR); - assertTrue(either.isRight()); - } - - @Test - public void testValidateComponentFilter() { - Service service = createService("booleanIncorrect"); - String property = "Prop1: {equal: {get_property: ['test','test2']}}"; - Either<Boolean, ResponseFormat> either = - nodeFilterValidator.validateComponentFilter(service, Collections.singletonList(property), - NodeFilterConstraintAction.ADD); - assertTrue(either.isRight()); - - property = "Prop1: {equal: {get_property: ['parentservice','Prop1']}}"; - either = - nodeFilterValidator.validateComponentFilter(service, Collections.singletonList(property), - NodeFilterConstraintAction.ADD); - assertTrue(either.isLeft()); - - String staticStr = "Prop1: {equal: 1}"; - either = nodeFilterValidator.validateComponentFilter(service, Collections.singletonList(staticStr), - NodeFilterConstraintAction.ADD); - assertTrue(either.isLeft()); - assertTrue(either.left().value()); - - staticStr = "Prop1: {equal: 'true'}"; - either = nodeFilterValidator.validateComponentFilter(service, Collections.singletonList(staticStr), - NodeFilterConstraintAction.ADD); - assertTrue(either.isRight()); - - staticStr = "Prop1: {greater_than: '3'}"; - either = nodeFilterValidator.validateComponentFilter(service, Collections.singletonList(staticStr), - NodeFilterConstraintAction.ADD); - assertTrue(either.isRight()); - - staticStr = "test: {greater_than: '3'}"; - either = nodeFilterValidator.validateComponentFilter(service, Collections.singletonList(staticStr), - NodeFilterConstraintAction.ADD); - assertTrue(either.isRight()); - } - - @Test - public void testValidateNodeFilterStaticIncorrectOperatorProvidedBoolean() { - Service service = createService("boolean"); - Either<Boolean, ResponseFormat> either = - nodeFilterValidator.validateFilter(service, INNER_SERVICE, - Collections.singletonList(UI_CONSTRAINT_STATIC.replace(VALUE, "true") - .replace("equal", "greater_than")), - NodeFilterConstraintAction.ADD, NodeFilterConstraintType.PROPERTIES, EMPTY_STR); - - Assert.assertFalse(either.isLeft()); - } - - @Test - public void testValidateNodeFilterStaticIncorrectValueProvidedBoolean() { - Service service = createService("boolean"); - Either<Boolean, ResponseFormat> either = - nodeFilterValidator.validateFilter(service, INNER_SERVICE, - Collections.singletonList(UI_CONSTRAINT_STATIC.replace(VALUE, "trues")), - NodeFilterConstraintAction.ADD, NodeFilterConstraintType.PROPERTIES, EMPTY_STR); - - Assert.assertFalse(either.isLeft()); - } - - @Test - public void testValidateNodeFilterStaticIncorrectOperatorProvidedString() { - Service service = createService(STRING_TYPE); - Either<Boolean, ResponseFormat> either = - nodeFilterValidator.validateFilter(service, INNER_SERVICE, - Collections.singletonList(UI_CONSTRAINT_STATIC.replace(VALUE, "true") - .replace("equal", "greater_than")), - NodeFilterConstraintAction.ADD, NodeFilterConstraintType.PROPERTIES, EMPTY_STR); - - Assert.assertTrue(either.isLeft()); - } - - @Test - public void testValidateNodeFilterIntegerValueSuccess() { - Service service = createService(INTEGER_TYPE); - Either<Boolean, ResponseFormat> either = - nodeFilterValidator.validateFilter(service, INNER_SERVICE, - Collections.singletonList(UI_CONSTRAINT_STATIC.replace(VALUE, "1")), - NodeFilterConstraintAction.ADD, NodeFilterConstraintType.PROPERTIES, EMPTY_STR); - - Assert.assertTrue(either.isLeft()); - } - - @Test - public void testValidateNodeFilterIntegerValueFail() { - Service service = createService(INTEGER_TYPE); - - Mockito.when(componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_VALUE_PROVIDED, "param1")) - .thenReturn(new ResponseFormat()); - - Either<Boolean, ResponseFormat> either = - nodeFilterValidator.validateFilter(service, INNER_SERVICE, - Collections.singletonList(UI_CONSTRAINT_STATIC.replace(VALUE, "1.0")), - NodeFilterConstraintAction.ADD, NodeFilterConstraintType.PROPERTIES, EMPTY_STR); - - Assert.assertTrue(either.isRight()); - } - - @Test - public void testValidateNodeFilterFloatValueSuccess() { - Service service = createService(FLOAT_TYPE); - Either<Boolean, ResponseFormat> either = - nodeFilterValidator.validateFilter(service, INNER_SERVICE, - Collections.singletonList(UI_CONSTRAINT_STATIC.replace(VALUE, "1.0")), - NodeFilterConstraintAction.ADD, NodeFilterConstraintType.PROPERTIES, EMPTY_STR); - - Assert.assertTrue(either.isLeft()); - } - - @Test - public void testValidateNodeFilterFloatValueFail() { - Service service = createService(FLOAT_TYPE); - - Mockito.when(componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_VALUE_PROVIDED, "param1")) - .thenReturn(new ResponseFormat()); - - Either<Boolean, ResponseFormat> either = - nodeFilterValidator.validateFilter(service, INNER_SERVICE, - Collections.singletonList(UI_CONSTRAINT_STATIC), NodeFilterConstraintAction.ADD, - NodeFilterConstraintType.PROPERTIES, EMPTY_STR); - - Assert.assertTrue(either.isRight()); - } - - @Test - public void testValidateNodeFilterStringValueSuccess() { - Service service = createService(STRING_TYPE); - Either<Boolean, ResponseFormat> either = - nodeFilterValidator.validateFilter(service, INNER_SERVICE, - Collections.singletonList(UI_CONSTRAINT_STATIC), NodeFilterConstraintAction.ADD, - NodeFilterConstraintType.PROPERTIES, EMPTY_STR); - - Assert.assertTrue(either.isLeft()); - } - - @Test - public void testValidatePropertyConstraintBrotherSuccess() { - Service service = createService(STRING_TYPE); - Either<Boolean, ResponseFormat> either = - nodeFilterValidator.validateFilter(service, COMPONENT1_ID, Collections.singletonList("Prop1:\n" - + " equal: { get_property :[component2, Prop1]}\n"), NodeFilterConstraintAction.ADD, - NodeFilterConstraintType.PROPERTIES, EMPTY_STR); - - Assert.assertTrue(either.isLeft()); - } - - @Test - public void testValidatePropertyConstraintParentSuccess() { - Service service = createService(STRING_TYPE); - Either<Boolean, ResponseFormat> either = - nodeFilterValidator.validateFilter(service, COMPONENT1_ID, Collections.singletonList("Prop1:\n" - + " equal: { get_property : [SELF, Prop1]}\n"), NodeFilterConstraintAction.ADD, - NodeFilterConstraintType.PROPERTIES, EMPTY_STR); - - Assert.assertTrue(either.isLeft()); - } - - @Test - public void testValidatePropertyConstraintBrotherPropertyTypeMismatch() { - Service service = createService(STRING_TYPE); - service.getComponentInstancesProperties().get(COMPONENT2_ID).get(0).setType(INTEGER_TYPE); - - Either<Boolean, ResponseFormat> either = - nodeFilterValidator.validateFilter(service, COMPONENT1_ID, Collections.singletonList("Prop1:\n" - + " equal: { get_property : [component2, Prop1]}\n"), NodeFilterConstraintAction.ADD, - NodeFilterConstraintType.PROPERTIES, EMPTY_STR); - - Assert.assertFalse(either.isLeft()); - } - - @Test - public void testValidatePropertyConstraintParentPropertyTypeMismatch() { - Service service = createService(STRING_TYPE); - service.getComponentInstancesProperties().get(COMPONENT1_ID).get(0).setType(INTEGER_TYPE); - - Either<Boolean, ResponseFormat> either = - nodeFilterValidator.validateFilter(service, COMPONENT1_ID, Collections.singletonList("Prop1:\n" - + " equal: { get_property : [parentservice, Prop1]}\n"), NodeFilterConstraintAction.ADD, - NodeFilterConstraintType.PROPERTIES, EMPTY_STR); - - Assert.assertFalse(either.isLeft()); - } - - @Test - public void testValidatePropertyConstraintParentPropertyNotFound() { - Service service = createService(STRING_TYPE); - service.getComponentInstancesProperties().get(COMPONENT1_ID).get(0).setName("Prop2"); - - Either<Boolean, ResponseFormat> either = - nodeFilterValidator.validateFilter(service, COMPONENT1_ID, Collections.singletonList("Prop1:\n" - + " equal: { get_property : [parentservice, Prop1]}\n"), NodeFilterConstraintAction.ADD, - NodeFilterConstraintType.PROPERTIES, EMPTY_STR); - - Assert.assertFalse(either.isLeft()); - } - - @Test - public void testvalidatePropertyConstraintBrotherPropertyNotFound() { - Service service = createService(STRING_TYPE); - service.getComponentInstancesProperties().get(COMPONENT1_ID).get(0).setName("Prop2"); - - Either<Boolean, ResponseFormat> either = - nodeFilterValidator.validateFilter(service, COMPONENT1_ID, Collections.singletonList("Prop1:\n" - + " equal: { get_property : [parentservice, Prop1]}\n"), NodeFilterConstraintAction.ADD, - NodeFilterConstraintType.PROPERTIES, EMPTY_STR); - - Assert.assertFalse(either.isLeft()); - } - - @Test - public void testValidatePropertyConstraintParentPropertySchemaMismatch() { - Service service = createService(LIST_TYPE,STRING_TYPE); - service.getComponentInstancesProperties().get(COMPONENT1_ID).get(0).setType(LIST_TYPE); - - Either<Boolean, ResponseFormat> either = - nodeFilterValidator.validateFilter(service, COMPONENT1_ID, Collections.singletonList("Prop1:\n" - + " equal: { get_property : [parentservice, Prop1]}\n"), NodeFilterConstraintAction.ADD, - NodeFilterConstraintType.PROPERTIES, EMPTY_STR); - - Assert.assertFalse(either.isLeft()); - } - - private Service createService(String type) { - return createService(type, null); - } - - private Service createService(String type, String schemaType) { - Service service = new Service(); - service.setName(PARENTSERVICE_ID); - - PropertyDefinition propertyDefinition = new PropertyDefinition(); - propertyDefinition.setName(PROPERTY_NAME); - propertyDefinition.setType(type); - if (schemaType != null){ - SchemaDefinition schemaDefinition = new SchemaDefinition(); - PropertyDataDefinition schemaProperty = new PropertyDataDefinition(); - schemaProperty.setType(schemaType); - schemaDefinition.setProperty(schemaProperty); - propertyDefinition.setSchema(schemaDefinition); - } - service.setProperties(Collections.singletonList(propertyDefinition)); - - ComponentInstance componentInstance = new ComponentInstance(); - componentInstance.setUniqueId(COMPONENT1_ID); - componentInstance.setName(COMPONENT1_ID); - - ComponentInstance componentInstance2 = new ComponentInstance(); - componentInstance2.setUniqueId(COMPONENT2_ID); - componentInstance2.setName(COMPONENT2_ID); - - service.setComponentInstances(Arrays.asList(componentInstance, componentInstance2)); - - ComponentInstanceProperty componentInstanceProperty = new ComponentInstanceProperty(); - componentInstanceProperty.setName(PROPERTY_NAME); - componentInstanceProperty.setType(type); - - ComponentInstanceProperty componentInstanceProperty2 = new ComponentInstanceProperty(); - componentInstanceProperty2.setName(PROPERTY_NAME); - componentInstanceProperty2.setType(type); - - Map<String, List<ComponentInstanceProperty>> componentInstancePropertyMap = new HashMap<>(); - componentInstancePropertyMap.put(componentInstance.getUniqueId(), - Collections.singletonList(componentInstanceProperty)); - componentInstancePropertyMap.put(componentInstance2.getUniqueId(), - Collections.singletonList(componentInstanceProperty2)); - componentInstancePropertyMap.put(INNER_SERVICE, Collections.singletonList(componentInstanceProperty)); - - service.setComponentInstancesProperties(componentInstancePropertyMap); - - return service; - } - -} 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 new file mode 100644 index 0000000000..e1d8e46d74 --- /dev/null +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/NodeFilterValidatorTest.java @@ -0,0 +1,553 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.components.validation; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +import fj.data.Either; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +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.datatypes.elements.PropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition; +import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; +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.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache; +import org.openecomp.sdc.be.model.dto.FilterConstraintDto; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.openecomp.sdc.be.model.validation.FilterConstraintValidator; +import org.openecomp.sdc.common.impl.ExternalConfiguration; +import org.openecomp.sdc.common.impl.FSConfigurationSource; +import org.openecomp.sdc.exception.ResponseFormat; + +class NodeFilterValidatorTest { + + private static final String INNER_SERVICE = "innerService"; + private static final String PROPERTY_NAME = "Prop1"; + private static final String COMPONENT1_ID = "component1"; + private static final String PARENTSERVICE_ID = "parentservice"; + private static final String COMPONENT2_ID = "component2"; + private ComponentsUtils componentsUtils; + + @Mock + ApplicationDataTypeCache applicationDataTypeCache; + @Mock + private FilterConstraintValidator filterConstraintValidator; + @InjectMocks + private NodeFilterValidator nodeFilterValidator; + private FilterConstraintDto baseFilterConstraintDto; + + @BeforeEach + void setup() { + componentsUtils = Mockito.mock(ComponentsUtils.class); + MockitoAnnotations.openMocks(this); + baseFilterConstraintDto = new FilterConstraintDto(); + baseFilterConstraintDto.setPropertyName(PROPERTY_NAME); + baseFilterConstraintDto.setValueType(FilterValueType.STATIC); + baseFilterConstraintDto.setOperator(ConstraintType.EQUAL); + baseFilterConstraintDto.setTargetType(PropertyFilterTargetType.PROPERTY); + baseFilterConstraintDto.setValue("value"); + when(applicationDataTypeCache.getAll(any())).thenReturn(Either.left(Map.of())); + new ConfigurationManager(new FSConfigurationSource(ExternalConfiguration.getChangeListener(), "src/test/resources/config/catalog-be")); + } + + @Test + void testValidateComponentInstanceExist() { + final ResponseFormat expectedResponse = new ResponseFormat(); + when(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND, "?", INNER_SERVICE)).thenReturn(expectedResponse); + Either<Boolean, ResponseFormat> either = + nodeFilterValidator.validateComponentInstanceExist(null, INNER_SERVICE); + assertTrue(either.isRight()); + assertEquals(expectedResponse, either.right().value()); + + Service service = createService("booleanIncorrect"); + when(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND, service.getName(), INNER_SERVICE)) + .thenReturn(expectedResponse); + either = nodeFilterValidator.validateComponentInstanceExist(service, INNER_SERVICE); + assertTrue(either.isRight()); + assertEquals(expectedResponse, either.right().value()); + + List<ComponentInstance> list = new LinkedList<>(); + ComponentInstance instance = new ComponentInstance(); + instance.setUniqueId("uniqueId"); + list.add(instance); + service.setComponentInstances(list); + either = nodeFilterValidator.validateComponentInstanceExist(service, "uniqueId"); + assertTrue(either.isLeft()); + } + + @Test + void testValidateNodeFilterStaticIncorrectPropertyTypeProvided() { + final Service service = createService("booleanIncorrect"); + final FilterConstraintDto filterConstraintDto = buildFilterConstraintDto(PROPERTY_NAME, FilterValueType.STATIC, ConstraintType.EQUAL, + PropertyFilterTargetType.PROPERTY, "true"); + Either<Boolean, ResponseFormat> either = + nodeFilterValidator.validateFilter(service, INNER_SERVICE, filterConstraintDto); + assertTrue(either.isRight()); + filterConstraintDto.setTargetType(PropertyFilterTargetType.CAPABILITY); + either = nodeFilterValidator.validateFilter(service, INNER_SERVICE, filterConstraintDto); + assertTrue(either.isRight()); + } + + @Test + void testValidateComponentFilter() { + Service service = createService("integer"); + final var filterConstraint1 = buildFilterConstraintDto( + PROPERTY_NAME, + FilterValueType.GET_PROPERTY, + ConstraintType.EQUAL, + PropertyFilterTargetType.PROPERTY, + createToscaGetFunction("test", PropertySource.INSTANCE, ToscaGetFunctionType.GET_PROPERTY, List.of("test2")) + ); + Either<Boolean, ResponseFormat> actualValidationResult = + nodeFilterValidator.validateSubstitutionFilter(service, Collections.singletonList(filterConstraint1)); + assertTrue(actualValidationResult.isRight()); + + final var filterConstraint2 = buildFilterConstraintDto( + PROPERTY_NAME, + FilterValueType.GET_PROPERTY, + ConstraintType.EQUAL, + PropertyFilterTargetType.PROPERTY, + createToscaGetFunction(PARENTSERVICE_ID, PropertySource.SELF, ToscaGetFunctionType.GET_PROPERTY, List.of("Prop1")) + ); + actualValidationResult = + nodeFilterValidator.validateSubstitutionFilter(service, Collections.singletonList(filterConstraint2)); + assertTrue(actualValidationResult.isLeft()); + + final var staticFilter1 = buildFilterConstraintDto( + PROPERTY_NAME, + FilterValueType.STATIC, + ConstraintType.EQUAL, + PropertyFilterTargetType.PROPERTY, + 1 + ); + actualValidationResult = nodeFilterValidator.validateSubstitutionFilter(service, List.of(staticFilter1)); + assertTrue(actualValidationResult.isLeft()); + assertTrue(actualValidationResult.left().value()); + + final var staticFilter2 = buildFilterConstraintDto( + PROPERTY_NAME, + FilterValueType.STATIC, + ConstraintType.EQUAL, + PropertyFilterTargetType.PROPERTY, + "true" + ); + actualValidationResult = nodeFilterValidator.validateSubstitutionFilter(service, List.of(staticFilter2)); + assertTrue(actualValidationResult.isRight()); + + service = createService(ToscaPropertyType.BOOLEAN.getType()); + final var staticFilter3 = buildFilterConstraintDto( + PROPERTY_NAME, + FilterValueType.STATIC, + ConstraintType.GREATER_THAN, + PropertyFilterTargetType.PROPERTY, + "3" + ); + actualValidationResult = nodeFilterValidator.validateSubstitutionFilter(service, List.of(staticFilter3)); + assertTrue(actualValidationResult.isRight()); + + final var staticFilter4 = buildFilterConstraintDto( + "test", + FilterValueType.STATIC, + ConstraintType.GREATER_THAN, + PropertyFilterTargetType.PROPERTY, + "3" + ); + actualValidationResult = nodeFilterValidator.validateSubstitutionFilter(service, Collections.singletonList(staticFilter4)); + assertTrue(actualValidationResult.isRight()); + } + + @Test + void testValidateNodeFilterStaticIncorrectOperatorProvidedBoolean() { + Service service = createService(ToscaPropertyType.BOOLEAN.getType()); + final FilterConstraintDto filterConstraintDto = buildFilterConstraintDto( + PROPERTY_NAME, + FilterValueType.STATIC, + ConstraintType.GREATER_THAN, + PropertyFilterTargetType.PROPERTY, + "true" + ); + final ResponseFormat expectedResponse = new ResponseFormat(); + when(componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_OPERATOR_PROVIDED, filterConstraintDto.getPropertyName(), + filterConstraintDto.getOperator().getType()) + ).thenReturn(expectedResponse); + final Either<Boolean, ResponseFormat> validationResult = + nodeFilterValidator.validateFilter(service, INNER_SERVICE, List.of(filterConstraintDto)); + assertTrue(validationResult.isRight()); + assertEquals(expectedResponse, validationResult.right().value()); + } + + @Test + void testValidateNodeFilterStaticIncorrectValueProvidedBoolean() { + final Service service = createService(ToscaPropertyType.BOOLEAN.getType()); + baseFilterConstraintDto.setValue("trues"); + + final ResponseFormat responseFormat = new ResponseFormat(); + when(componentsUtils + .getResponseFormat(eq(ActionStatus.UNSUPPORTED_VALUE_PROVIDED), eq(ToscaPropertyType.BOOLEAN.getType()), eq(PROPERTY_NAME), any()) + ).thenReturn(responseFormat); + final Either<Boolean, ResponseFormat> validationResult = + nodeFilterValidator.validateFilter(service, INNER_SERVICE, List.of(baseFilterConstraintDto)); + + assertTrue(validationResult.isRight()); + assertEquals(responseFormat, validationResult.right().value()); + } + + @Test + void testValidateNodeFilterStaticIncorrectOperatorProvidedString() { + Service service = createService(ToscaPropertyType.STRING.getType()); + baseFilterConstraintDto.setValue("true"); + baseFilterConstraintDto.setOperator(ConstraintType.GREATER_THAN); + Either<Boolean, ResponseFormat> either = + nodeFilterValidator.validateFilter(service, INNER_SERVICE, List.of(baseFilterConstraintDto)); + + assertTrue(either.isLeft()); + } + + @Test + void testValidateNodeFilterIntegerValueSuccess() { + Service service = createService(ToscaPropertyType.INTEGER.getType()); + baseFilterConstraintDto.setValue(1); + Either<Boolean, ResponseFormat> validationResult = + nodeFilterValidator.validateFilter(service, INNER_SERVICE, List.of(baseFilterConstraintDto)); + + assertTrue(validationResult.isLeft()); + } + + @Test + void testValidateNodeFilterIntegerValueFail() { + Service service = createService(ToscaPropertyType.INTEGER.getType()); + + baseFilterConstraintDto.setValue(1.0); + + final ResponseFormat expectedResponse = new ResponseFormat(); + when(componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_VALUE_PROVIDED, ToscaPropertyType.INTEGER.getType(), + baseFilterConstraintDto.getPropertyName(), "1.0") + ).thenReturn(expectedResponse); + Either<Boolean, ResponseFormat> validationResult = + nodeFilterValidator.validateFilter(service, INNER_SERVICE, List.of(baseFilterConstraintDto)); + + assertTrue(validationResult.isRight()); + assertEquals(expectedResponse, validationResult.right().value()); + } + + @Test + void testValidateNodeFilterFloatValueSuccess() { + final Service service = createService(ToscaPropertyType.FLOAT.getType()); + baseFilterConstraintDto.setValue(1.0); + final Either<Boolean, ResponseFormat> validationResult = + nodeFilterValidator.validateFilter(service, INNER_SERVICE, List.of(baseFilterConstraintDto)); + + assertTrue(validationResult.isLeft()); + assertTrue(validationResult.left().value()); + } + + @Test + void testValidateNodeFilterFloatValueFail() { + Service service = createService(ToscaPropertyType.FLOAT.getType()); + + when(componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_VALUE_PROVIDED, "param1")).thenReturn(new ResponseFormat()); + + Either<Boolean, ResponseFormat> either = + nodeFilterValidator.validateFilter(service, INNER_SERVICE, List.of(baseFilterConstraintDto)); + + assertTrue(either.isRight()); + } + + @Test + void testValidateNodeFilterStringValueSuccess() { + Service service = createService(ToscaPropertyType.STRING.getType()); + Either<Boolean, ResponseFormat> either = + nodeFilterValidator.validateFilter(service, INNER_SERVICE, List.of(baseFilterConstraintDto)); + + assertTrue(either.isLeft()); + } + + @Test + void testValidatePropertyConstraintBrotherSuccess() { + Service service = createService(ToscaPropertyType.STRING.getType()); + final ToscaGetFunctionDataDefinition toscaGetFunction = + createToscaGetFunction(COMPONENT2_ID, PropertySource.INSTANCE, ToscaGetFunctionType.GET_PROPERTY, List.of(PROPERTY_NAME)); + final var filterConstraintDto = buildFilterConstraintDto( + PROPERTY_NAME, + FilterValueType.GET_PROPERTY, + ConstraintType.EQUAL, + PropertyFilterTargetType.PROPERTY, + toscaGetFunction + ); + Either<Boolean, ResponseFormat> either = + nodeFilterValidator.validateFilter(service, COMPONENT1_ID, List.of(filterConstraintDto)); + + assertTrue(either.isLeft()); + assertTrue(either.left().value()); + } + + @Test + void testValidatePropertyConstraintParentSuccess() { + final var service = createService(ToscaPropertyType.STRING.getType()); + final ToscaGetFunctionDataDefinition toscaGetFunction = + createToscaGetFunction(PARENTSERVICE_ID, PropertySource.SELF, ToscaGetFunctionType.GET_PROPERTY, List.of(PROPERTY_NAME)); + final var filterConstraintDto = buildFilterConstraintDto( + PROPERTY_NAME, + FilterValueType.GET_PROPERTY, + ConstraintType.EQUAL, + PropertyFilterTargetType.PROPERTY, + toscaGetFunction + ); + final Either<Boolean, ResponseFormat> validationResult = + nodeFilterValidator.validateFilter(service, COMPONENT1_ID, List.of(filterConstraintDto)); + + assertTrue(validationResult.isLeft()); + assertTrue(validationResult.left().value()); + } + + @Test + void testValidatePropertyConstraintBrotherPropertyTypeMismatch() { + 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)); + final var filterConstraintDto = buildFilterConstraintDto( + PROPERTY_NAME, + FilterValueType.GET_PROPERTY, + ConstraintType.EQUAL, + PropertyFilterTargetType.PROPERTY, + toscaGetFunction + ); + + final ResponseFormat expectedResponse = new ResponseFormat(); + when(componentsUtils.getResponseFormat(ActionStatus.SOURCE_TARGET_PROPERTY_TYPE_MISMATCH, + PROPERTY_NAME, ToscaPropertyType.INTEGER.getType(), PROPERTY_NAME, ToscaPropertyType.STRING.getType()) + ).thenReturn(expectedResponse); + + final Either<Boolean, ResponseFormat> either = + nodeFilterValidator.validateFilter(service, COMPONENT1_ID, List.of(filterConstraintDto)); + + assertTrue(either.isRight()); + assertEquals(expectedResponse, either.right().value()); + } + + @Test + void testValidatePropertyConstraintParentPropertyTypeMismatch() { + final Service service = createService(ToscaPropertyType.STRING.getType()); + service.getComponentInstancesProperties().get(COMPONENT1_ID).get(0).setType(ToscaPropertyType.INTEGER.getType()); + final ToscaGetFunctionDataDefinition toscaGetFunction = + createToscaGetFunction(PARENTSERVICE_ID, PropertySource.SELF, ToscaGetFunctionType.GET_PROPERTY, List.of(PROPERTY_NAME)); + final var filterConstraintDto = buildFilterConstraintDto( + PROPERTY_NAME, + FilterValueType.GET_PROPERTY, + ConstraintType.EQUAL, + PropertyFilterTargetType.PROPERTY, + toscaGetFunction + ); + + final ResponseFormat expectedResponse = new ResponseFormat(); + when(componentsUtils.getResponseFormat(ActionStatus.SOURCE_TARGET_PROPERTY_TYPE_MISMATCH, + PROPERTY_NAME, ToscaPropertyType.STRING.getType(), PROPERTY_NAME, ToscaPropertyType.INTEGER.getType()) + ).thenReturn(expectedResponse); + + Either<Boolean, ResponseFormat> either = + nodeFilterValidator.validateFilter(service, COMPONENT1_ID, List.of(filterConstraintDto)); + + assertTrue(either.isRight()); + assertEquals(expectedResponse, either.right().value()); + } + + @Test + void testValidatePropertyConstraintParentPropertyNotFound() { + final Service service = createService(ToscaPropertyType.STRING.getType()); + service.getComponentInstancesProperties().get(COMPONENT1_ID).get(0).setName("Prop2"); + + final ResponseFormat expectedResponse = new ResponseFormat(); + when(componentsUtils.getResponseFormat(eq(ActionStatus.FILTER_PROPERTY_NOT_FOUND), any(), any())) + .thenReturn(expectedResponse); + + final ToscaGetFunctionDataDefinition toscaGetFunction = + createToscaGetFunction(PARENTSERVICE_ID, PropertySource.SELF, ToscaGetFunctionType.GET_PROPERTY, List.of(PROPERTY_NAME)); + final var filterConstraintDto = buildFilterConstraintDto( + PROPERTY_NAME, + FilterValueType.GET_PROPERTY, + ConstraintType.EQUAL, + PropertyFilterTargetType.PROPERTY, + toscaGetFunction + ); + final Either<Boolean, ResponseFormat> validationResult = + nodeFilterValidator.validateFilter(service, COMPONENT1_ID, List.of(filterConstraintDto)); + + assertTrue(validationResult.isRight()); + assertEquals(expectedResponse, validationResult.right().value()); + } + + @Test + void testValidatePropertyConstraintBrotherPropertyNotFound() { + Service service = createService(ToscaPropertyType.STRING.getType()); + service.getComponentInstancesProperties().get(COMPONENT1_ID).get(0).setName("Prop2"); + final ToscaGetFunctionDataDefinition toscaGetFunction = + createToscaGetFunction(PARENTSERVICE_ID, PropertySource.SELF, ToscaGetFunctionType.GET_PROPERTY, List.of(PROPERTY_NAME)); + final var filterConstraintDto = buildFilterConstraintDto( + PROPERTY_NAME, + FilterValueType.GET_PROPERTY, + ConstraintType.EQUAL, + PropertyFilterTargetType.PROPERTY, + toscaGetFunction + ); + final ResponseFormat expectedResponse = new ResponseFormat(); + when(componentsUtils.getResponseFormat(ActionStatus.FILTER_PROPERTY_NOT_FOUND, "Target", PROPERTY_NAME)) + .thenReturn(expectedResponse); + Either<Boolean, ResponseFormat> either = + nodeFilterValidator.validateFilter(service, COMPONENT1_ID, List.of(filterConstraintDto)); + + assertTrue(either.isRight()); + assertEquals(expectedResponse, either.right().value()); + } + + protected static ToscaGetFunctionDataDefinition createToscaGetFunction(final String sourceName, + final PropertySource propertySource, + final ToscaGetFunctionType toscaGetFunctionType, + final List<String> propertyPathFromSource) { + final var toscaGetFunction = new ToscaGetFunctionDataDefinition(); + toscaGetFunction.setFunctionType(toscaGetFunctionType); + toscaGetFunction.setPropertyPathFromSource(propertyPathFromSource); + toscaGetFunction.setSourceName(sourceName); + toscaGetFunction.setPropertySource(propertySource); + toscaGetFunction.setPropertyName(propertyPathFromSource.get(0)); + return toscaGetFunction; + } + + @Test + void testValidatePropertyConstraintParentPropertySchemaMismatch() { + final Service service = createService(ToscaPropertyType.LIST.getType(), ToscaPropertyType.STRING.getType()); + service.getComponentInstancesProperties().get(COMPONENT1_ID).get(0).setType(ToscaPropertyType.LIST.getType()); + final var schemaProperty = new PropertyDataDefinition(); + schemaProperty.setType(ToscaPropertyType.INTEGER.getType()); + final var schemaDefinition = new SchemaDefinition(); + schemaDefinition.setProperty(schemaProperty); + service.getComponentInstancesProperties().get(COMPONENT1_ID).get(0).setSchema(schemaDefinition); + + final ToscaGetFunctionDataDefinition toscaGetFunction = + createToscaGetFunction(PARENTSERVICE_ID, PropertySource.SELF, ToscaGetFunctionType.GET_PROPERTY, List.of(PROPERTY_NAME)); + final var filterConstraintDto = buildFilterConstraintDto( + PROPERTY_NAME, + FilterValueType.GET_PROPERTY, + ConstraintType.EQUAL, + PropertyFilterTargetType.PROPERTY, + toscaGetFunction + ); + + final ResponseFormat expectedResponse = new ResponseFormat(); + when(componentsUtils.getResponseFormat(ActionStatus.SOURCE_TARGET_SCHEMA_MISMATCH, PROPERTY_NAME, ToscaPropertyType.INTEGER.getType(), + PROPERTY_NAME, ToscaPropertyType.STRING.getType()) + ).thenReturn(expectedResponse); + + Either<Boolean, ResponseFormat> either = + nodeFilterValidator.validateFilter(service, COMPONENT1_ID, List.of(filterConstraintDto)); + + assertTrue(either.isRight()); + assertEquals(expectedResponse, either.right().value()); + } + + private Service createService(String type) { + return createService(type, null); + } + + private Service createService(String type, String schemaType) { + Service service = new Service(); + service.setName(PARENTSERVICE_ID); + + PropertyDefinition propertyDefinition = new PropertyDefinition(); + propertyDefinition.setName(PROPERTY_NAME); + propertyDefinition.setType(type); + if (schemaType != null){ + SchemaDefinition schemaDefinition = new SchemaDefinition(); + PropertyDataDefinition schemaProperty = new PropertyDataDefinition(); + schemaProperty.setType(schemaType); + schemaDefinition.setProperty(schemaProperty); + propertyDefinition.setSchema(schemaDefinition); + } + service.setProperties(Collections.singletonList(propertyDefinition)); + + ComponentInstance componentInstance = new ComponentInstance(); + componentInstance.setUniqueId(COMPONENT1_ID); + componentInstance.setName(COMPONENT1_ID); + + ComponentInstance componentInstance2 = new ComponentInstance(); + componentInstance2.setUniqueId(COMPONENT2_ID); + componentInstance2.setName(COMPONENT2_ID); + + service.setComponentInstances(Arrays.asList(componentInstance, componentInstance2)); + + ComponentInstanceProperty componentInstanceProperty = new ComponentInstanceProperty(); + componentInstanceProperty.setName(PROPERTY_NAME); + componentInstanceProperty.setType(type); + + ComponentInstanceProperty componentInstanceProperty2 = new ComponentInstanceProperty(); + componentInstanceProperty2.setName(PROPERTY_NAME); + componentInstanceProperty2.setType(type); + + Map<String, List<ComponentInstanceProperty>> componentInstancePropertyMap = new HashMap<>(); + componentInstancePropertyMap.put(componentInstance.getUniqueId(), + Collections.singletonList(componentInstanceProperty)); + componentInstancePropertyMap.put(componentInstance2.getUniqueId(), + Collections.singletonList(componentInstanceProperty2)); + componentInstancePropertyMap.put(INNER_SERVICE, Collections.singletonList(componentInstanceProperty)); + + service.setComponentInstancesProperties(componentInstancePropertyMap); + + return service; + } + + private static FilterConstraintDto buildFilterConstraintDto(final String propertyName, final FilterValueType valueType, + final ConstraintType constraintType, + final PropertyFilterTargetType targetType, Object value) { + final var filterConstraintDto = new FilterConstraintDto(); + filterConstraintDto.setPropertyName(propertyName); + filterConstraintDto.setValueType(valueType); + filterConstraintDto.setOperator(constraintType); + filterConstraintDto.setTargetType(targetType); + filterConstraintDto.setValue(value); + return filterConstraintDto; + } + +} diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/datamodel/UiComponentDataConverterTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/datamodel/UiComponentDataConverterTest.java index 9864cf456d..a66b19d1b3 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/datamodel/UiComponentDataConverterTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/datamodel/UiComponentDataConverterTest.java @@ -19,10 +19,9 @@ package org.openecomp.sdc.be.datamodel; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertEquals; import static org.hibernate.validator.internal.util.CollectionHelper.asSet; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -47,8 +46,12 @@ import org.openecomp.sdc.be.datamodel.utils.UiComponentDataConverter; import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition; import org.openecomp.sdc.be.datatypes.elements.GetPolicyValueDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; -import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterPropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyFilterConstraintDataDefinition; import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterPropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; +import org.openecomp.sdc.be.datatypes.enums.FilterValueType; +import org.openecomp.sdc.be.datatypes.enums.PropertyFilterTargetType; import org.openecomp.sdc.be.model.ComponentInstanceProperty; import org.openecomp.sdc.be.model.GroupDefinition; import org.openecomp.sdc.be.model.InputDefinition; @@ -336,15 +339,27 @@ public class UiComponentDataConverterTest { SubstitutionFilterDataDefinition substitutionFilter = new SubstitutionFilterDataDefinition(); substitutionFilter.setID(SUBSTITUTION_FILTER_UID); - final ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> expectedPropertyFilters = new ListDataDefinition<>(); - var filter1 = new RequirementSubstitutionFilterPropertyDataDefinition(); + final ListDataDefinition<SubstitutionFilterPropertyDataDefinition> expectedPropertyFilters = new ListDataDefinition<>(); + var filter1 = new SubstitutionFilterPropertyDataDefinition(); filter1.setName("filter1"); - filter1.setConstraints(Collections.singletonList("constraint1: {equal: testvalue1}\n")); + var propertyFilter1 = new PropertyFilterConstraintDataDefinition(); + propertyFilter1.setPropertyName("constraint1"); + propertyFilter1.setOperator(ConstraintType.EQUAL); + propertyFilter1.setValueType(FilterValueType.STATIC); + propertyFilter1.setTargetType(PropertyFilterTargetType.PROPERTY); + propertyFilter1.setValue("testvalue1"); + filter1.setConstraints(List.of(propertyFilter1)); expectedPropertyFilters.add(filter1); - var filter2 = new RequirementSubstitutionFilterPropertyDataDefinition(); + var filter2 = new SubstitutionFilterPropertyDataDefinition(); filter2.setName("filter2"); - filter2.setConstraints(Collections.singletonList("constraint2: {equal: testvalue2}\n")); + var propertyFilter2 = new PropertyFilterConstraintDataDefinition(); + propertyFilter2.setPropertyName("constraint2"); + propertyFilter2.setOperator(ConstraintType.EQUAL); + propertyFilter2.setValueType(FilterValueType.STATIC); + propertyFilter2.setTargetType(PropertyFilterTargetType.PROPERTY); + propertyFilter2.setValue("testvalue2"); + filter2.setConstraints(List.of(propertyFilter2)); expectedPropertyFilters.add(filter2); substitutionFilter.setProperties(expectedPropertyFilters); diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/model/ConstraintConvertorTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/datamodel/utils/ConstraintConvertorTest.java index 109af5562a..75eb48b86c 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/model/ConstraintConvertorTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/datamodel/utils/ConstraintConvertorTest.java @@ -13,33 +13,34 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.openecomp.sdc.be.tosca.model; -import org.junit.Test; -import org.openecomp.sdc.be.datamodel.utils.ConstraintConvertor; -import org.openecomp.sdc.be.ui.model.UIConstraint; +package org.openecomp.sdc.be.datamodel.utils; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.List; import java.util.Map; +import org.junit.jupiter.api.Test; +import org.openecomp.sdc.be.datatypes.elements.ToscaFunctionType; +import org.openecomp.sdc.be.ui.model.UIConstraint; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -public class ConstraintConvertorTest { +class ConstraintConvertorTest { @Test - public void convertStatic(){ + void convertStatic(){ ConstraintConvertor constraintConvertor = new ConstraintConvertor(); UIConstraint uiConstraint = constraintConvertor.convert("mem_size: {equal: some static}\n"); assertNotNull(uiConstraint); - assertEquals(uiConstraint.getConstraintOperator(),"equal"); - assertEquals(uiConstraint.getValue(),"some static"); - assertEquals(uiConstraint.getServicePropertyName().trim(),"mem_size"); + assertEquals("equal",uiConstraint.getConstraintOperator()); + assertEquals("some static",uiConstraint.getValue()); + assertEquals("mem_size",uiConstraint.getServicePropertyName().trim()); } @Test - public void convertFromStatic(){ + void convertFromStatic(){ ConstraintConvertor constraintConvertor = new ConstraintConvertor(); UIConstraint uiConstraint = new UIConstraint("mem_size", "equal" , ConstraintConvertor.STATIC_CONSTRAINT, "some static"); String constraint = constraintConvertor.convert(uiConstraint); @@ -48,19 +49,19 @@ public class ConstraintConvertorTest { } @Test - public void convertSelfProperty(){ + void convertSelfProperty(){ ConstraintConvertor constraintConvertor = new ConstraintConvertor(); UIConstraint uiConstraint = constraintConvertor.convert("mem_size:\n {equal: { get_property: [SELF, size] }}"); assertNotNull(uiConstraint); - assertEquals(uiConstraint.getConstraintOperator(),"equal"); - assertEquals(uiConstraint.getValue(),"size"); - assertEquals(uiConstraint.getServicePropertyName().trim(),"mem_size"); - assertEquals(uiConstraint.getSourceName().trim(),"SELF"); - assertEquals(uiConstraint.getSourceType(), ConstraintConvertor.PROPERTY_CONSTRAINT); + assertEquals("equal",uiConstraint.getConstraintOperator()); + assertEquals(uiConstraint.getValue(), Map.of(ToscaFunctionType.GET_PROPERTY.getName(), List.of("SELF", "size"))); + assertEquals("mem_size",uiConstraint.getServicePropertyName().trim()); + assertEquals("SELF",uiConstraint.getSourceName().trim()); + assertEquals(uiConstraint.getSourceType(), ToscaFunctionType.GET_PROPERTY.getName()); } @Test - public void convertFromSelfProperty(){ + void convertFromSelfProperty(){ ConstraintConvertor constraintConvertor = new ConstraintConvertor(); UIConstraint uiConstraint = new UIConstraint("mem_size", "equal" , ConstraintConvertor.PROPERTY_CONSTRAINT, "SELF" ,"some static"); String constraint = constraintConvertor.convert(uiConstraint); @@ -69,19 +70,19 @@ public class ConstraintConvertorTest { } @Test - public void convertCIProperty(){ + void convertCIProperty(){ ConstraintConvertor constraintConvertor = new ConstraintConvertor(); UIConstraint uiConstraint = constraintConvertor.convert("mem_size:\n" + " equal: { get_property: [A, size]}"); assertNotNull(uiConstraint); - assertEquals(uiConstraint.getConstraintOperator(),"equal"); - assertEquals(uiConstraint.getValue(),"size"); - assertEquals(uiConstraint.getServicePropertyName().trim(),"mem_size"); - assertEquals(uiConstraint.getSourceName().trim(),"A"); + assertEquals("equal",uiConstraint.getConstraintOperator()); + assertEquals(uiConstraint.getValue(),Map.of(ToscaFunctionType.GET_PROPERTY.getName(), List.of("A", "size"))); + assertEquals("mem_size",uiConstraint.getServicePropertyName().trim()); + assertEquals("A",uiConstraint.getSourceName().trim()); } @Test - public void convertFromCIProperty(){ + void convertFromCIProperty(){ ConstraintConvertor constraintConvertor = new ConstraintConvertor(); UIConstraint uiConstraint = new UIConstraint("mem_size", "equal" , ConstraintConvertor.PROPERTY_CONSTRAINT, "A" ,"size"); String constraint = constraintConvertor.convert(uiConstraint); @@ -90,14 +91,14 @@ public class ConstraintConvertorTest { } @Test - public void convertServiceTemplateInput(){ + void convertServiceTemplateInput(){ ConstraintConvertor constraintConvertor = new ConstraintConvertor(); UIConstraint uiConstraint = constraintConvertor.convert("mem_size: {equal: {get_input: InputName}}\n"); assertNotNull(uiConstraint); } @Test - public void convertFromServiceTemplateInput(){ + void convertFromServiceTemplateInput(){ ConstraintConvertor constraintConvertor = new ConstraintConvertor(); UIConstraint uiConstraint = new UIConstraint("mem_size", "equal" , ConstraintConvertor.SERVICE_INPUT_CONSTRAINT, "InputName"); String constraint = constraintConvertor.convert(uiConstraint); @@ -106,17 +107,17 @@ public class ConstraintConvertorTest { } @Test - public void convertGreaterThanStatic(){ + void convertGreaterThanStatic(){ ConstraintConvertor constraintConvertor = new ConstraintConvertor(); UIConstraint uiConstraint = constraintConvertor.convert("mem_size: {greater_than: 2}\n"); assertNotNull(uiConstraint); - assertEquals(uiConstraint.getConstraintOperator(),"greater_than"); - assertEquals(uiConstraint.getValue(),2); - assertEquals(uiConstraint.getServicePropertyName().trim(),"mem_size"); + assertEquals("greater_than",uiConstraint.getConstraintOperator()); + assertEquals(2,uiConstraint.getValue()); + assertEquals("mem_size",uiConstraint.getServicePropertyName().trim()); } @Test - public void convertFromGreaterThanStatic(){ + void convertFromGreaterThanStatic(){ ConstraintConvertor constraintConvertor = new ConstraintConvertor(); UIConstraint uiConstraint = new UIConstraint("mem_size", "greater_than" , ConstraintConvertor.STATIC_CONSTRAINT, 2); String constraint = constraintConvertor.convert(uiConstraint); @@ -125,14 +126,14 @@ public class ConstraintConvertorTest { } @Test - public void convertLessThanServiceProperty(){ + void convertLessThanServiceProperty(){ ConstraintConvertor constraintConvertor = new ConstraintConvertor(); UIConstraint uiConstraint = constraintConvertor.convert("mem_size: {less_then: {get_input: InputName}}"); assertNotNull(uiConstraint); } @Test - public void convertFromLessThanServiceProperty(){ + void convertFromLessThanServiceProperty(){ ConstraintConvertor constraintConvertor = new ConstraintConvertor(); UIConstraint uiConstraint = new UIConstraint("mem_size", "less_then" , ConstraintConvertor.SERVICE_INPUT_CONSTRAINT, "InputName"); String constraint = constraintConvertor.convert(uiConstraint); @@ -141,7 +142,7 @@ public class ConstraintConvertorTest { } @Test - public void convertFromEqualStaticMap(){ + void convertFromEqualStaticMap(){ ConstraintConvertor constraintConvertor = new ConstraintConvertor(); UIConstraint uiConstraint = new UIConstraint("mem_size", "equal" , ConstraintConvertor.STATIC_CONSTRAINT, "{x: xx,"+ " y: yy}\n"); @@ -151,7 +152,7 @@ public class ConstraintConvertorTest { } @Test - public void convertStringToMap(){ + void convertStringToMap(){ ConstraintConvertor constraintConvertor = new ConstraintConvertor(); UIConstraint uiConstraint = constraintConvertor.convert("mem_size:\n" + " equal: {x: xx, y: yy}\n"); assertNotNull(uiConstraint); @@ -159,7 +160,7 @@ public class ConstraintConvertorTest { } @Test - public void convertFromEqualStaticList(){ + void convertFromEqualStaticList(){ ConstraintConvertor constraintConvertor = new ConstraintConvertor(); UIConstraint uiConstraint = new UIConstraint("mem_size", "equal" , ConstraintConvertor.STATIC_CONSTRAINT, "[x, y]\n"); String constraint = constraintConvertor.convert(uiConstraint); @@ -168,7 +169,7 @@ public class ConstraintConvertorTest { } @Test - public void convertStringToList(){ + void convertStringToList(){ ConstraintConvertor constraintConvertor = new ConstraintConvertor(); UIConstraint uiConstraint = constraintConvertor.convert("mem_size:\n" + " equal: [x, y]\n"); assertNotNull(uiConstraint); diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/nodeFilter/BaseServiceFilterUtilsTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/nodeFilter/BaseServiceFilterUtilsTest.java index 68ceaca0a6..7948f84f96 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/nodeFilter/BaseServiceFilterUtilsTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/nodeFilter/BaseServiceFilterUtilsTest.java @@ -16,13 +16,18 @@ package org.openecomp.sdc.be.nodeFilter; -import java.util.Arrays; -import org.junit.Assert; -import org.junit.Before; +import java.util.List; +import org.junit.jupiter.api.BeforeEach; import org.openecomp.sdc.be.config.ConfigurationManager; import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; -import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyFilterConstraintDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyFilterDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; +import org.openecomp.sdc.be.datatypes.enums.FilterValueType; +import org.openecomp.sdc.be.datatypes.enums.PropertyFilterTargetType; +import org.openecomp.sdc.be.datatypes.tosca.ToscaGetFunctionType; import org.openecomp.sdc.be.model.ComponentInstance; import org.openecomp.sdc.be.model.PropertyDefinition; import org.openecomp.sdc.be.model.Service; @@ -32,47 +37,60 @@ import org.openecomp.sdc.common.impl.FSConfigurationSource; public class BaseServiceFilterUtilsTest { protected Service service; - protected RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition; - protected RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition2; + protected PropertyFilterDataDefinition propertyFilterDataDefinition; + protected PropertyFilterDataDefinition propertyFilterDataDefinition2; protected static final String CI_NAME = "AAAAAA"; protected static final String A_PROP_NAME = "A_PROP"; protected static final String SIZE_PROP = "size"; - protected static final String ORIG_COMP_INSTANCE_ID = "54355645457457"; - @Before - public void initService() { - try { - new ConfigurationManager(new FSConfigurationSource( - ExternalConfiguration.getChangeListener(), "src/test/resources/config/catalog-be")); - service = new Service(); - ComponentInstance componentInstance = new ComponentInstance(); - componentInstance.setUniqueId(CI_NAME); - componentInstance.setName(CI_NAME); - service.setComponentInstances(Arrays.asList(componentInstance)); - componentInstance.setDirectives(ConfigurationManager.getConfigurationManager().getConfiguration() - .getDirectives()); - CINodeFilterDataDefinition serviceFilter = new CINodeFilterDataDefinition(); - componentInstance.setNodeFilter(serviceFilter); - requirementNodeFilterPropertyDataDefinition = new RequirementNodeFilterPropertyDataDefinition(); - requirementNodeFilterPropertyDataDefinition.setName("Name1"); - requirementNodeFilterPropertyDataDefinition - .setConstraints(Arrays.asList("mem_size:\n" + " equal: { get_property : [" + CI_NAME + ", size]}\n")); - requirementNodeFilterPropertyDataDefinition2 = new RequirementNodeFilterPropertyDataDefinition(); - requirementNodeFilterPropertyDataDefinition2.setName("Name2"); - requirementNodeFilterPropertyDataDefinition2 - .setConstraints(Arrays.asList("mem_size:\n {equal: { get_property : [SELF, "+A_PROP_NAME+"]}}\n")); + @BeforeEach + void initService() { + new ConfigurationManager(new FSConfigurationSource(ExternalConfiguration.getChangeListener(), "src/test/resources/config/catalog-be")); + service = new Service(); + ComponentInstance componentInstance = new ComponentInstance(); + componentInstance.setUniqueId(CI_NAME); + componentInstance.setName(CI_NAME); + service.setComponentInstances(List.of(componentInstance)); + componentInstance.setDirectives(ConfigurationManager.getConfigurationManager().getConfiguration() + .getDirectives()); + CINodeFilterDataDefinition serviceFilter = new CINodeFilterDataDefinition(); + componentInstance.setNodeFilter(serviceFilter); + propertyFilterDataDefinition = new PropertyFilterDataDefinition(); + propertyFilterDataDefinition.setName("Name1"); + final var propertyFilterConstraint1 = new PropertyFilterConstraintDataDefinition(); + propertyFilterConstraint1.setPropertyName("mem_size"); + propertyFilterConstraint1.setOperator(ConstraintType.EQUAL); + propertyFilterConstraint1.setValue(createToscaGetFunction(CI_NAME, ToscaGetFunctionType.GET_PROPERTY, List.of("size"))); + propertyFilterConstraint1.setValueType(FilterValueType.GET_PROPERTY); + propertyFilterConstraint1.setTargetType(PropertyFilterTargetType.PROPERTY); + propertyFilterDataDefinition.setConstraints(List.of(propertyFilterConstraint1)); + propertyFilterDataDefinition2 = new PropertyFilterDataDefinition(); + propertyFilterDataDefinition2.setName("Name2"); + final var propertyFilterConstraint2 = new PropertyFilterConstraintDataDefinition(); + propertyFilterConstraint2.setPropertyName("mem_size"); + propertyFilterConstraint2.setOperator(ConstraintType.EQUAL); + propertyFilterConstraint2.setValue(createToscaGetFunction("SELF", ToscaGetFunctionType.GET_PROPERTY, List.of(A_PROP_NAME))); + propertyFilterConstraint2.setValueType(FilterValueType.GET_PROPERTY); + propertyFilterConstraint2.setTargetType(PropertyFilterTargetType.PROPERTY); + propertyFilterDataDefinition2.setConstraints(List.of(propertyFilterConstraint2)); - ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> listDataDefinition = - new ListDataDefinition<>(Arrays.asList( - requirementNodeFilterPropertyDataDefinition, - requirementNodeFilterPropertyDataDefinition2)); - serviceFilter.setProperties(listDataDefinition); - PropertyDefinition property = new PropertyDefinition(); - property.setName(A_PROP_NAME); - service.setProperties(Arrays.asList(property)); - } catch (Exception e) { - Assert.fail(e.getMessage()); - } + ListDataDefinition<PropertyFilterDataDefinition> listDataDefinition = + new ListDataDefinition<>(List.of(propertyFilterDataDefinition, propertyFilterDataDefinition2)); + serviceFilter.setProperties(listDataDefinition); + PropertyDefinition property = new PropertyDefinition(); + property.setName(A_PROP_NAME); + service.setProperties(List.of(property)); + } + + protected static ToscaGetFunctionDataDefinition createToscaGetFunction(final String sourceName, + final ToscaGetFunctionType toscaGetFunctionType, + final List<String> propertyPathFromSource) { + final var toscaGetFunction = new ToscaGetFunctionDataDefinition(); + toscaGetFunction.setFunctionType(toscaGetFunctionType); + toscaGetFunction.setPropertyPathFromSource(propertyPathFromSource); + toscaGetFunction.setSourceName(sourceName); + toscaGetFunction.setPropertyName(propertyPathFromSource.get(0)); + return toscaGetFunction; } } diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/nodeFilter/ServiceFilterRenameCiTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/nodeFilter/ServiceFilterRenameCiTest.java index 8e94b94e61..d18f6039f2 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/nodeFilter/ServiceFilterRenameCiTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/nodeFilter/ServiceFilterRenameCiTest.java @@ -16,31 +16,28 @@ package org.openecomp.sdc.be.nodeFilter; -import org.junit.Test; -import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition; -import org.openecomp.sdc.be.impl.ServiceFilterUtils; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; import java.util.List; import java.util.Map; +import org.junit.jupiter.api.Test; +import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyFilterConstraintDataDefinition; +import org.openecomp.sdc.be.impl.ServiceFilterUtils; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -public class ServiceFilterRenameCiTest extends BaseServiceFilterUtilsTest { +class ServiceFilterRenameCiTest extends BaseServiceFilterUtilsTest { protected static final String CI_NEW_NAME = "BBBBB"; @Test - public void renameCI() { + void renameCI() { Map<String, CINodeFilterDataDefinition> renamedNodeFilters = getRenamedNodeFilters(CI_NAME, CI_NEW_NAME); assertNotNull(renamedNodeFilters); - final List<String> constraints = + final List<PropertyFilterConstraintDataDefinition> constraints = renamedNodeFilters.get(CI_NAME).getProperties().getListToscaDataDefinition().iterator().next() .getConstraints(); - assertEquals(1,constraints.size()); - final String constraint = constraints.iterator().next(); - assertTrue(constraint.contains(CI_NEW_NAME)); + assertEquals(1, constraints.size()); } private Map<String, CINodeFilterDataDefinition> getRenamedNodeFilters(String oldName, String newName) { diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/nodeFilter/ServiceFilterUtilsCIChangeTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/nodeFilter/ServiceFilterUtilsCIChangeTest.java index 57b95e2fbe..374e8209ed 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/nodeFilter/ServiceFilterUtilsCIChangeTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/nodeFilter/ServiceFilterUtilsCIChangeTest.java @@ -16,13 +16,25 @@ package org.openecomp.sdc.be.nodeFilter; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import fj.data.Either; -import org.junit.Test; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.List; +import java.util.Set; +import org.junit.jupiter.api.Test; import org.mockito.Mockito; import org.openecomp.sdc.be.auditing.impl.AuditingManager; +import org.openecomp.sdc.be.datatypes.elements.PropertyFilterConstraintDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; +import org.openecomp.sdc.be.datatypes.enums.FilterValueType; +import org.openecomp.sdc.be.datatypes.enums.PropertyFilterTargetType; +import org.openecomp.sdc.be.datatypes.tosca.ToscaGetFunctionType; import org.openecomp.sdc.be.impl.ComponentsUtils; import org.openecomp.sdc.be.impl.ServiceFilterUtils; import org.openecomp.sdc.be.model.ComponentInstance; @@ -31,43 +43,38 @@ import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; import org.openecomp.sdc.be.ui.model.UIConstraint; import org.openecomp.sdc.exception.ResponseFormat; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.Arrays; -import java.util.Set; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -public class ServiceFilterUtilsCIChangeTest extends BaseServiceFilterUtilsTest { - +class ServiceFilterUtilsCIChangeTest extends BaseServiceFilterUtilsTest { @Test - public void checkComponentInstanceIsFound() { + void checkComponentInstanceIsFound() { Set<String> nodesFiltersToBeDeleted = getNodeFiltersToBeDeleted(CI_NAME); assertNotNull(nodesFiltersToBeDeleted); assertTrue(nodesFiltersToBeDeleted.contains(CI_NAME)); } private Set<String> getNodeFiltersToBeDeleted(String inCiName) { - requirementNodeFilterPropertyDataDefinition - .setConstraints(Arrays.asList("mem_size:\n" + " equal:\n" + " get_property: ["+CI_NAME+", some static]\n")); - ComponentInstance ci = new ComponentInstance(); - ci.setName(inCiName); - return ServiceFilterUtils.getNodesFiltersToBeDeleted(service, ci); + final var propertyFilterConstraint = new PropertyFilterConstraintDataDefinition(); + propertyFilterConstraint.setPropertyName("mem_size"); + propertyFilterConstraint.setOperator(ConstraintType.EQUAL); + propertyFilterConstraint.setValue(createToscaGetFunction(CI_NAME, ToscaGetFunctionType.GET_PROPERTY, List.of("some static"))); + propertyFilterConstraint.setValueType(FilterValueType.GET_PROPERTY); + propertyFilterConstraint.setTargetType(PropertyFilterTargetType.PROPERTY); + propertyFilterDataDefinition + .setConstraints(List.of(propertyFilterConstraint)); + final var componentInstance = new ComponentInstance(); + componentInstance.setName(inCiName); + return ServiceFilterUtils.getNodesFiltersToBeDeleted(service, componentInstance); } @Test - public void checkComponentInstanceIsNotFound() { + void checkComponentInstanceIsNotFound() { Set<String> nodesFiltersToBeDeleted = getNodeFiltersToBeDeleted(CI_NAME + " aaa bbb"); assertNotNull(nodesFiltersToBeDeleted); assertTrue(nodesFiltersToBeDeleted.isEmpty()); - assertFalse(nodesFiltersToBeDeleted.contains(CI_NAME)); } @Test - public void testServiceConstraintPairSerialization() throws IOException { + void testServiceConstraintPairSerialization() throws IOException { UIConstraint uiConstraint =new UIConstraint(); ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true); diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/nodeFilter/ServiceFilterUtilsPropertyRemovedTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/nodeFilter/ServiceFilterUtilsPropertyRemovedTest.java index 0b40359d60..47f462bb15 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/nodeFilter/ServiceFilterUtilsPropertyRemovedTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/nodeFilter/ServiceFilterUtilsPropertyRemovedTest.java @@ -16,23 +16,24 @@ package org.openecomp.sdc.be.nodeFilter; -import org.junit.Test; -import org.openecomp.sdc.be.impl.ServiceFilterUtils; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import org.junit.jupiter.api.Test; +import org.openecomp.sdc.be.impl.ServiceFilterUtils; -public class ServiceFilterUtilsPropertyRemovedTest extends BaseServiceFilterUtilsTest { +class ServiceFilterUtilsPropertyRemovedTest extends BaseServiceFilterUtilsTest { @Test - public void checkPropertyIsFound() { + void checkPropertyIsFound() { assertTrue(ServiceFilterUtils.isNodeFilterAffectedByPropertyRemoval(service, CI_NAME, SIZE_PROP)); } @Test - public void checkPropertyIsNotFound() { + void checkPropertyIsNotFound() { assertFalse(ServiceFilterUtils.isNodeFilterAffectedByPropertyRemoval(service, CI_NAME, A_PROP_NAME + "XXXX")); } } + diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/nodeFilter/ServiceFilterUtilsServiceInputTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/nodeFilter/ServiceFilterUtilsServiceInputTest.java index e17da93b0e..0d473518cd 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/nodeFilter/ServiceFilterUtilsServiceInputTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/nodeFilter/ServiceFilterUtilsServiceInputTest.java @@ -16,42 +16,52 @@ package org.openecomp.sdc.be.nodeFilter; -import org.junit.Test; -import org.openecomp.sdc.be.impl.ServiceFilterUtils; -import org.openecomp.sdc.be.model.InputDefinition; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; -import java.util.Arrays; +import java.util.List; import java.util.Set; +import org.junit.jupiter.api.Test; +import org.openecomp.sdc.be.datatypes.elements.PropertyFilterConstraintDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; +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.be.impl.ServiceFilterUtils; +import org.openecomp.sdc.be.model.InputDefinition; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -public class ServiceFilterUtilsServiceInputTest extends BaseServiceFilterUtilsTest { +class ServiceFilterUtilsServiceInputTest extends BaseServiceFilterUtilsTest { private static final String CONSTRAINT_NAME = "InputName"; - @Test - public void checkInputStreamIsFound() { + void checkInputStreamIsFound() { Set<String> nodesFiltersToBeDeleted = getNodeFiltersToBeDeleted(CONSTRAINT_NAME); assertNotNull(nodesFiltersToBeDeleted); assertTrue(nodesFiltersToBeDeleted.contains(CI_NAME)); } private Set<String> getNodeFiltersToBeDeleted(String constraintName) { - requirementNodeFilterPropertyDataDefinition - .setConstraints(Arrays.asList("mem_size:\n equal: {get_input: " + CONSTRAINT_NAME + "}\n")); + final var propertyFilterConstraint = new PropertyFilterConstraintDataDefinition(); + propertyFilterConstraint.setPropertyName("mem_size"); + propertyFilterConstraint.setOperator(ConstraintType.EQUAL); + + propertyFilterConstraint.setValue( + createToscaGetFunction(PropertySource.SELF.getName(), ToscaGetFunctionType.GET_INPUT, List.of(CONSTRAINT_NAME)) + ); + propertyFilterConstraint.setValueType(FilterValueType.GET_INPUT); + propertyFilterConstraint.setTargetType(PropertyFilterTargetType.PROPERTY); + propertyFilterDataDefinition.setConstraints(List.of(propertyFilterConstraint)); InputDefinition inputDefinition = new InputDefinition(); inputDefinition.setName(constraintName); return ServiceFilterUtils.getNodesFiltersToBeDeleted(service, inputDefinition); } @Test - public void checkInputStreamIsNOtFound() { + public void checkInputStreamIsNotFound() { Set<String> nodesFiltersToBeDeleted = getNodeFiltersToBeDeleted(CONSTRAINT_NAME + " aaa bbb"); assertNotNull(nodesFiltersToBeDeleted); assertTrue(nodesFiltersToBeDeleted.isEmpty()); - assertFalse(nodesFiltersToBeDeleted.contains(CI_NAME)); } } diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ComponentNodeFilterServletTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ComponentNodeFilterServletTest.java index 548a046229..49252109cd 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ComponentNodeFilterServletTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ComponentNodeFilterServletTest.java @@ -20,13 +20,12 @@ package org.openecomp.sdc.be.servlets; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -35,8 +34,8 @@ import static org.openecomp.sdc.common.api.Constants.USER_ID_HEADER; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import java.util.Arrays; import java.util.LinkedList; +import java.util.List; import java.util.Optional; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; @@ -49,7 +48,6 @@ import org.glassfish.hk2.utilities.binding.AbstractBinder; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.test.JerseyTest; import org.glassfish.jersey.test.TestProperties; -import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; @@ -57,7 +55,6 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.TestInstance.Lifecycle; import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.ArgumentMatchers; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.junit.jupiter.MockitoExtension; @@ -65,7 +62,6 @@ import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; import org.openecomp.sdc.be.components.impl.ComponentNodeFilterBusinessLogic; import org.openecomp.sdc.be.components.impl.ResourceImportManager; import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException; -import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction; import org.openecomp.sdc.be.components.validation.UserValidations; import org.openecomp.sdc.be.config.ConfigurationManager; import org.openecomp.sdc.be.config.SpringConfig; @@ -73,14 +69,16 @@ import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.datamodel.utils.ConstraintConvertor; import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyFilterDataDefinition; import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterCapabilityDataDefinition; -import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.datatypes.enums.NodeFilterConstraintType; import org.openecomp.sdc.be.impl.ComponentsUtils; import org.openecomp.sdc.be.impl.ServletUtils; import org.openecomp.sdc.be.impl.WebAppContextWrapper; import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.dto.FilterConstraintDto; +import org.openecomp.sdc.be.ui.mapper.FilterConstraintMapper; import org.openecomp.sdc.be.ui.model.UIConstraint; import org.openecomp.sdc.be.user.Role; import org.openecomp.sdc.be.user.UserBusinessLogic; @@ -111,6 +109,7 @@ class ComponentNodeFilterServletTest extends JerseyTest { private static final String V_1_CATALOG_S_S_COMPONENT_INSTANCE_S_S_NODE_FILTER = "/v1/catalog/%s/%s/componentInstance/%s/%s/nodeFilter"; private final UIConstraint uiConstraint = new UIConstraint("resourceType", "equal", "static", "static", "resourceTypeValue"); private final String constraint = new ConstraintConvertor().convert(uiConstraint); + private final FilterConstraintDto filterConstraintDto = new FilterConstraintMapper().mapFrom(uiConstraint); private final String inputJson = buildConstraintDataJson(uiConstraint); private final User user = new User("", "", USER_ID, "", Role.ADMIN.name(), null); @Mock @@ -176,7 +175,7 @@ class ComponentNodeFilterServletTest extends JerseyTest { } @Test - void addNodeFilterPropertiesSuccessTest() throws BusinessLogicException, JsonProcessingException { + void addNodeFilterPropertiesSuccessTest() throws BusinessLogicException { initComponentData(); final String pathFormat = V_1_CATALOG_S_S_COMPONENT_INSTANCE_S_S_NODE_FILTER; final String path = String.format(pathFormat, componentType, componentId, componentInstance, @@ -194,7 +193,7 @@ class ComponentNodeFilterServletTest extends JerseyTest { assertThat(propertyValue).isEqualToIgnoringCase(uiConstraint.getValue().toString()); doReturn(Optional.of(uiConstraint)).when(componentsUtils) - .parseToConstraint(anyString(), any(User.class), ArgumentMatchers.any(ComponentTypeEnum.class)); + .parseToConstraint(anyString(), any(User.class), any(ComponentTypeEnum.class)); assertNotNull(constraint); assertNotNull(ciNodeFilterDataDefinition); @@ -202,8 +201,7 @@ class ComponentNodeFilterServletTest extends JerseyTest { assertThat("resourceType: {equal: resourceTypeValue}\n").isEqualToIgnoringCase(constraint); doReturn(Optional.of(ciNodeFilterDataDefinition)).when(componentNodeFilterBusinessLogic) - .addNodeFilter(componentId, componentInstance, NodeFilterConstraintAction.ADD, - uiConstraint.getServicePropertyName(), constraint, true, ComponentTypeEnum.RESOURCE, + .addNodeFilter(componentId, componentInstance, filterConstraintDto, true, ComponentTypeEnum.RESOURCE, NodeFilterConstraintType.PROPERTIES, ""); final Response response = target() @@ -213,9 +211,9 @@ class ComponentNodeFilterServletTest extends JerseyTest { .post(Entity.entity(inputJson, MediaType.APPLICATION_JSON)); verify(componentNodeFilterBusinessLogic, times(1)) - .addNodeFilter(anyString(), anyString(), ArgumentMatchers.any(NodeFilterConstraintAction.class), anyString(), - anyString(), anyBoolean(), ArgumentMatchers.any(ComponentTypeEnum.class), - ArgumentMatchers.any(NodeFilterConstraintType.class), anyString()); + .addNodeFilter(anyString(), anyString(), any(FilterConstraintDto.class), anyBoolean(), any(ComponentTypeEnum.class), + any(NodeFilterConstraintType.class), anyString() + ); assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200); verify(componentNodeFilterBusinessLogic,times(1)).validateUser(USER_ID); @@ -224,8 +222,7 @@ class ComponentNodeFilterServletTest extends JerseyTest { @Test void addNodeFilterCapabilitiesSuccessTest() throws BusinessLogicException, JsonProcessingException { initComponentData(); - final String pathFormat = V_1_CATALOG_S_S_COMPONENT_INSTANCE_S_S_NODE_FILTER; - final String path = String.format(pathFormat, componentType, componentId, componentInstance, + final String path = String.format(V_1_CATALOG_S_S_COMPONENT_INSTANCE_S_S_NODE_FILTER, componentType, componentId, componentInstance, NodeFilterConstraintType.CAPABILITIES_PARAM_NAME); final UIConstraint uiConstraint1 = new UIConstraint(uiConstraint.getServicePropertyName(), uiConstraint.getConstraintOperator(), uiConstraint.getSourceType(), uiConstraint.getSourceName(), uiConstraint.getValue()); @@ -234,27 +231,24 @@ class ComponentNodeFilterServletTest extends JerseyTest { when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(responseFormat); doReturn(componentsUtils).when(servletUtils).getComponentsUtils(); uiConstraint1.setCapabilityName(capabilityName); - - when(componentsUtils.parseToConstraint(anyString(), any(User.class), ArgumentMatchers.any(ComponentTypeEnum.class))) - .thenReturn(Optional.of(uiConstraint1)); + final String requestPayload = buildConstraintDataJson(uiConstraint1); + when(componentsUtils.parseToConstraint(requestPayload, user, ComponentTypeEnum.RESOURCE)).thenReturn(Optional.of(uiConstraint1)); assertThat(ciNodeFilterDataDefinition.getProperties().getListToscaDataDefinition()).hasSize(1); + final FilterConstraintDto filterConstraintDto1 = new FilterConstraintMapper().mapFrom(uiConstraint1); when(componentNodeFilterBusinessLogic - .addNodeFilter(componentId, componentInstance, NodeFilterConstraintAction.ADD, - uiConstraint1.getServicePropertyName(), constraint, true, ComponentTypeEnum.RESOURCE, - NodeFilterConstraintType.CAPABILITIES, capabilityName)) - .thenReturn(Optional.of(ciNodeFilterDataDefinition)); - + .addNodeFilter(componentId, componentInstance, filterConstraintDto1, true, ComponentTypeEnum.RESOURCE, + NodeFilterConstraintType.CAPABILITIES, capabilityName) + ).thenReturn(Optional.of(ciNodeFilterDataDefinition)); final Response response = target() .path(path) .request(MediaType.APPLICATION_JSON) .header(USER_ID_HEADER, USER_ID) - .post(Entity.entity(inputJson, MediaType.APPLICATION_JSON)); + .post(Entity.entity(requestPayload, MediaType.APPLICATION_JSON)); verify(componentNodeFilterBusinessLogic, times(1)) - .addNodeFilter(anyString(), anyString(), ArgumentMatchers.any(NodeFilterConstraintAction.class), anyString(), - anyString(), anyBoolean(), ArgumentMatchers.any(ComponentTypeEnum.class), - ArgumentMatchers.any(NodeFilterConstraintType.class), anyString()); + .addNodeFilter(componentId, componentInstance, filterConstraintDto1, true, ComponentTypeEnum.RESOURCE, + NodeFilterConstraintType.CAPABILITIES, capabilityName); assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200); verify(componentNodeFilterBusinessLogic,times(1)).validateUser(USER_ID); @@ -352,7 +346,7 @@ class ComponentNodeFilterServletTest extends JerseyTest { when(componentNodeFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user); - when(componentsUtils.parseToConstraint(anyString(), any(User.class), ArgumentMatchers.any(ComponentTypeEnum.class))) + when(componentsUtils.parseToConstraint(anyString(), any(User.class), any(ComponentTypeEnum.class))) .thenReturn(Optional.of(uiConstraint)); doReturn(componentsUtils).when(servletUtils).getComponentsUtils(); when(responseFormat.getStatus()).thenReturn(HttpStatus.OK_200); @@ -370,8 +364,8 @@ class ComponentNodeFilterServletTest extends JerseyTest { .put(Entity.entity(inputJson, MediaType.APPLICATION_JSON)); verify(componentNodeFilterBusinessLogic, times(1)) - .updateNodeFilter(anyString(), anyString(), ArgumentMatchers.any(UIConstraint.class), - ArgumentMatchers.any(ComponentTypeEnum.class), ArgumentMatchers.any(NodeFilterConstraintType.class), + .updateNodeFilter(anyString(), anyString(), any(UIConstraint.class), + any(ComponentTypeEnum.class), any(NodeFilterConstraintType.class), anyInt()); assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200); @@ -447,9 +441,8 @@ class ComponentNodeFilterServletTest extends JerseyTest { when(responseFormat.getStatus()).thenReturn(HttpStatus.OK_200); when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(responseFormat); - when(componentNodeFilterBusinessLogic.deleteNodeFilter(componentId, componentInstance, - NodeFilterConstraintAction.DELETE, null, 0, true, ComponentTypeEnum.RESOURCE, - NodeFilterConstraintType.PROPERTIES)) + when(componentNodeFilterBusinessLogic + .deleteNodeFilter(componentId, componentInstance, 0, true, ComponentTypeEnum.RESOURCE, NodeFilterConstraintType.PROPERTIES)) .thenReturn(Optional.of(ciNodeFilterDataDefinition)); final Response response = target() @@ -460,9 +453,7 @@ class ComponentNodeFilterServletTest extends JerseyTest { .delete(Response.class); verify(componentNodeFilterBusinessLogic, times(1)) - .deleteNodeFilter(anyString(), anyString(), ArgumentMatchers.any(NodeFilterConstraintAction.class), - nullable(String.class), anyInt(), anyBoolean(), ArgumentMatchers.any(ComponentTypeEnum.class), - ArgumentMatchers.any(NodeFilterConstraintType.class)); + .deleteNodeFilter(anyString(), anyString(), anyInt(), anyBoolean(), any(ComponentTypeEnum.class), any(NodeFilterConstraintType.class)); assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200); verify(componentNodeFilterBusinessLogic,times(1)).validateUser(USER_ID); @@ -503,14 +494,14 @@ class ComponentNodeFilterServletTest extends JerseyTest { .property("contextConfig", context); } - private void initComponentData() throws JsonProcessingException { - final RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition = - new RequirementNodeFilterPropertyDataDefinition(); - requirementNodeFilterPropertyDataDefinition.setName(uiConstraint.getServicePropertyName()); - requirementNodeFilterPropertyDataDefinition.setConstraints(new LinkedList<>(Arrays.asList(constraint))); + private void initComponentData() { + final PropertyFilterDataDefinition propertyFilterDataDefinition = + new PropertyFilterDataDefinition(); + propertyFilterDataDefinition.setName(uiConstraint.getServicePropertyName()); + propertyFilterDataDefinition.setConstraints(new LinkedList<>(List.of(new FilterConstraintMapper().mapTo(filterConstraintDto)))); - final ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> propertyDataDefinitionList = - new ListDataDefinition<>(new LinkedList<>(Arrays.asList(requirementNodeFilterPropertyDataDefinition))); + final ListDataDefinition<PropertyFilterDataDefinition> propertyDataDefinitionList = + new ListDataDefinition<>(new LinkedList<>(List.of(propertyFilterDataDefinition))); final RequirementNodeFilterCapabilityDataDefinition requirementNodeFilterCapabilityDataDefinition = new RequirementNodeFilterCapabilityDataDefinition(); @@ -518,7 +509,7 @@ class ComponentNodeFilterServletTest extends JerseyTest { requirementNodeFilterCapabilityDataDefinition.setProperties(propertyDataDefinitionList); final ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> capabilityDataDefinitionList = - new ListDataDefinition<>(new LinkedList<>(Arrays.asList(requirementNodeFilterCapabilityDataDefinition))); + new ListDataDefinition<>(new LinkedList<>(List.of(requirementNodeFilterCapabilityDataDefinition))); ciNodeFilterDataDefinition = new CINodeFilterDataDefinition(); ciNodeFilterDataDefinition.setProperties(propertyDataDefinitionList); diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ComponentSubstitutionFilterServletTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ComponentSubstitutionFilterServletTest.java index bcc0f2eadb..9bd7244e04 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ComponentSubstitutionFilterServletTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ComponentSubstitutionFilterServletTest.java @@ -22,11 +22,11 @@ package org.openecomp.sdc.be.servlets; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.nullable; -import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.times; @@ -36,9 +36,8 @@ import static org.openecomp.sdc.common.api.Constants.USER_ID_HEADER; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import java.util.Arrays; import java.util.Collections; -import java.util.LinkedList; +import java.util.List; import java.util.Optional; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; @@ -46,7 +45,6 @@ import javax.servlet.http.HttpSession; import javax.ws.rs.client.Entity; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; - import org.eclipse.jetty.http.HttpStatus; import org.glassfish.hk2.utilities.binding.AbstractBinder; import org.glassfish.jersey.server.ResourceConfig; @@ -62,24 +60,24 @@ import org.openecomp.sdc.be.components.impl.ComponentSubstitutionFilterBusinessL import org.openecomp.sdc.be.components.impl.ResourceImportManager; import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException; import org.openecomp.sdc.be.components.validation.UserValidations; -import org.openecomp.sdc.be.config.Configuration; import org.openecomp.sdc.be.config.ConfigurationManager; import org.openecomp.sdc.be.config.SpringConfig; import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.datamodel.utils.ConstraintConvertor; import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; -import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterPropertyDataDefinition; import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterPropertyDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.impl.ComponentsUtils; import org.openecomp.sdc.be.impl.ServletUtils; import org.openecomp.sdc.be.impl.WebAppContextWrapper; import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.dto.FilterConstraintDto; +import org.openecomp.sdc.be.ui.mapper.FilterConstraintMapper; import org.openecomp.sdc.be.ui.model.UIConstraint; import org.openecomp.sdc.be.user.Role; import org.openecomp.sdc.be.user.UserBusinessLogic; -import org.openecomp.sdc.common.api.Constants; import org.openecomp.sdc.common.api.ConfigurationSource; +import org.openecomp.sdc.common.api.Constants; import org.openecomp.sdc.common.impl.ExternalConfiguration; import org.openecomp.sdc.common.impl.FSConfigurationSource; import org.openecomp.sdc.exception.ResponseFormat; @@ -112,13 +110,11 @@ public class ComponentSubstitutionFilterServletTest extends JerseyTest { private static ComponentSubstitutionFilterBusinessLogic componentSubstitutionFilterBusinessLogic; private static ResponseFormat responseFormat; private static UserValidations userValidations; - private static ConfigurationManager configurationManager; private SubstitutionFilterDataDefinition substitutionFilterDataDefinition; - private RequirementSubstitutionFilterPropertyDataDefinition requirementSubstitutionFilterPropertyDataDefinition; private UIConstraint uiConstraint; - private String constraint; private String inputJson; private User user; + private FilterConstraintDto filterConstraintDto; @BeforeAll public static void initClass() { @@ -135,7 +131,7 @@ public class ComponentSubstitutionFilterServletTest extends JerseyTest { when(servletUtils.getComponentsUtils()).thenReturn(componentsUtils); String appConfigDir = "src/test/resources/config/catalog-be"; ConfigurationSource configurationSource = new FSConfigurationSource(ExternalConfiguration.getChangeListener(), appConfigDir); - configurationManager = new ConfigurationManager(configurationSource); + ConfigurationManager configurationManager = new ConfigurationManager(configurationSource); org.openecomp.sdc.be.config.Configuration configuration = new org.openecomp.sdc.be.config.Configuration(); configuration.setJanusGraphInMemoryGraph(true); configurationManager.setConfiguration(configuration); @@ -155,7 +151,7 @@ public class ComponentSubstitutionFilterServletTest extends JerseyTest { } @Test - public void addSubstitutionFilterTest() throws Exception { + void addSubstitutionFilterTest() throws Exception { final String pathFormat = "/v1/catalog/%s/%s/substitutionFilter/%s"; final String path = String.format(pathFormat, componentType, componentId, constraintType); @@ -165,21 +161,19 @@ public class ComponentSubstitutionFilterServletTest extends JerseyTest { when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(responseFormat); assertNotNull(uiConstraint); - assertThat(servicePropertyName).isEqualToIgnoringCase(uiConstraint.getServicePropertyName()); - assertThat(constraintOperator).isEqualToIgnoringCase(uiConstraint.getConstraintOperator()); - assertThat(sourceType).isEqualToIgnoringCase(uiConstraint.getSourceType()); - assertThat(sourceName).isEqualToIgnoringCase(uiConstraint.getSourceName()); - assertThat(propertyValue).isEqualToIgnoringCase(uiConstraint.getValue().toString()); + assertThat(uiConstraint.getServicePropertyName()).isEqualToIgnoringCase(servicePropertyName); + assertThat(uiConstraint.getConstraintOperator()).isEqualToIgnoringCase(constraintOperator); + assertThat(uiConstraint.getSourceType()).isEqualToIgnoringCase(sourceType); + assertThat(uiConstraint.getSourceName()).isEqualToIgnoringCase(sourceName); + assertThat(uiConstraint.getValue().toString()).isEqualToIgnoringCase(propertyValue); when(componentsUtils.parseToConstraint(anyString(), any(User.class), any(ComponentTypeEnum.class))) .thenReturn(Optional.of(uiConstraint)); - assertNotNull(constraint); assertNotNull(substitutionFilterDataDefinition); assertThat(substitutionFilterDataDefinition.getProperties().getListToscaDataDefinition()).hasSize(1); - assertThat("controller_actor: {equal: constraintValue}\n").isEqualToIgnoringCase(constraint); - when(componentSubstitutionFilterBusinessLogic.addSubstitutionFilter(componentId, uiConstraint.getServicePropertyName(), constraint, - true, ComponentTypeEnum.SERVICE)).thenReturn(Optional.of(substitutionFilterDataDefinition)); + when(componentSubstitutionFilterBusinessLogic.addSubstitutionFilter(componentId, filterConstraintDto, true, ComponentTypeEnum.SERVICE)) + .thenReturn(Optional.of(substitutionFilterDataDefinition)); final Response response = target() .path(path) @@ -190,12 +184,11 @@ public class ComponentSubstitutionFilterServletTest extends JerseyTest { assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200); verify(componentSubstitutionFilterBusinessLogic, times(1)) - .addSubstitutionFilter(componentId, uiConstraint.getServicePropertyName(), constraint, - true, ComponentTypeEnum.SERVICE); + .addSubstitutionFilter(componentId, filterConstraintDto, true, ComponentTypeEnum.SERVICE); } @Test - public void addSubstitutionFilterFailConstraintParseTest() { + void addSubstitutionFilterFailConstraintParseTest() { final String pathFormat = "/v1/catalog/%s/%s/substitutionFilter/%s"; final String path = String.format(pathFormat, componentType, componentId, constraintType); @@ -216,7 +209,7 @@ public class ComponentSubstitutionFilterServletTest extends JerseyTest { } @Test - public void addSubstitutionFilterFailTest() { + void addSubstitutionFilterFailTest() { final String pathFormat = "/v1/catalog/%s/%s/substitutionFilter/%s"; final String path = String.format(pathFormat, componentType, componentId, constraintType); @@ -237,7 +230,7 @@ public class ComponentSubstitutionFilterServletTest extends JerseyTest { } @Test - public void updateSubstitutionFilterTest() throws BusinessLogicException { + void updateSubstitutionFilterTest() throws BusinessLogicException { final String pathFormat = "/v1/catalog/%s/%s/substitutionFilter/%s"; final String path = String.format(pathFormat, componentType, componentId, constraintType); @@ -250,7 +243,7 @@ public class ComponentSubstitutionFilterServletTest extends JerseyTest { any(User.class))).thenReturn(Collections.singletonList(uiConstraint)); when(componentSubstitutionFilterBusinessLogic.updateSubstitutionFilter(componentId.toLowerCase(), - Collections.singletonList(constraint), true, ComponentTypeEnum.SERVICE)) + List.of(filterConstraintDto), true, ComponentTypeEnum.SERVICE)) .thenReturn(Optional.ofNullable(substitutionFilterDataDefinition)); final Response response = target() @@ -266,7 +259,7 @@ public class ComponentSubstitutionFilterServletTest extends JerseyTest { } @Test - public void updateSubstitutionFilterFailConstraintParseTest() { + void updateSubstitutionFilterFailConstraintParseTest() { final String pathFormat = "/v1/catalog/%s/%s/substitutionFilter/%s"; final String path = String.format(pathFormat, componentType, componentId, constraintType); @@ -287,7 +280,7 @@ public class ComponentSubstitutionFilterServletTest extends JerseyTest { } @Test - public void updateSubstitutionFilterFailTest() { + void updateSubstitutionFilterFailTest() { final String pathFormat = "/v1/catalog/%s/%s/substitutionFilter/%s"; final String path = String.format(pathFormat, componentType, componentId, constraintType); @@ -308,7 +301,7 @@ public class ComponentSubstitutionFilterServletTest extends JerseyTest { } @Test - public void deleteSubstitutionFilterConstraintTest() throws BusinessLogicException { + void deleteSubstitutionFilterConstraintTest() throws BusinessLogicException { final String pathFormat = "/v1/catalog/%s/%s/substitutionFilter/%s/0"; final String path = String.format(pathFormat, componentType, componentId, constraintType); @@ -334,7 +327,7 @@ public class ComponentSubstitutionFilterServletTest extends JerseyTest { } @Test - public void deleteSubstitutionFilterConstraintFailTest() { + void deleteSubstitutionFilterConstraintFailTest() { final String pathFormat = "/v1/catalog/%s/%s/substitutionFilter/%s/0"; final String path = String.format(pathFormat, componentType, componentId, constraintType); @@ -390,16 +383,16 @@ public class ComponentSubstitutionFilterServletTest extends JerseyTest { private void initComponentData() throws JsonProcessingException { uiConstraint = new UIConstraint(servicePropertyName, constraintOperator, sourceType, sourceName, propertyValue); - constraint = new ConstraintConvertor().convert(uiConstraint); + final FilterConstraintMapper filterConstraintMapper = new FilterConstraintMapper(); + filterConstraintDto = filterConstraintMapper.mapFrom(uiConstraint); inputJson = buildConstraintDataJson(uiConstraint); - requirementSubstitutionFilterPropertyDataDefinition = new RequirementSubstitutionFilterPropertyDataDefinition(); - requirementSubstitutionFilterPropertyDataDefinition.setName(uiConstraint.getServicePropertyName()); - requirementSubstitutionFilterPropertyDataDefinition.setConstraints(new LinkedList<>(Arrays.asList(constraint))); + SubstitutionFilterPropertyDataDefinition substitutionFilterPropertyDataDefinition = new SubstitutionFilterPropertyDataDefinition(); + substitutionFilterPropertyDataDefinition.setName(uiConstraint.getServicePropertyName()); + substitutionFilterPropertyDataDefinition.setConstraints(List.of(filterConstraintMapper.mapTo(filterConstraintDto))); - final ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> listDataDefinition = - new ListDataDefinition<>( - new LinkedList<>(Arrays.asList(requirementSubstitutionFilterPropertyDataDefinition))); + final ListDataDefinition<SubstitutionFilterPropertyDataDefinition> listDataDefinition = + new ListDataDefinition<>(List.of(substitutionFilterPropertyDataDefinition)); substitutionFilterDataDefinition = new SubstitutionFilterDataDefinition(); substitutionFilterDataDefinition.setProperties(listDataDefinition); diff --git a/catalog-be/src/test/resources/config/catalog-be/error-configuration.yaml b/catalog-be/src/test/resources/config/catalog-be/error-configuration.yaml index 293bd49632..81e302f8bd 100644 --- a/catalog-be/src/test/resources/config/catalog-be/error-configuration.yaml +++ b/catalog-be/src/test/resources/config/catalog-be/error-configuration.yaml @@ -111,6 +111,12 @@ errors: message: "Error: Invalid userId '%1'.", messageId: "SVC4008" } + #---------SVC4009----------------------------- + USER_DEFINED: { + code: 400, + message: "Error: User Defined '%1'.", + messageId: "SVC4009" + } #---------SVC4049------------------------------ # %1 - service/resource COMPONENT_MISSING_CONTACT: { @@ -1430,10 +1436,10 @@ errors: message: "Error: artifact %1 is defined in CSAR %2 manifest but is not provided", messageId: "SVC4618" } -#---------SVC4619------------------------------ -# %1Â - artifact name -# %2Â -Â artifact type -# %3 - existing artifact type + #---------SVC4619------------------------------ + # %1Â - artifact name + # %2Â -Â artifact type + # %3 - existing artifact type ARTIFACT_ALREADY_EXIST_IN_DIFFERENT_TYPE_IN_CSAR: { code: 400, message: "Error: artifact %1 in type %2 already exists in type %3.", @@ -1797,9 +1803,11 @@ errors: messageId: "SVC4669" } #---------SVC4670------------------------------ + # %1 - artifactname + # %2 - validname ARTIFACT_NAME_INVALID: { code: 400, - message: "Error: Artifact name is invalid.", + message: "Error: Artifact name '%1' is invalid. Only the following characters are allowed in the Artifact Name: '%2'.", messageId: "SVC4670" } #---------SVC4671------------------------------ @@ -1909,6 +1917,22 @@ errors: message: "Error: Invalid policy name %1 received.", messageId: "SVC4684" } + #---------SVC4801------------------------------ + # %1Â -Â policy type + POLICY_TYPE_IS_INVALID: { + code: 400, + message: "Error: Invalid content. Policy type %1 does not exist", + messageId: "SVC4801" + } + + #---------SVC4802------------------------------ + # %1Â -Â policy name + POLICY_MISSING_POLICY_TYPE: { + code: 400, + message: "Error: Invalid content. Type name is not defined for policy %1", + messageId: "SVC4802" + } + #---------SVC4685------------------------------ # %1 - policy name POLICY_NAME_ALREADY_EXIST: { @@ -1988,7 +2012,7 @@ errors: #---------SVC4695----------------------------- # %1 - Interface Operation Name INTERFACE_OPERATION_NAME_ALREADY_IN_USE: { - code: 400, + code: 409, message: "Error: Interface Operation name '%1' already in use, Your current changes will not be saved.", messageId: "SVC4695" } @@ -1996,20 +2020,20 @@ errors: # %1 - Interface Operation Name INTERFACE_OPERATION_NAME_INVALID: { code: 400, - message: "Error: Interface Operation name '%1' is Invalid, Operation name should not contain special character, space, numbers and should not be greater than 200 characters.", + message: "Error: Interface Operation name '%1' is Invalid, Operation name should not contain special character, space and should not be greater than 200 characters.", messageId: "SVC4696" } #---------SVC4697----------------------------- INTERFACE_OPERATION_NAME_MANDATORY: { - code: 404, + code: 400, message: "Error: Interface Operation name is mandatory, Operation name can't be empty.", messageId: "SVC4697" } #---------SVC4698----------------------------- - # %1 - Interface Operation description - INTERFACE_OPERATION_DESCRIPTION_MAX_LENGTH: { + # %1 - Interface type + INTERFACE_OPERATION_INVALID_FOR_LOCAL_TYPE: { code: 400, - message: "Error: Interface Operation description '%1' is invalid, maximum 200 characters allowed.", + message: "Error: Invalid input, only one operation is allowed in local interface type '%1'.", messageId: "SVC4698" } #---------SVC4699----------------------------- @@ -2021,20 +2045,20 @@ errors: } #---------SVC4700----------------------------- INTERFACE_OPERATION_INPUT_NAME_MANDATORY: { - code: 404, + code: 400, message: "Error: Interface operation input parameter name should not be empty.", messageId: "SVC4700" } #---------SVC4701----------------------------- - # %1 - resource Id + # %1 - component Id INTERFACE_OPERATION_NOT_FOUND: { code: 404, - message: "Error: Interface operation not found in the resource '%1'.", + message: "Error: Interface operation not found in the component '%1'.", messageId: "SVC4701" } #---------SVC4702----------------------------- INTERFACE_OPERATION_NOT_DELETED: { - code: 404, + code: 400, message: "Error: Failed to delete interface operation.", messageId: "SVC4702" } @@ -2107,25 +2131,32 @@ errors: message: "Error: CSAR packaging failed for %1 %2.", messageId: "SVC4706" } - #---------SVC4704----------------------------- - # %1 - Interface Operation input property name + #---------SVC4708----------------------------- + # %1 - Interface Operation input property name, component type INTERFACE_OPERATION_INPUT_PROPERTY_NOT_FOUND_IN_COMPONENT: { code: 404, - message: "Error: Interface operation input parameter property '%1' not found in component input properties.", - messageId: "SVC4704" + message: "Error: Interface operation input parameter property '%1' not found in '%2' input properties, capability properties or outputs of other operations.", + messageId: "SVC4708" } - #---------SVC4705----------------------------- + #---------SVC4709----------------------------- # %1 - Interface Operation output parameter name INTERFACE_OPERATION_OUTPUT_NAME_ALREADY_IN_USE: { code: 400, message: "Error: Interface Operation output parameter name '%1' already in use, Your current changes will not be saved.", - messageId: "SVC4705" + messageId: "SVC4708" } - #---------SVC4706----------------------------- + #---------SVC4710----------------------------- INTERFACE_OPERATION_OUTPUT_NAME_MANDATORY: { - code: 404, + code: 400, message: "Error: Interface operation output parameter name should not be empty.", - messageId: "SVC4706" + messageId: "SVC4710" + } + #---------SVC4711----------------------------- + # %1 - interface Id + INTERFACE_NOT_FOUND_IN_COMPONENT: { + code: 404, + message: "Error: Interface not found in the component '%1'.", + messageId: "SVC4711" } #---------SVC4709----------------------------- INVALID_PROPERTY_CONSTRAINTS: { @@ -2237,34 +2268,177 @@ errors: message: "Error: Missing value for the mandatory %1 property" , messageId: "SVC4721" } + #---------SVC4712----------------------------- + INTERFACE_LIFECYCLE_TYPES_NOT_FOUND: { + code: 404, + message: "Error: Interface Lifecycle types not found.", + messageId: "SVC4712" + } + #---------SVC4713----------------------------- + # %1 - Interface Operation Name + INTERFACE_OPERATION_INVALID_FOR_GLOBAL_TYPE: { + code: 400, + message: "Error: Invalid input, only pre-defined operation names are allowed in global interface type '%1'", + messageId: "SVC4713" + } + + #---------SVC4714----------------------------- + NODE_FILTER_NOT_FOUND: { + code: 400, + message: "Error: Node Filter was not found", + messageId: "SVC4714" + } + #---------SVC4715---------------------------- + UNSUPPORTED_VALUE_PROVIDED: { + code: 400, + message: "Error: Supported value type is %1 for %2 property. Provided Value: %3", + messageId: "SVC4715" + } + #---------SVC4716---------------------------- + # %1 - Property Name + SELECTED_PROPERTY_NOT_PRESENT: { + code: 400, + message: "Error: %1 property does not exists in Service anymore.", + messageId: "SVC4716" + } + + #---------SVC4184---------------------------- + # %1 - Source type + # %2 - Property Type + # %3 - Property Name + FILTER_PROPERTY_NOT_FOUND: + code: 400 + message: "%1 %2 %3 does not exist." + messageId: "SVC4184" + + #---------SVC4718---------------------------- + # %1 - Property Name + # %2 - Operator Name + UNSUPPORTED_OPERATOR_PROVIDED: { + code: 400, + message: "Error: %1 property does not support %2 operator.", + messageId: "SVC4718" + } + + #---------SVC4719---------------------------- + CONSTRAINT_FORMAT_INCORRECT: { + code: 400, + message: "Error: Constraint provided does not contains expected values.", + messageId: "SVC4719" + } + + #---------SVC4182---------------------------- + # %1 - Property Name + # %2 - Operator Type + SOURCE_TARGET_PROPERTY_TYPE_MISMATCH: { + code: 400, + message: "Error: Property '%1' type '%2' does not match with property '%3' type '%4'.", + messageId: "SVC4182" + } + + #---------SVC4721---------------------------- + # %1 - Property Type + # %2 - Operator Type + UNSUPPORTED_PROPERTY_TYPE: { + code: 400, + message: "Error: Property type %1 provided against %2 is not supported for static value.", + messageId: "SVC4721" + } + #---------SVC4722------------------------------ + # %1 Directive value set + DIRECTIVES_INVALID_VALUE: { + code: 404, + message: "Error: Invalid directive value : '%1' .", + messageId: "SVC4722" + } + #---------SVC4723----------------------------- + # %1 - Interface Operation output name + INTERFACE_OPERATION_MAPPED_OUTPUT_MODIFIED: { + code: 400, + message: "Error: Cannot update or delete interface operation output(s) '%1' mapped to an operation input", + messageId: "SVC4723" + } + #---------SVC4724----------------------------- + # %1 - Interface Operation output name + INTERFACE_OPERATION_DELETE_WITH_MAPPED_OUTPUT: { + code: 400, + message: "Error: Cannot delete interface operation with output(s) '%1' mapped to another operation input", + messageId: "SVC4724" + } + #---------SVC4725----------------------------- + INVALID_CONSUMPTION_TYPE: { + code: 400, + message: "Error: Given value is different than input type. Needs to be %1", + messageId: "SVC4725" + } + #---------SVC4726----------------------------- + INVALID_PROPERTY_VALUES: { + code: 400, + message: "Error: Invalid property values provided:\n %1", + messageId: "SVC4726" + } + #---------SVC4727------------------------------ + INVALID_PROPERTY_NAME: { + code: 400, + message: "Error: Property name contains invalid characters. It should have only letters, numbers and underscores.", + messageId: "SVC4727" + } + + #---------SVC4728------------------------------ + FAILED_TO_CREATE_OR_UPDATE_CAPABILITY_PROPERTIES: { + code: 500, + message: "Error: Failed to create or update capabilities properties", + messageId: "SVC4728" + } + + #---------SVC4729------------------------------ + # %1 - resource Id + CAPABILITY_PROPERTIES_NOT_FOUND: { + code: 400, + message: "Error: Capability properties not found in the resource '%1'.", + messageId: "SVC4729" + } + #---------SVC4730------------------------------ # %1 - property name PROPERTY_EXCEEDS_LIMIT: { code: 400, message: "Error: Invalid Content. %1 exceeds limit.", messageId: "SVC4722" } - #---------SVC4723------------------------------ + #---------SVC4731------------------------------ INVALID_PROPERY: { # %1 - property name code: 400, message: 'Error: Invalid Content. %1 has invalid format.', messageId: "SVC4723" } - #---------SVC4801------------------------------ - # %1Â -Â policy type - POLICY_TYPE_IS_INVALID: { + #---------SVC4734------------------------------ + # %1 - list of validation errors + INVALID_PM_DICTIONARY_FILE: { code: 400, - message: "Error: Invalid content. Policy type %1 does not exist", - messageId: "SVC4801" + message: 'Error: Invalid PM Dictionary File. %1', + messageId: "SVC4734" } - - #---------SVC4802------------------------------ - # %1Â -Â policy name - POLICY_MISSING_POLICY_TYPE: { + #-----------SVC4735--------------------------- + #%1 - input name + INPUT_ALREADY_EXIST: { + code: 409, + message: "Error: Input with '%1' name already exists.", + messageId: "SVC4735" + } + #---------SVC4736------------------------------ + INVALID_INPUT_NAME: { code: 400, - message: "Error: Invalid content. Type name is not defined for policy %1", - messageId: "SVC4802" + message: "Error: Input name contains invalid characters. It should have only letters, numbers and underscores.", + messageId: "SVC4736" + } + #---------SVC4139------------------------------ + # %1 - The action that is not supported + NOT_SUPPORTED: { + code: 400, + message: '%1 is not yet supported', + messageId: "SVC4139" } #---------SVC4140------------------------------ # %1 - Component uid @@ -2294,31 +2468,172 @@ errors: message: "An unexpected error occurred while updating the capability '%1'.", messageId: "SVC4143" } + + #---------SVC4144------------------------------ + # %1 - "Model name" + MODEL_ALREADY_EXISTS: { + code: 409, + message: "Error: Model name '%1' already exists.", + messageId: "SVC4144" + } + + #---------SVC4145------------------------------ + # %1 - "Model name" + INVALID_MODEL: { + code: 400, + message: "Invalid model '%1'.", + messageId: "SVC4145" + } + + #---------SVC4146------------------------------ + MODEL_IMPORTS_IS_EMPTY: { + code: 400, + message: "Given model imports zip is empty.", + messageId: "SVC4146" + } + + #---------SVC4147------------------------------ + COULD_NOT_READ_MODEL_IMPORTS: { + code: 400, + message: "Could not read imports zip.", + messageId: "SVC4147" + } + + #---------SVC4148------------------------------ + # %1 - "Model name" + MODEL_NOT_FOUND: { + code: 404, + message: "Error: Model name '%1' not found. Please, make sure the model is created.", + messageId: "SVC4148" + } + + #---------SVC4149------------------------------ + MODEL_NAME_CANNOT_BE_EMPTY: { + code: 409, + message: "Error: Model name cannot be empty.", + messageId: "SVC4149" + } + + #-----------SVC4150--------------------------- + # %1 - "Component name" + # %2 - "Model name" + COMPONENT_WITH_MODEL_ALREADY_EXIST: { + code: 409, + message: "Error: Component %1 with Model %2 already exist.", + messageId: "SVC4150" + } + #-----------SVC4151--------------------------- + # %1 - "Component name" + # %2 - "Vendor release" + # %3 - "Model name" + COMPONENT_WITH_VENDOR_RELEASE_ALREADY_EXISTS_IN_MODEL: { + code: 409, + message: "Error: Component '%1' with Vendor Release '%2' already exists in Model '%3'.", + messageId: "SVC4151" + } + #-----------SVC4152--------------------------- + # %1 - "Component name" + # %2 - "Vendor release" + COMPONENT_WITH_VENDOR_RELEASE_ALREADY_EXISTS: { + code: 409, + message: "Error: Component '%1' with Vendor Release '%2' already exists.", + messageId: "SVC4152" + } + + #-----------SVC4153--------------------------- + # %1 - "Model name" + DATA_TYPES_NOT_LOADED: { + code: 500, + message: "Could not fetch data types from data base with model %1", + messageId: "SVC4153" + } + #-----------SVC4154--------------------------- + # %1 - "Model name" + UNKNOWN_MODEL_TYPE: { + code: 400, + message: "Error: Model type %1 not known in the system", + messageId: "SVC4154" + } + + #-----------SVC4154--------------------------- + CSAR_TOSCA_IMPORTS_ERROR: { + code: 500, + message: "Error: An error has occurred while including the default TOSCA imports in the CSAR", + messageId: "SVC4154" + } + + #-----------SVC4155--------------------------- # %1 - "VSP id" # %2 - "VSP version id" VSP_FIND_ERROR: { code: 500, message: "An error has occurred while retrieving the Vendor Software Product of id '%1', version id '%2'", - messageId: "SVC4154" + messageId: "SVC4155" } - #-----------SVC4155--------------------------- + #-----------SVC4156--------------------------- # %1 - "VSP id" # %2 - "VSP version id" VSP_NOT_FOUND: { code: 404, message: "Could not find Vendor Software Product of id '%1', version id '%2'", - messageId: "SVC4155" + messageId: "SVC4156" } - #-----------SVC4156--------------------------- + #-----------SVC4157--------------------------- # %1 - "The model name" # %2 - "List of allowed models" VSP_MODEL_NOT_ALLOWED: { code: 400, message: "The Model '%1' is not allowed for the imported Vendor Software Product. Allowed Models: '%2'", - messageId: "SVC4156" + messageId: "SVC4157" + } + + #---------SVC4158----------------------------- + # %1 - Valid artifact label name + INVALID_ARTIFACT_LABEL_NAME: { + code: 400, + message: "Invalid label name. Only the following characters are allowed in label name: '%1'", + messageId: "SVC4158" + } + + #---------SVC4159----------------------------- + # %1 - The model name + COULD_NOT_DELETE_MODEL: { + code: 500, + message: "Could not delete the model '%1'.", + messageId: "SVC4159" + } + + #---------SVC4160----------------------------- + # %1 - The model name + COULD_NOT_DELETE_MODEL_ELEMENTS: { + code: 500, + message: "Could not delete the model '%1' elements.", + messageId: "SVC4160" + } + #---------SVC4161----------------------------- + INVALID_NODE_TYPES_YAML: { + code: 400, + message: "Invalid node_types TOSCA yaml", + messageId: "SVC4161" + } + + #---------SVC4162----------------------------- + # %1 - The janusgraph status + FAILED_CREATE_ARTIFACTS_TYPES: { + code: 500, + message: "Failed to create artifact types with status '%1'.", + messageId: "SVC4162" + } + + #---------SVC4163----------------------------- + # %1 - The janusgraph status + ARTIFACT_TYPE_ALREADY_EXIST: { + code: 409, + message: "Artifact type '%1' already exist.", + messageId: "SVC4163" } #---------SVC4692----------------------------- @@ -2336,6 +2651,16 @@ errors: message: "Component is in use by '%1'", messageId: "SVC4693" } + + #---------SVC4164----------------------------- + # %1 - componentType + # %2 - component name + CANNOT_DELETE_SYSTEM_DEPLOYED_RESOURCES: { + code: 409, + message: "System deployed '%1' cannot be deleted '%2'", + messageId: "SVC4164" + } + #---------SVC4165----------------------------- # %1 - input origin TOSCA_GET_FUNCTION_INPUTS_ONLY_SELF_ERROR: { @@ -2393,6 +2718,14 @@ errors: messageId: "SVC4170" } + #---------SVC4171----------------------------- + # %1 - Instance name + TOSCA_GET_FUNCTION_INSTANCE_NOT_FOUND: { + code: 404, + message: "The instance '%1' was not found.", + messageId: "SVC4171" + } + #-----------SVC4172--------------------------- #%1 - TOSCA function attribute TOSCA_FUNCTION_MISSING_ATTRIBUTE: { @@ -2401,3 +2734,82 @@ errors: messageId: "SVC4172" } + #-----------SVC4173--------------------------- + RELATIONSHIP_TEMPLATE_NOT_FOUND: { + code: 404, + message: "Relationship_templates entry not found in TOSCA CSAR.", + messageId: "SVC4173" + } + + #-----------SVC4174--------------------------- + RELATIONSHIP_TEMPLATE_DEFINITION_NOT_FOUND: { + code: 404, + message: "Relationship_templates definition not found in TOSCA CSAR.", + messageId: "SVC4174" + } + + #-----------SVC4175--------------------------- + TOSCA_FUNCTION_EXPECTED_ERROR: { + code: 400, + message: "Expecting a Tosca Function value.", + messageId: "SVC4175" + } + + #-----------SVC4176--------------------------- + FILTER_CONSTRAINT_MISSING: { + code: 400, + message: "The filter constraint was not provided.", + messageId: "SVC4176" + } + + #-----------SVC4177--------------------------- + #%1 - The missing field + FILTER_CONSTRAINT_MISSING_FIELD: { + code: 400, + message: "Required field '%1' is missing in the filter constraint.", + messageId: "SVC4177" + } + + #%1 - the component id + SUBSTITUTION_FILTER_NOT_FOUND: { + code: 404, + message: 'Substitution filter not found in the component "%1"', + messageId: "SVC4178" + } + + # %1 - Component name + COMPONENT_DOES_NOT_HAVE_INPUTS: { + code: 400, + message: "Component '%1' does not have inputs.", + messageId: "SVC4179" + } + + # %1 - Input name + # %2 - Component name + COMPONENT_INPUT_NOT_FOUND: { + code: 400, + message: "Input '%1' does not exist in '%2'.", + messageId: "SVC4180" + } + + # %1 - Target property name + # %2 - Source property name + SOURCE_TARGET_SCHEMA_MISMATCH: { + code: 400, + message: "Target property '%1' schema '%2' does not match with source property '%3' schema '%4'.", + messageId: "SVC4181" + } + + # %1 - Property name + # %2 - Component name + COMPONENT_PROPERTY_NOT_FOUND: + code: 400 + message: "Property '%1' does not exist in '%2'." + messageId: "SVC4183" + + # %1 - The component type + # %2 - The expected component types + INVALID_COMPONENT_TYPE: + code: 400 + message: "Invalid component type '%1'. Expected types are: %2" + messageId: "SVC4185" diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java index 603f9ccf61..6208f11732 100644 --- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java @@ -108,9 +108,9 @@ public enum ActionStatus { //InterfaceOperation INTERFACE_OPERATION_NOT_FOUND, INTERFACE_OPERATION_NAME_ALREADY_IN_USE, INTERFACE_OPERATION_NAME_MANDATORY, INTERFACE_OPERATION_NAME_INVALID, INTERFACE_OPERATION_INPUT_NAME_ALREADY_IN_USE, INTERFACE_OPERATION_OUTPUT_NAME_ALREADY_IN_USE, INTERFACE_OPERATION_NOT_DELETED, INTERFACE_OPERATION_MAPPED_OUTPUT_MODIFIED, INTERFACE_OPERATION_DELETE_WITH_MAPPED_OUTPUT, INTERFACE_OPERATION_INPUT_NAME_MANDATORY, INTERFACE_OPERATION_OUTPUT_NAME_MANDATORY, INTERFACE_OPERATION_INPUT_PROPERTY_NOT_FOUND_IN_COMPONENT, INTERFACE_OPERATION_INVALID_FOR_LOCAL_TYPE, INTERFACE_OPERATION_INVALID_FOR_GLOBAL_TYPE, INTERFACE_OPERATION_NOT_DEFINED, PROPERTY_USED_BY_OPERATION, DECLARED_INPUT_USED_BY_OPERATION, INVALID_CONSUMPTION_TYPE, //NodeFilter - NODE_FILTER_NOT_FOUND, UNSUPPORTED_VALUE_PROVIDED, SELECTED_PROPERTY_NOT_PRESENT, MAPPED_PROPERTY_NOT_FOUND, UNSUPPORTED_OPERATOR_PROVIDED, CONSTRAINT_FORMAT_INCORRECT, SOURCE_TARGET_PROPERTY_TYPE_MISMATCH, SOURCE_TARGET_SCHEMA_MISMATCH, UNSUPPORTED_PROPERTY_TYPE, + NODE_FILTER_NOT_FOUND, UNSUPPORTED_VALUE_PROVIDED, SELECTED_PROPERTY_NOT_PRESENT, FILTER_PROPERTY_NOT_FOUND, UNSUPPORTED_OPERATOR_PROVIDED, CONSTRAINT_FORMAT_INCORRECT, SOURCE_TARGET_PROPERTY_TYPE_MISMATCH, SOURCE_TARGET_SCHEMA_MISMATCH, UNSUPPORTED_PROPERTY_TYPE, //Filter - SUBSTITUTION_FILTER_NOT_FOUND, FILTER_NOT_FOUND, + SUBSTITUTION_FILTER_NOT_FOUND, //InterfaceLifeCycleType INTERFACE_LIFECYCLE_TYPES_NOT_FOUND, INVALID_PROPERTY_NAME, INVALID_INPUT_NAME, //Property Constraints @@ -140,7 +140,13 @@ public enum ActionStatus { TOSCA_GET_FUNCTION_PROPERTY_NOT_FOUND, TOSCA_GET_FUNCTION_INSTANCE_NOT_FOUND, TOSCA_FUNCTION_MISSING_ATTRIBUTE, + TOSCA_FUNCTION_EXPECTED_ERROR, RELATIONSHIP_TEMPLATE_NOT_FOUND, - RELATIONSHIP_TEMPLATE_DEFINITION_NOT_FOUND - + RELATIONSHIP_TEMPLATE_DEFINITION_NOT_FOUND, + FILTER_CONSTRAINT_MISSING_FIELD, + FILTER_CONSTRAINT_MISSING, + COMPONENT_DOES_NOT_HAVE_INPUTS, + COMPONENT_INPUT_NOT_FOUND, + COMPONENT_PROPERTY_NOT_FOUND, + INVALID_COMPONENT_TYPE } diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ParsedToscaYamlInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ParsedToscaYamlInfo.java index 6af88e1215..326cfca202 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ParsedToscaYamlInfo.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ParsedToscaYamlInfo.java @@ -24,7 +24,7 @@ import lombok.Getter; import lombok.Setter; import lombok.ToString; import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; -import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterPropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterPropertyDataDefinition; @ToString @Getter @@ -37,6 +37,6 @@ public class ParsedToscaYamlInfo { Map<String, GroupDefinition> groups; Map<String, PolicyDefinition> policies; Map<String, PropertyDefinition> properties; - ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> substitutionFilterProperties; + ListDataDefinition<SubstitutionFilterPropertyDataDefinition> substitutionFilterProperties; String substitutionMappingNodeType; } diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyConstraint.java index 6bc8083118..12a79ec90e 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyConstraint.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyConstraint.java @@ -21,7 +21,7 @@ package org.openecomp.sdc.be.model; import com.fasterxml.jackson.annotation.JsonIgnore; import org.openecomp.sdc.be.model.tosca.ToscaType; -import org.openecomp.sdc.be.model.tosca.constraints.ConstraintType; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintFunctionalException; import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException; import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException; diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ToscaPropertyData.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ToscaPropertyData.java index 14c95757c7..6626d9aa3d 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ToscaPropertyData.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ToscaPropertyData.java @@ -26,6 +26,7 @@ package org.openecomp.sdc.be.model; */ public interface ToscaPropertyData { String getUniqueId(); + String getName(); String getType(); String getSchemaType(); } diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/dto/FilterConstraintDto.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/dto/FilterConstraintDto.java new file mode 100644 index 0000000000..b9ceb11276 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/dto/FilterConstraintDto.java @@ -0,0 +1,58 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.openecomp.sdc.be.model.dto; + +import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.Optional; +import lombok.Data; +import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; +import org.openecomp.sdc.be.datatypes.enums.FilterValueType; +import org.openecomp.sdc.be.datatypes.enums.PropertyFilterTargetType; + +@Data +public class FilterConstraintDto { + + private String propertyName; + private String capabilityName; + private PropertyFilterTargetType targetType; + private ConstraintType operator; + private FilterValueType valueType; + private Object value; + + public boolean isCapabilityPropertyFilter() { + return capabilityName != null; + } + + public Optional<ToscaGetFunctionDataDefinition> getAsToscaGetFunction() { + if (value instanceof ToscaGetFunctionDataDefinition) { + return Optional.of((ToscaGetFunctionDataDefinition) value); + } + try { + return Optional.of(new ObjectMapper().convertValue(value, ToscaGetFunctionDataDefinition.class)); + } catch (final Exception ignored) { + return Optional.empty(); + } + } + +} + diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeFilterOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeFilterOperation.java index 2d0693af76..3dc2a73466 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeFilterOperation.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeFilterOperation.java @@ -19,8 +19,6 @@ */ package org.openecomp.sdc.be.model.jsonjanusgraph.operations; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; import fj.data.Either; import java.util.ArrayList; import java.util.List; @@ -33,8 +31,8 @@ import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum; import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum; import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyFilterDataDefinition; import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterCapabilityDataDefinition; -import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition; import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields; import org.openecomp.sdc.be.datatypes.enums.NodeFilterConstraintType; import org.openecomp.sdc.be.model.Component; @@ -69,7 +67,7 @@ public class NodeFilterOperation extends BaseOperation { public Either<String, StorageOperationStatus> deleteNodeFilter(final Component component, final String componentInstanceId) { final Either<Set<String>, StorageOperationStatus> listStorageOperationStatusEither = deleteNodeFilters(component, - ImmutableSet.of(componentInstanceId)); + Set.of(componentInstanceId)); if (listStorageOperationStatusEither.isRight()) { return Either.right(listStorageOperationStatusEither.right().value()); } @@ -86,7 +84,7 @@ public class NodeFilterOperation extends BaseOperation { final int propertyIndex, final NodeFilterConstraintType nodeFilterConstraintType) { if (NodeFilterConstraintType.PROPERTIES.equals(nodeFilterConstraintType)) { - final ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> properties = nodeFilterDataDefinition.getProperties(); + final ListDataDefinition<PropertyFilterDataDefinition> properties = nodeFilterDataDefinition.getProperties(); properties.getListToscaDataDefinition().remove(propertyIndex); nodeFilterDataDefinition.setProperties(properties); } else if (NodeFilterConstraintType.CAPABILITIES.equals(nodeFilterConstraintType)) { @@ -97,22 +95,22 @@ public class NodeFilterOperation extends BaseOperation { return addOrUpdateNodeFilter(true, serviceId, componentInstanceId, nodeFilterDataDefinition); } - public Either<CINodeFilterDataDefinition, StorageOperationStatus> addNewProperty(final String componentId, final String componentInstanceId, - final CINodeFilterDataDefinition nodeFilterDataDefinition, - final RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition) { - ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> properties = nodeFilterDataDefinition.getProperties(); + public Either<CINodeFilterDataDefinition, StorageOperationStatus> addPropertyFilter(final String componentId, final String componentInstanceId, + final CINodeFilterDataDefinition nodeFilterDataDefinition, + final PropertyFilterDataDefinition propertyFilterDataDefinition) { + ListDataDefinition<PropertyFilterDataDefinition> properties = nodeFilterDataDefinition.getProperties(); if (properties == null) { properties = new ListDataDefinition<>(); nodeFilterDataDefinition.setProperties(properties); } - properties.getListToscaDataDefinition().add(requirementNodeFilterPropertyDataDefinition); + properties.getListToscaDataDefinition().add(propertyFilterDataDefinition); nodeFilterDataDefinition.setProperties(properties); return addOrUpdateNodeFilter(true, componentId, componentInstanceId, nodeFilterDataDefinition); } - public Either<CINodeFilterDataDefinition, StorageOperationStatus> addNewCapabilities(final String componentId, final String componentInstanceId, - final CINodeFilterDataDefinition nodeFilterDataDefinition, - final RequirementNodeFilterCapabilityDataDefinition requirementNodeFilterCapabilityDataDefinition) { + public Either<CINodeFilterDataDefinition, StorageOperationStatus> addCapabilities(final String componentId, final String componentInstanceId, + final CINodeFilterDataDefinition nodeFilterDataDefinition, + final RequirementNodeFilterCapabilityDataDefinition requirementNodeFilterCapabilityDataDefinition) { ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> capabilities = nodeFilterDataDefinition.getCapabilities(); if (capabilities == null) { capabilities = new ListDataDefinition<>(); @@ -124,9 +122,9 @@ public class NodeFilterOperation extends BaseOperation { .filter(def -> def.getName().equals(requirementNodeFilterCapabilityDataDefinition.getName())).findAny(); if (existingCap.isPresent()) { - final ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> newProperties = requirementNodeFilterCapabilityDataDefinition.getProperties(); - final ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> existingProperties = existingCap.get().getProperties(); - newProperties.getListToscaDataDefinition().stream().forEach((prop -> existingProperties.add(prop))) ; + final ListDataDefinition<PropertyFilterDataDefinition> newProperties = requirementNodeFilterCapabilityDataDefinition.getProperties(); + final ListDataDefinition<PropertyFilterDataDefinition> existingProperties = existingCap.get().getProperties(); + newProperties.getListToscaDataDefinition().forEach((existingProperties::add)) ; } else { capabilities.getListToscaDataDefinition().add(requirementNodeFilterCapabilityDataDefinition); } @@ -134,26 +132,6 @@ public class NodeFilterOperation extends BaseOperation { return addOrUpdateNodeFilter(true, componentId, componentInstanceId, nodeFilterDataDefinition); } - public Either<CINodeFilterDataDefinition, StorageOperationStatus> updateProperties(final String componentId, final String componentInstanceId, - final CINodeFilterDataDefinition nodeFilterDataDefinition, - final List<RequirementNodeFilterPropertyDataDefinition> requirementNodeFilterPropertyDataDefinition) { - final ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> properties = nodeFilterDataDefinition.getProperties(); - properties.getListToscaDataDefinition().clear(); - properties.getListToscaDataDefinition().addAll(requirementNodeFilterPropertyDataDefinition); - nodeFilterDataDefinition.setProperties(properties); - return addOrUpdateNodeFilter(true, componentId, componentInstanceId, nodeFilterDataDefinition); - } - - public Either<CINodeFilterDataDefinition, StorageOperationStatus> updateCapabilities(final String componentId, final String componentInstanceId, - final CINodeFilterDataDefinition nodeFilterDataDefinition, - final List<RequirementNodeFilterCapabilityDataDefinition> requirementNodeFilterCapabilityDataDefinitions) { - final ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> capabilities = nodeFilterDataDefinition.getCapabilities(); - capabilities.getListToscaDataDefinition().clear(); - capabilities.getListToscaDataDefinition().addAll(requirementNodeFilterCapabilityDataDefinitions); - nodeFilterDataDefinition.setCapabilities(capabilities); - return addOrUpdateNodeFilter(true, componentId, componentInstanceId, nodeFilterDataDefinition); - } - public Either<CINodeFilterDataDefinition, StorageOperationStatus> updateNodeFilter(final String serviceId, final String componentInstanceId, final CINodeFilterDataDefinition ciNodeFilterDataDefinition) { return addOrUpdateNodeFilter(true, serviceId, componentInstanceId, ciNodeFilterDataDefinition); @@ -169,20 +147,19 @@ public class NodeFilterOperation extends BaseOperation { private Either<CINodeFilterDataDefinition, StorageOperationStatus> addOrUpdateNodeFilter(final boolean isUpdateAction, final String componentId, final String componentInstanceId, final CINodeFilterDataDefinition ciNodeFilterDataDefinition) { - StorageOperationStatus statusRes; - Either<GraphVertex, JanusGraphOperationStatus> getToscaElementRes; - getToscaElementRes = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.NoParse); - if (getToscaElementRes.isRight()) { - JanusGraphOperationStatus status = getToscaElementRes.right().value(); + + final Either<GraphVertex, JanusGraphOperationStatus> serviceVertexEither = + janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.NoParse); + if (serviceVertexEither.isRight()) { + JanusGraphOperationStatus status = serviceVertexEither.right().value(); CommonUtility .addRecordToLog(logger, CommonUtility.LogLevelEnum.DEBUG, "Failed to get tosca element {} upon adding the properties. Status is {}. ", componentId, status); - statusRes = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status); - return Either.right(statusRes); + return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status)); } - GraphVertex serviceVertex = getToscaElementRes.left().value(); + final GraphVertex serviceVertex = serviceVertexEither.left().value(); ciNodeFilterDataDefinition.setID(componentInstanceId); - statusRes = performUpdateToscaAction(isUpdateAction, serviceVertex, ImmutableList.of(ciNodeFilterDataDefinition)); + final StorageOperationStatus statusRes = performUpdateToscaAction(isUpdateAction, serviceVertex, List.of(ciNodeFilterDataDefinition)); if (!statusRes.equals(StorageOperationStatus.OK)) { janusGraphDao.rollback(); logger.error(" Failed to perform tosca update for node filter in service {} , component instance {}. status is {}", componentId, diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/SubstitutionFilterOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/SubstitutionFilterOperation.java index b4873fa78a..ca50f42453 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/SubstitutionFilterOperation.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/SubstitutionFilterOperation.java @@ -18,7 +18,6 @@ */ package org.openecomp.sdc.be.model.jsonjanusgraph.operations; -import com.google.common.collect.ImmutableList; import fj.data.Either; import java.util.List; import java.util.Objects; @@ -28,8 +27,8 @@ import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum; import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum; import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum; import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; -import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterPropertyDataDefinition; import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterPropertyDataDefinition; import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter; @@ -50,7 +49,7 @@ public class SubstitutionFilterOperation extends BaseOperation { public Either<SubstitutionFilterDataDefinition, StorageOperationStatus> deleteConstraint(final String serviceId, final SubstitutionFilterDataDefinition substitutionFilterDataDefinition, final int propertyIndex) { - final ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> properties = substitutionFilterDataDefinition.getProperties(); + final ListDataDefinition<SubstitutionFilterPropertyDataDefinition> properties = substitutionFilterDataDefinition.getProperties(); properties.getListToscaDataDefinition().remove(propertyIndex); substitutionFilterDataDefinition.setProperties(properties); return addOrUpdateSubstitutionFilter(true, serviceId, substitutionFilterDataDefinition); @@ -58,26 +57,34 @@ public class SubstitutionFilterOperation extends BaseOperation { public Either<SubstitutionFilterDataDefinition, StorageOperationStatus> addPropertyFilter(final String componentId, final SubstitutionFilterDataDefinition substitutionFilterDataDefinition, - final RequirementSubstitutionFilterPropertyDataDefinition substitutionFilterPropertyDataDefinition) { + final SubstitutionFilterPropertyDataDefinition substitutionFilterPropertyDataDefinition) { final SubstitutionFilterDataDefinition substitutionFilterDataDefinition1 = Objects .requireNonNullElseGet(substitutionFilterDataDefinition, SubstitutionFilterDataDefinition::new); - final ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> properties = Objects + final ListDataDefinition<SubstitutionFilterPropertyDataDefinition> properties = Objects .requireNonNullElseGet(substitutionFilterDataDefinition1.getProperties(), ListDataDefinition::new); properties.getListToscaDataDefinition().add(substitutionFilterPropertyDataDefinition); substitutionFilterDataDefinition1.setProperties(properties); return addOrUpdateSubstitutionFilter(true, componentId, substitutionFilterDataDefinition1); } - public Either<SubstitutionFilterDataDefinition, StorageOperationStatus> updateProperties(final String componentId, - final SubstitutionFilterDataDefinition substitutionFilterDataDefinition, - final List<RequirementSubstitutionFilterPropertyDataDefinition> requirementSubstitutionFilterPropertyDataDefinition) { - final ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> properties = substitutionFilterDataDefinition.getProperties(); + public Either<SubstitutionFilterDataDefinition, StorageOperationStatus> updatePropertyFilters(final String componentId, + final SubstitutionFilterDataDefinition substitutionFilterDataDefinition, + final List<SubstitutionFilterPropertyDataDefinition> substitutionFilterPropertyDataDefinition) { + final ListDataDefinition<SubstitutionFilterPropertyDataDefinition> properties = substitutionFilterDataDefinition.getProperties(); properties.getListToscaDataDefinition().clear(); - properties.getListToscaDataDefinition().addAll(requirementSubstitutionFilterPropertyDataDefinition); + properties.getListToscaDataDefinition().addAll(substitutionFilterPropertyDataDefinition); substitutionFilterDataDefinition.setProperties(properties); return addOrUpdateSubstitutionFilter(true, componentId, substitutionFilterDataDefinition); } + public Either<SubstitutionFilterDataDefinition, StorageOperationStatus> updatePropertyFilter(final String componentId, + final SubstitutionFilterDataDefinition substitutionFilter, + final SubstitutionFilterPropertyDataDefinition substitutionFilterProperty, + final int index) { + substitutionFilter.getProperties().getListToscaDataDefinition().set(index, substitutionFilterProperty); + return addOrUpdateSubstitutionFilter(true, componentId, substitutionFilter); + } + private Either<SubstitutionFilterDataDefinition, StorageOperationStatus> addOrUpdateSubstitutionFilter(final boolean isUpdateAction, final String componentId, final SubstitutionFilterDataDefinition substitutionFilterDataDefinition) { @@ -92,7 +99,7 @@ public class SubstitutionFilterOperation extends BaseOperation { final GraphVertex serviceVertex = toscaElementEither.left().value(); substitutionFilterDataDefinition.setID(componentId); final StorageOperationStatus operationStatus = performUpdateToscaAction(isUpdateAction, serviceVertex, - ImmutableList.of(substitutionFilterDataDefinition)); + List.of(substitutionFilterDataDefinition)); if (!StorageOperationStatus.OK.equals(operationStatus)) { janusGraphDao.rollback(); LOGGER.error(EcompErrorSeverity.ERROR, EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperation.java index b5215dc848..6b580527c4 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperation.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperation.java @@ -82,12 +82,11 @@ import org.openecomp.sdc.be.model.DataTypeDefinition; import org.openecomp.sdc.be.model.IComplexDefaultValue; import org.openecomp.sdc.be.model.PropertyConstraint; import org.openecomp.sdc.be.model.PropertyDefinition; -import org.openecomp.sdc.be.model.validation.ToscaFunctionValidator; import org.openecomp.sdc.be.model.operations.api.DerivedFromOperation; import org.openecomp.sdc.be.model.operations.api.IPropertyOperation; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; -import org.openecomp.sdc.be.model.tosca.constraints.ConstraintType; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; import org.openecomp.sdc.be.model.tosca.constraints.GreaterOrEqualConstraint; import org.openecomp.sdc.be.model.tosca.constraints.GreaterThanConstraint; import org.openecomp.sdc.be.model.tosca.constraints.InRangeConstraint; @@ -96,6 +95,7 @@ import org.openecomp.sdc.be.model.tosca.constraints.LessThanConstraint; import org.openecomp.sdc.be.model.tosca.constraints.MinLengthConstraint; import org.openecomp.sdc.be.model.tosca.constraints.ValidValuesConstraint; import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter; +import org.openecomp.sdc.be.model.validation.ToscaFunctionValidator; import org.openecomp.sdc.be.resources.data.ComponentInstanceData; import org.openecomp.sdc.be.resources.data.DataTypeData; import org.openecomp.sdc.be.resources.data.ModelData; @@ -2145,7 +2145,7 @@ public class PropertyOperation extends AbstractOperation implements IPropertyOpe Entry<String, JsonElement> element = set.iterator().next(); String key = element.getKey(); JsonElement value = element.getValue(); - ConstraintType constraintType = ConstraintType.getByType(key); + ConstraintType constraintType = ConstraintType.findByType(key).orElse(null); if (constraintType == null) { log.warn("ConstraintType was not found for constraint name:{}", key); } else { diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/ToscaPropertyType.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/ToscaPropertyType.java index ec7ca43155..364dfd33fb 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/ToscaPropertyType.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/ToscaPropertyType.java @@ -71,10 +71,10 @@ public enum ToscaPropertyType { JSON("json", JsonValidator.getInstance(), JsonConverter.getInstance(), ToscaJsonValueConverter.getInstance()); // @formatter:on - private String type; - private PropertyTypeValidator validator; - private PropertyValueConverter converter; - private ToscaValueConverter valueConverter; + private final String type; + private final PropertyTypeValidator validator; + private final PropertyValueConverter converter; + private final ToscaValueConverter valueConverter; private boolean isAbstract = false; ToscaPropertyType(String type, PropertyTypeValidator validator, PropertyValueConverter converter, ToscaValueConverter valueConverter) { @@ -111,10 +111,7 @@ public enum ToscaPropertyType { if (ToscaPropertyType.MAP.getType().equals(dataTypeName) || ToscaPropertyType.LIST.getType().equals(dataTypeName)) { return false; } - if (isScalarType(dataTypeName)) { - return true; - } - return false; + return isScalarType(dataTypeName); } public static ToscaPropertyType getTypeIfScalar(String dataTypeName) { diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ConstraintType.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ConstraintType.java deleted file mode 100644 index 3647bd67d0..0000000000 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ConstraintType.java +++ /dev/null @@ -1,58 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * 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. - * ============LICENSE_END========================================================= - */ -package org.openecomp.sdc.be.model.tosca.constraints; - -import java.util.Arrays; -import java.util.List; - -public enum ConstraintType { - // @formatter:off - EQUAL("equal", "equal"), - IN_RANGE("inRange", "in_range"), - GREATER_THAN("greaterThan", "greater_than"), - GREATER_OR_EQUAL("greaterOrEqual", "greater_or_equal"), - LESS_OR_EQUAL("lessOrEqual", "less_or_equal"), - LENGTH("length", "length"), - MIN_LENGTH("minLength", "min_length"), - MAX_LENGTH("maxLength", "max_length"), - VALID_VALUES("validValues", "valid_values"), - LESS_THAN("lessThan", "less_than"), - SCHEMA("schema", "schema"); - // @formatter:on - - List<String> types; - - private ConstraintType(String... types) { - this.types = Arrays.asList(types); - } - - public static ConstraintType getByType(String type) { - for (ConstraintType inst : ConstraintType.values()) { - if (inst.getTypes().contains(type)) { - return inst; - } - } - return null; - } - - public List<String> getTypes() { - return types; - } -} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/EqualConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/EqualConstraint.java index 4b62b12897..c4b26f3077 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/EqualConstraint.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/EqualConstraint.java @@ -21,6 +21,7 @@ package org.openecomp.sdc.be.model.tosca.constraints; import java.io.Serializable; import javax.validation.constraints.NotNull; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; import org.openecomp.sdc.be.model.PropertyConstraint; import org.openecomp.sdc.be.model.tosca.ToscaType; import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintFunctionalException; diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/GreaterOrEqualConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/GreaterOrEqualConstraint.java index dc50d7d549..d32ab721fc 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/GreaterOrEqualConstraint.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/GreaterOrEqualConstraint.java @@ -23,6 +23,7 @@ import javax.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; import org.openecomp.sdc.be.model.PropertyConstraint; import org.openecomp.sdc.be.model.tosca.ToscaType; import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintFunctionalException; diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/GreaterThanConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/GreaterThanConstraint.java index 0b76e97967..e50c8fe3d0 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/GreaterThanConstraint.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/GreaterThanConstraint.java @@ -20,6 +20,7 @@ package org.openecomp.sdc.be.model.tosca.constraints; import javax.validation.constraints.NotNull; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; import org.openecomp.sdc.be.model.PropertyConstraint; import org.openecomp.sdc.be.model.tosca.ToscaType; import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintFunctionalException; diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/InRangeConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/InRangeConstraint.java index bfb1b75a5c..d574816c5f 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/InRangeConstraint.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/InRangeConstraint.java @@ -22,6 +22,7 @@ package org.openecomp.sdc.be.model.tosca.constraints; import com.google.common.collect.Lists; import java.util.List; import javax.validation.constraints.NotNull; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; import org.openecomp.sdc.be.model.PropertyConstraint; import org.openecomp.sdc.be.model.tosca.ToscaType; import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintFunctionalException; diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LengthConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LengthConstraint.java index 3c89ed1b07..457c824ac6 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LengthConstraint.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LengthConstraint.java @@ -22,6 +22,7 @@ package org.openecomp.sdc.be.model.tosca.constraints; import java.util.List; import java.util.Map; import javax.validation.constraints.NotNull; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; import org.openecomp.sdc.be.model.PropertyConstraint; import org.openecomp.sdc.be.model.tosca.ToscaType; import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintFunctionalException; diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LessOrEqualConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LessOrEqualConstraint.java index 653c93bf29..62cec05a73 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LessOrEqualConstraint.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LessOrEqualConstraint.java @@ -20,6 +20,7 @@ package org.openecomp.sdc.be.model.tosca.constraints; import javax.validation.constraints.NotNull; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; import org.openecomp.sdc.be.model.PropertyConstraint; import org.openecomp.sdc.be.model.tosca.ToscaType; import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintFunctionalException; diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LessThanConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LessThanConstraint.java index 59c091f224..c721c5cd63 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LessThanConstraint.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LessThanConstraint.java @@ -21,6 +21,7 @@ package org.openecomp.sdc.be.model.tosca.constraints; import javax.validation.constraints.NotNull; import lombok.AllArgsConstructor; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; import org.openecomp.sdc.be.model.PropertyConstraint; import org.openecomp.sdc.be.model.tosca.ToscaType; import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintFunctionalException; diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/MaxLengthConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/MaxLengthConstraint.java index 2535d972ca..004e431485 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/MaxLengthConstraint.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/MaxLengthConstraint.java @@ -22,6 +22,7 @@ package org.openecomp.sdc.be.model.tosca.constraints; import java.util.List; import java.util.Map; import javax.validation.constraints.NotNull; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; import org.openecomp.sdc.be.model.PropertyConstraint; import org.openecomp.sdc.be.model.tosca.ToscaType; import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintFunctionalException; diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/MinLengthConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/MinLengthConstraint.java index 98fda80604..a2ff95512a 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/MinLengthConstraint.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/MinLengthConstraint.java @@ -22,6 +22,7 @@ package org.openecomp.sdc.be.model.tosca.constraints; import java.util.List; import java.util.Map; import javax.validation.constraints.NotNull; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; import org.openecomp.sdc.be.model.PropertyConstraint; import org.openecomp.sdc.be.model.tosca.ToscaType; import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintFunctionalException; diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/PatternConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/PatternConstraint.java index e3f4d3e7e3..e519f1b7e4 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/PatternConstraint.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/PatternConstraint.java @@ -21,6 +21,7 @@ package org.openecomp.sdc.be.model.tosca.constraints; import java.util.regex.Pattern; import javax.validation.constraints.NotNull; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; import org.openecomp.sdc.be.model.PropertyConstraint; import org.openecomp.sdc.be.model.tosca.ToscaType; import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintFunctionalException; diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ValidValuesConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ValidValuesConstraint.java index fb4685d716..1cafc213bb 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ValidValuesConstraint.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ValidValuesConstraint.java @@ -26,6 +26,7 @@ import java.util.List; import java.util.Set; import javax.validation.constraints.NotNull; import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; import org.openecomp.sdc.be.model.PropertyConstraint; import org.openecomp.sdc.be.model.tosca.ToscaType; import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintFunctionalException; diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/DataTypeValidatorConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/DataTypeValidatorConverter.java index 0a537a5445..4a5cda2fdd 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/DataTypeValidatorConverter.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/DataTypeValidatorConverter.java @@ -29,6 +29,8 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; import org.apache.commons.lang3.tuple.ImmutablePair; import org.openecomp.sdc.be.model.DataTypeDefinition; import org.openecomp.sdc.be.model.PropertyDefinition; @@ -36,18 +38,13 @@ import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter; import org.openecomp.sdc.common.log.wrappers.Logger; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public class DataTypeValidatorConverter { private static final Logger log = Logger.getLogger(DataTypeValidatorConverter.class.getName()); - private static DataTypeValidatorConverter dataTypeValidatorConverter = new DataTypeValidatorConverter(); - JsonParser jsonParser = new JsonParser(); - ImmutablePair<JsonElement, Boolean> falseResult = new ImmutablePair<>(null, false); - ImmutablePair<JsonElement, Boolean> trueEmptyResult = new ImmutablePair<>(null, true); - ImmutablePair<String, Boolean> trueStringEmptyResult = new ImmutablePair<>(null, true); - ImmutablePair<String, Boolean> falseStringEmptyResult = new ImmutablePair<>(null, true); - - private DataTypeValidatorConverter() { - } + private static final DataTypeValidatorConverter dataTypeValidatorConverter = new DataTypeValidatorConverter(); + private static final ImmutablePair<JsonElement, Boolean> falseResult = new ImmutablePair<>(null, false); + private static final ImmutablePair<JsonElement, Boolean> trueEmptyResult = new ImmutablePair<>(null, true); public static DataTypeValidatorConverter getInstance() { return dataTypeValidatorConverter; @@ -101,7 +98,7 @@ public class DataTypeValidatorConverter { String convertedValue = converter.convert(value, null, allDataTypes); JsonElement element = null; try { - element = jsonParser.parse(convertedValue); + element = JsonParser.parseString(convertedValue); } catch (JsonSyntaxException e) { log.debug("Failed to parse value {} of property {} {}", convertedValue, dataTypeDefinition.getName(), e); return falseResult; @@ -174,7 +171,7 @@ public class DataTypeValidatorConverter { element = new JsonPrimitive(""); } else { try { - element = jsonParser.parse(convertedValue); + element = JsonParser.parseString(convertedValue); } catch (JsonSyntaxException e) { log.debug("Failed to parse value {} of type {}", convertedValue, propertyType, e); return falseResult; @@ -237,9 +234,9 @@ public class DataTypeValidatorConverter { if (value == null || value.isEmpty()) { return true; } - JsonElement jsonElement = null; + JsonElement jsonElement; try { - jsonElement = jsonParser.parse(value); + jsonElement = JsonParser.parseString(value); } catch (JsonSyntaxException e) { log.debug("Failed to parse the value {} from type {}", value, dataTypeDefinition, e); return false; diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/MapValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/MapValidator.java index 2635647467..d3424b8612 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/MapValidator.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/MapValidator.java @@ -52,9 +52,8 @@ Keys always need " " around them. public class MapValidator implements PropertyTypeValidator { private static final Logger log = Logger.getLogger(MapValidator.class.getName()); - private static MapValidator mapValidator = new MapValidator(); - private static DataTypeValidatorConverter dataTypeValidatorConverter = DataTypeValidatorConverter.getInstance(); - private static JsonParser jsonParser = new JsonParser(); + private static final MapValidator mapValidator = new MapValidator(); + private static final DataTypeValidatorConverter dataTypeValidatorConverter = DataTypeValidatorConverter.getInstance(); public static MapValidator getInstance() { return mapValidator; @@ -99,7 +98,7 @@ public class MapValidator implements PropertyTypeValidator { return isValid; } try { - JsonElement jsonObject = jsonParser.parse(value); + JsonElement jsonObject = JsonParser.parseString(value); if (!jsonObject.isJsonObject()) { return false; } @@ -134,7 +133,7 @@ public class MapValidator implements PropertyTypeValidator { return false; } try { - JsonElement jsonObject = jsonParser.parse(value); + JsonElement jsonObject = JsonParser.parseString(value); JsonObject asJsonObject = jsonObject.getAsJsonObject(); Set<Entry<String, JsonElement>> entrySet = asJsonObject.entrySet(); for (Entry<String, JsonElement> entry : entrySet) { diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/validation/FilterConstraintValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/validation/FilterConstraintValidator.java new file mode 100644 index 0000000000..634b1efe85 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/validation/FilterConstraintValidator.java @@ -0,0 +1,39 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.openecomp.sdc.be.model.validation; + +import org.openecomp.sdc.be.model.dto.FilterConstraintDto; + +/** + * Handle validation for a node/substitution filter constraint + */ +public interface FilterConstraintValidator { + + /** + * Validates a node/substitution filter constraint + * + * @param filterConstraint the filter constraint + * @throws RuntimeException when the filter constraint is invalid + */ + void validate(final FilterConstraintDto filterConstraint); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/ui/mapper/FilterConstraintMapper.java b/catalog-model/src/main/java/org/openecomp/sdc/be/ui/mapper/FilterConstraintMapper.java new file mode 100644 index 0000000000..da486e47f5 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/ui/mapper/FilterConstraintMapper.java @@ -0,0 +1,124 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.openecomp.sdc.be.ui.mapper; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; +import java.util.Map; +import java.util.Optional; +import org.apache.commons.lang3.StringUtils; +import org.openecomp.sdc.be.datatypes.elements.PropertyFilterConstraintDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ToscaFunction; +import org.openecomp.sdc.be.datatypes.elements.ToscaFunctionType; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; +import org.openecomp.sdc.be.datatypes.enums.FilterValueType; +import org.openecomp.sdc.be.datatypes.enums.PropertyFilterTargetType; +import org.openecomp.sdc.be.model.dto.FilterConstraintDto; +import org.openecomp.sdc.be.ui.model.UIConstraint; + +public class FilterConstraintMapper { + + public FilterConstraintDto mapFrom(final UIConstraint uiConstraint) { + final var filterConstraint = new FilterConstraintDto(); + ConstraintType.findByType(uiConstraint.getConstraintOperator()).ifPresent(filterConstraint::setOperator); + filterConstraint.setCapabilityName(uiConstraint.getCapabilityName()); + filterConstraint.setPropertyName(uiConstraint.getServicePropertyName()); + filterConstraint.setTargetType(StringUtils.isEmpty(uiConstraint.getCapabilityName()) ? PropertyFilterTargetType.PROPERTY : PropertyFilterTargetType.CAPABILITY); + FilterValueType.findByName(uiConstraint.getSourceType()).ifPresent(filterConstraint::setValueType); + filterConstraint.setValue(parseValueFromUiConstraint(uiConstraint.getValue())); + return filterConstraint; + } + + public FilterConstraintDto mapFrom(final PropertyFilterConstraintDataDefinition propertyFilterConstraint) { + var filterConstraintDto = new FilterConstraintDto(); + filterConstraintDto.setTargetType(propertyFilterConstraint.getTargetType()); + filterConstraintDto.setPropertyName(propertyFilterConstraint.getPropertyName()); + filterConstraintDto.setCapabilityName(propertyFilterConstraint.getCapabilityName()); + filterConstraintDto.setOperator(propertyFilterConstraint.getOperator()); + filterConstraintDto.setValueType(propertyFilterConstraint.getValueType()); + filterConstraintDto.setValue(propertyFilterConstraint.getValue()); + return filterConstraintDto; + } + + public PropertyFilterConstraintDataDefinition mapTo(final FilterConstraintDto filterConstraintDto) { + var propertyFilterConstraint = new PropertyFilterConstraintDataDefinition(); + propertyFilterConstraint.setTargetType(filterConstraintDto.getTargetType()); + propertyFilterConstraint.setPropertyName(filterConstraintDto.getPropertyName()); + propertyFilterConstraint.setCapabilityName(filterConstraintDto.getCapabilityName()); + propertyFilterConstraint.setOperator(filterConstraintDto.getOperator()); + propertyFilterConstraint.setValueType(filterConstraintDto.getValueType()); + propertyFilterConstraint.setValue(filterConstraintDto.getValue()); + return propertyFilterConstraint; + } + + public UIConstraint mapToUiConstraint(final FilterConstraintDto filterConstraintDto) { + final var uiConstraint = new UIConstraint(); + uiConstraint.setConstraintOperator(filterConstraintDto.getOperator().getType()); + uiConstraint.setValue(filterConstraintDto.getValue()); + uiConstraint.setCapabilityName(filterConstraintDto.getCapabilityName()); + uiConstraint.setServicePropertyName(filterConstraintDto.getPropertyName()); + uiConstraint.setSourceType(filterConstraintDto.getValueType().getName()); + return uiConstraint; + } + + private Object parseValueFromUiConstraint(final Object value) { + if (!(value instanceof Map || value instanceof String)) { + return value; + } + final Map<?, ?> valueAsMap; + if (value instanceof String) { + try { + valueAsMap = new Gson().fromJson((String) value, Map.class); + } catch (final Exception ignored) { + return value; + } + } else { + valueAsMap = (Map<?, ?>) value; + } + + final Optional<ToscaFunction> toscaFunction = parseValueToToscaFunction(valueAsMap); + if (toscaFunction.isPresent()) { + return toscaFunction.get(); + } + + return valueAsMap; + } + + public Optional<ToscaFunction> parseValueToToscaFunction(final Object value) { + if (value instanceof ToscaFunction) { + return Optional.of((ToscaFunction) value); + } + return readToscaFunctionType(value).map(toscaFunctionType -> new ObjectMapper().convertValue(value, ToscaFunction.class)); + } + + private Optional<ToscaFunctionType> readToscaFunctionType(final Object toscaFunction) { + if (!(toscaFunction instanceof Map)) { + return Optional.empty(); + } + final Object type = ((Map<?, ?>) toscaFunction).get("type"); + if (type instanceof String) { + return ToscaFunctionType.findType((String) type); + } + return Optional.empty(); + } + +} diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/dto/FilterConstraintDtoTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/dto/FilterConstraintDtoTest.java new file mode 100644 index 0000000000..e67fdc0f33 --- /dev/null +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/dto/FilterConstraintDtoTest.java @@ -0,0 +1,101 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.openecomp.sdc.be.model.dto; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; +import java.util.Map; +import java.util.Optional; +import org.junit.jupiter.api.Test; +import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.PropertySource; +import org.openecomp.sdc.be.datatypes.tosca.ToscaGetFunctionType; + +class FilterConstraintDtoTest { + + @Test + void isCapabilityPropertyFilter() { + var filterConstraintDto = new FilterConstraintDto(); + assertFalse(filterConstraintDto.isCapabilityPropertyFilter()); + filterConstraintDto.setCapabilityName("aCapability"); + assertTrue(filterConstraintDto.isCapabilityPropertyFilter()); + } + + @Test + void readGetFunctionWithToscaGetFunctionInstanceAsValue() { + final var filterConstraintDto = new FilterConstraintDto(); + final var toscaGetFunction = new ToscaGetFunctionDataDefinition(); + toscaGetFunction.setFunctionType(ToscaGetFunctionType.GET_PROPERTY); + filterConstraintDto.setValue(toscaGetFunction); + final Optional<ToscaGetFunctionDataDefinition> readGetFunctionOpt = filterConstraintDto.getAsToscaGetFunction(); + assertTrue(readGetFunctionOpt.isPresent()); + assertEquals(toscaGetFunction, readGetFunctionOpt.get()); + } + + @Test + void readGetFunctionWithInvalidGetFunctionValue() { + final var filterConstraintDto = new FilterConstraintDto(); + filterConstraintDto.setValue("not a ToscaGetFunctionDataDefinition"); + final Optional<ToscaGetFunctionDataDefinition> readGetFunctionOpt = filterConstraintDto.getAsToscaGetFunction(); + assertTrue(readGetFunctionOpt.isEmpty()); + } + + @Test + void readGetFunctionWithGetFunctionValueAsMap() { + //given + final List<String> propertyPathFromSource = List.of("input", "path"); + final String propertyUniqueId = "propertyUniqueIdValue"; + final String propertyName = "propertyNameValue"; + final String sourceUniqueId = "sourceUniqueIdValue"; + final String sourceName = "sourceNameValue"; + final Map<String, Object> toscaGetFunctionAsMap = Map.of( + "propertyUniqueId", propertyUniqueId, + "propertyName", propertyName, + "propertySource", PropertySource.SELF.getName(), + "sourceUniqueId", sourceUniqueId, + "sourceName", sourceName, + "functionType", ToscaGetFunctionType.GET_INPUT.getFunctionName(), + "propertyPathFromSource", propertyPathFromSource + ); + + final var filterConstraintDto = new FilterConstraintDto(); + filterConstraintDto.setValue(toscaGetFunctionAsMap); + //when + final Optional<ToscaGetFunctionDataDefinition> readGetFunctionOpt = filterConstraintDto.getAsToscaGetFunction(); + //then + assertTrue(readGetFunctionOpt.isPresent()); + final ToscaGetFunctionDataDefinition toscaGetFunctionDataDefinition = readGetFunctionOpt.get(); + assertEquals(toscaGetFunctionDataDefinition.getPropertyUniqueId(), propertyUniqueId); + assertEquals(toscaGetFunctionDataDefinition.getPropertyName(), propertyName); + assertEquals(toscaGetFunctionDataDefinition.getPropertySource(), PropertySource.SELF); + assertEquals(toscaGetFunctionDataDefinition.getSourceUniqueId(), sourceUniqueId); + assertEquals(toscaGetFunctionDataDefinition.getSourceName(), sourceName); + assertEquals(toscaGetFunctionDataDefinition.getFunctionType(), ToscaGetFunctionType.GET_INPUT); + assertEquals(toscaGetFunctionDataDefinition.getPropertyPathFromSource().size(), 2); + assertEquals(toscaGetFunctionDataDefinition.getPropertyPathFromSource().get(0), propertyPathFromSource.get(0)); + assertEquals(toscaGetFunctionDataDefinition.getPropertyPathFromSource().get(1), propertyPathFromSource.get(1)); + } + +}
\ No newline at end of file diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeFilterOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeFilterOperationTest.java index 0cbba25e04..bd16016ad9 100644 --- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeFilterOperationTest.java +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeFilterOperationTest.java @@ -21,6 +21,8 @@ package org.openecomp.sdc.be.model.jsonjanusgraph.operations; import fj.data.Either; +import java.util.List; +import java.util.Map; import org.janusgraph.core.JanusGraphVertex; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -33,7 +35,11 @@ import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum; import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum; import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; -import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyFilterConstraintDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyFilterDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; +import org.openecomp.sdc.be.datatypes.enums.FilterValueType; +import org.openecomp.sdc.be.datatypes.enums.PropertyFilterTargetType; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import java.util.Arrays; @@ -66,19 +72,30 @@ class NodeFilterOperationTest { nodeFilterDataDefinition.setName("new node filter name"); String prop1 = "property1"; String prop2 = "property2"; - RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition = new RequirementNodeFilterPropertyDataDefinition(); - requirementNodeFilterPropertyDataDefinition.setName("Name1"); - requirementNodeFilterPropertyDataDefinition - .setConstraints(Arrays.asList("mem_size:\n" + " equal: { get_property : [" + prop1 + ", size]}\n")); - RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition2 = new RequirementNodeFilterPropertyDataDefinition(); - requirementNodeFilterPropertyDataDefinition2.setName("Name2"); - requirementNodeFilterPropertyDataDefinition2 - .setConstraints(Arrays.asList("mem_size:\n {equal: { get_property : [SELF, " + prop2 + "]}}\n")); + final var propertyFilterDataDefinition = new PropertyFilterDataDefinition(); + propertyFilterDataDefinition.setName("Name1"); + final var propertyFilterConstraint1 = new PropertyFilterConstraintDataDefinition(); + propertyFilterConstraint1.setPropertyName("mem_size"); + propertyFilterConstraint1.setOperator(ConstraintType.EQUAL); + propertyFilterConstraint1.setValue(Map.of("get_property", List.of(prop1, "size"))); + propertyFilterConstraint1.setValueType(FilterValueType.GET_PROPERTY); + propertyFilterConstraint1.setTargetType(PropertyFilterTargetType.PROPERTY); + propertyFilterDataDefinition.setConstraints(List.of(propertyFilterConstraint1)); - ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> listDataDefinition = + final var propertyFilterDataDefinition2 = new PropertyFilterDataDefinition(); + propertyFilterDataDefinition2.setName("Name2"); + final var propertyFilterConstraint2 = new PropertyFilterConstraintDataDefinition(); + propertyFilterConstraint2.setPropertyName("mem_size"); + propertyFilterConstraint2.setOperator(ConstraintType.EQUAL); + propertyFilterConstraint2.setValue(Map.of("get_property", List.of("SELF", prop2))); + propertyFilterConstraint2.setValueType(FilterValueType.GET_PROPERTY); + propertyFilterConstraint2.setTargetType(PropertyFilterTargetType.PROPERTY); + propertyFilterDataDefinition2.setConstraints(List.of(propertyFilterConstraint2)); + + ListDataDefinition<PropertyFilterDataDefinition> listDataDefinition = new ListDataDefinition<>(Arrays.asList( - requirementNodeFilterPropertyDataDefinition, - requirementNodeFilterPropertyDataDefinition2)); + propertyFilterDataDefinition, + propertyFilterDataDefinition2)); nodeFilterDataDefinition.setProperties(listDataDefinition); String componentId = "componentId"; diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractPropertyConstraintTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractPropertyConstraintTest.java index 6fd578856d..621c95109e 100644 --- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractPropertyConstraintTest.java +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractPropertyConstraintTest.java @@ -24,6 +24,7 @@ package org.openecomp.sdc.be.model.tosca.constraints; import static org.junit.Assert.assertEquals; import org.junit.Test; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; import org.openecomp.sdc.be.model.PropertyConstraint; import org.openecomp.sdc.be.model.tosca.ToscaType; import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintFunctionalException; diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractStringPropertyConstraintTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractStringPropertyConstraintTest.java index 376bac8ca9..595437fab6 100644 --- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractStringPropertyConstraintTest.java +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractStringPropertyConstraintTest.java @@ -24,6 +24,7 @@ package org.openecomp.sdc.be.model.tosca.constraints; import static org.junit.Assert.assertEquals; import org.junit.Test; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; import org.openecomp.sdc.be.model.PropertyConstraint; import org.openecomp.sdc.be.model.tosca.ToscaType; import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintFunctionalException; diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/ui/mapper/FilterConstraintMapperTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/ui/mapper/FilterConstraintMapperTest.java new file mode 100644 index 0000000000..1ea72937b9 --- /dev/null +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/ui/mapper/FilterConstraintMapperTest.java @@ -0,0 +1,142 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.openecomp.sdc.be.ui.mapper; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Map; +import java.util.Optional; +import org.junit.jupiter.api.Test; +import org.openecomp.sdc.be.datatypes.elements.PropertyFilterConstraintDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ToscaConcatFunction; +import org.openecomp.sdc.be.datatypes.elements.ToscaFunction; +import org.openecomp.sdc.be.datatypes.elements.ToscaFunctionType; +import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; +import org.openecomp.sdc.be.datatypes.enums.FilterValueType; +import org.openecomp.sdc.be.datatypes.enums.PropertyFilterTargetType; +import org.openecomp.sdc.be.model.dto.FilterConstraintDto; +import org.openecomp.sdc.be.ui.model.UIConstraint; + +class FilterConstraintMapperTest { + + private final FilterConstraintMapper filterConstraintMapper = new FilterConstraintMapper(); + + @Test + void mapFromUIConstraintTest() { + //given + final var uIConstraint = new UIConstraint(); + final FilterValueType filterValueType = FilterValueType.STATIC; + uIConstraint.setSourceType(filterValueType.getName()); + final String capabilityName = "aCapability"; + uIConstraint.setCapabilityName(capabilityName); + final String propertyName = "aProperty"; + uIConstraint.setServicePropertyName(propertyName); + final ConstraintType operator = ConstraintType.GREATER_OR_EQUAL; + uIConstraint.setConstraintOperator(operator.getType()); + final ToscaFunctionType expectedValueToscaFunctionType = ToscaFunctionType.GET_INPUT; + uIConstraint.setValue(Map.of("type", expectedValueToscaFunctionType.getName())); + //when + final FilterConstraintDto filterConstraintDto = filterConstraintMapper.mapFrom(uIConstraint); + //then + assertEquals(PropertyFilterTargetType.CAPABILITY, filterConstraintDto.getTargetType()); + assertEquals(propertyName, filterConstraintDto.getPropertyName()); + assertEquals(capabilityName, filterConstraintDto.getCapabilityName()); + assertEquals(filterValueType, filterConstraintDto.getValueType()); + assertTrue(filterConstraintDto.getValue() instanceof ToscaGetFunctionDataDefinition); + assertEquals(expectedValueToscaFunctionType, ((ToscaGetFunctionDataDefinition) filterConstraintDto.getValue()).getType()); + assertEquals(operator, filterConstraintDto.getOperator()); + //when + final UIConstraint actualUiConstraint = filterConstraintMapper.mapToUiConstraint(filterConstraintDto); + //then + assertEquals(propertyName, actualUiConstraint.getServicePropertyName()); + assertEquals(capabilityName, actualUiConstraint.getCapabilityName()); + assertEquals(filterValueType.getName(), actualUiConstraint.getSourceType()); + assertTrue(actualUiConstraint.getValue() instanceof ToscaGetFunctionDataDefinition); + assertEquals(expectedValueToscaFunctionType, ((ToscaGetFunctionDataDefinition) actualUiConstraint.getValue()).getType()); + assertEquals(operator.getType(), actualUiConstraint.getConstraintOperator()); + assertNull(actualUiConstraint.getSourceName()); + } + + @Test + void mapFromPropertyFilterConstraintDataDefinitionTest() { + //given + final var propertyFilterConstraintDataDefinition = new PropertyFilterConstraintDataDefinition(); + propertyFilterConstraintDataDefinition.setTargetType(PropertyFilterTargetType.CAPABILITY); + final String capabilityName = "aCapability"; + propertyFilterConstraintDataDefinition.setCapabilityName(capabilityName); + final String propertyName = "aProperty"; + propertyFilterConstraintDataDefinition.setPropertyName(propertyName); + final ConstraintType operator = ConstraintType.GREATER_OR_EQUAL; + propertyFilterConstraintDataDefinition.setOperator(operator); + final FilterValueType filterValueType = FilterValueType.STATIC; + propertyFilterConstraintDataDefinition.setValueType(filterValueType); + final String value = "aStaticValue"; + propertyFilterConstraintDataDefinition.setValue(value); + //when + final FilterConstraintDto filterConstraintDto = filterConstraintMapper.mapFrom(propertyFilterConstraintDataDefinition); + //then + assertEquals(PropertyFilterTargetType.CAPABILITY, filterConstraintDto.getTargetType()); + assertEquals(propertyName, filterConstraintDto.getPropertyName()); + assertEquals(capabilityName, filterConstraintDto.getCapabilityName()); + assertEquals(filterValueType, filterConstraintDto.getValueType()); + assertEquals(value, filterConstraintDto.getValue()); + assertEquals(operator, filterConstraintDto.getOperator()); + //when + final PropertyFilterConstraintDataDefinition actualPropertyFilterConstraint = + filterConstraintMapper.mapTo(filterConstraintDto); + assertEquals(PropertyFilterTargetType.CAPABILITY, actualPropertyFilterConstraint.getTargetType()); + assertEquals(propertyName, actualPropertyFilterConstraint.getPropertyName()); + assertEquals(capabilityName, actualPropertyFilterConstraint.getCapabilityName()); + assertEquals(filterValueType, actualPropertyFilterConstraint.getValueType()); + assertEquals(value, actualPropertyFilterConstraint.getValue()); + assertEquals(operator, actualPropertyFilterConstraint.getOperator()); + } + + @Test + void parseValueToToscaFunctionTest() { + //given + final ToscaConcatFunction expectedValue = new ToscaConcatFunction(); + //when + Optional<ToscaFunction> actualToscaFunction = filterConstraintMapper.parseValueToToscaFunction(expectedValue); + //then + assertTrue(actualToscaFunction.isPresent()); + assertEquals(expectedValue, actualToscaFunction.get()); + //when + actualToscaFunction = filterConstraintMapper.parseValueToToscaFunction("not a tosca function"); + //then + assertTrue(actualToscaFunction.isEmpty()); + //given + final Map<String, Object> value = Map.of("type", ToscaFunctionType.CONCAT.getName()); + //when + actualToscaFunction = filterConstraintMapper.parseValueToToscaFunction(value); + //then + assertTrue(actualToscaFunction.isPresent()); + assertTrue(actualToscaFunction.get() instanceof ToscaConcatFunction); + //when + actualToscaFunction = filterConstraintMapper.parseValueToToscaFunction(Map.of("type", 1)); + //then + assertTrue(actualToscaFunction.isEmpty()); + } +}
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/components/logic/capabilities-constraint/capabilities-constraint.component.ts b/catalog-ui/src/app/models/capability-filter-constraint.ts index 853106c806..64d9913a54 100644 --- a/catalog-ui/src/app/ng2/components/logic/capabilities-constraint/capabilities-constraint.component.ts +++ b/catalog-ui/src/app/models/capability-filter-constraint.ts @@ -19,7 +19,7 @@ * ============LICENSE_END========================================================= */ -export class CapabilitiesConstraintObject { +export class CapabilityFilterConstraint { capabilityName: string; servicePropertyName: string; constraintOperator: string; @@ -39,7 +39,7 @@ export class CapabilitiesConstraintObject { } } -export class CapabilitiesConstraintObjectUI extends CapabilitiesConstraintObject{ +export class CapabilityFilterConstraintUI extends CapabilityFilterConstraint { isValidValue: boolean; constructor(input?: any) { diff --git a/catalog-ui/src/app/models/filter-constraint.ts b/catalog-ui/src/app/models/filter-constraint.ts new file mode 100644 index 0000000000..a118c97d7b --- /dev/null +++ b/catalog-ui/src/app/models/filter-constraint.ts @@ -0,0 +1,17 @@ +export class FilterConstraint { + servicePropertyName: string; + constraintOperator: string; + sourceType: string; + sourceName: string; + value: any; + + constructor(input?: any) { + if (input) { + this.servicePropertyName = input.servicePropertyName; + this.constraintOperator = input.constraintOperator; + this.sourceType = input.sourceType; + this.sourceName = input.sourceName; + this.value = input.value; + } + } +} diff --git a/catalog-ui/src/app/models/properties-inputs/property-fe-model.ts b/catalog-ui/src/app/models/properties-inputs/property-fe-model.ts index eb18c4e4f9..49baefd4e0 100644 --- a/catalog-ui/src/app/models/properties-inputs/property-fe-model.ts +++ b/catalog-ui/src/app/models/properties-inputs/property-fe-model.ts @@ -46,6 +46,9 @@ export class PropertyFEModel extends PropertyBEModel { constructor(property: PropertyBEModel){ super(property); + if (!property) { + return; + } this.value = property.value ? property.value : property.defaultValue;//In FE if a property doesn't have value - display the default value this.isSimpleType = PROPERTY_DATA.SIMPLE_TYPES.indexOf(this.type) > -1; this.setNonDeclared(); @@ -290,7 +293,7 @@ export class PropertyFEModel extends PropertyBEModel { propertyType !== PROPERTY_TYPES.TIMESTAMP && propertyType !== PROPERTY_TYPES.JSON && PROPERTY_DATA.SCALAR_TYPES.indexOf(<string>propertyType) == -1) { - return JSON.parse(value); // the value object contains the real value ans not the value as string + return JSON.parse(valueObj); // the value object contains the real value ans not the value as string } return valueObj; } diff --git a/catalog-ui/src/app/models/tosca-concat-function.ts b/catalog-ui/src/app/models/tosca-concat-function.ts index 9656d8ddb9..74fe7f6793 100644 --- a/catalog-ui/src/app/models/tosca-concat-function.ts +++ b/catalog-ui/src/app/models/tosca-concat-function.ts @@ -22,6 +22,9 @@ import {ToscaFunction} from "./tosca-function"; import {ToscaFunctionType} from "./tosca-function-type.enum"; import {ToscaFunctionParameter} from "./tosca-function-parameter"; +import {ToscaGetFunction} from "./tosca-get-function"; +import {YamlFunction} from "./yaml-function"; +import {ToscaStringParameter} from "./tosca-string-parameter"; export class ToscaConcatFunction implements ToscaFunction, ToscaFunctionParameter { type = ToscaFunctionType.CONCAT; @@ -33,6 +36,39 @@ export class ToscaConcatFunction implements ToscaFunction, ToscaFunctionParamete return; } this.value = toscaConcatFunction.value; + if (toscaConcatFunction.parameters) { + toscaConcatFunction.parameters.forEach(parameter => { + switch (parameter.type) { + case ToscaFunctionType.GET_INPUT: + case ToscaFunctionType.GET_ATTRIBUTE: + case ToscaFunctionType.GET_PROPERTY: + this.parameters.push(new ToscaGetFunction(<ToscaGetFunction>parameter)); + break; + case ToscaFunctionType.CONCAT: + this.parameters.push(new ToscaConcatFunction(<ToscaConcatFunction>parameter)); + break; + case ToscaFunctionType.YAML: + this.parameters.push(new YamlFunction(<YamlFunction>parameter)); + break; + case ToscaFunctionType.STRING: + this.parameters.push(new ToscaStringParameter(<ToscaStringParameter>parameter)); + break; + default: + console.error(`Unsupported parameter type "${parameter.type}"`); + this.parameters.push(parameter); + } + }); + } + } + + public buildValueString(): string { + return JSON.stringify(this.buildValueObject()); + } + + public buildValueObject(): Object { + return { + [this.type.toLowerCase()]: this.parameters.map(parameter => parameter.buildValueObject()) + } } }
\ No newline at end of file diff --git a/catalog-ui/src/app/models/tosca-function-parameter.ts b/catalog-ui/src/app/models/tosca-function-parameter.ts index 84c4f0b014..a667543f74 100644 --- a/catalog-ui/src/app/models/tosca-function-parameter.ts +++ b/catalog-ui/src/app/models/tosca-function-parameter.ts @@ -24,4 +24,5 @@ import {ToscaFunctionType} from "./tosca-function-type.enum"; export interface ToscaFunctionParameter { type: ToscaFunctionType; value: any; + buildValueObject(): Object; }
\ No newline at end of file diff --git a/catalog-ui/src/app/models/tosca-function.ts b/catalog-ui/src/app/models/tosca-function.ts index ebb024ee7c..8ea2a829a8 100644 --- a/catalog-ui/src/app/models/tosca-function.ts +++ b/catalog-ui/src/app/models/tosca-function.ts @@ -24,4 +24,6 @@ import {ToscaFunctionType} from "./tosca-function-type.enum"; export interface ToscaFunction { type: ToscaFunctionType; value: any; + buildValueString(): string + buildValueObject(): Object }
\ No newline at end of file diff --git a/catalog-ui/src/app/models/tosca-get-function.ts b/catalog-ui/src/app/models/tosca-get-function.ts index 2386338c98..7e6c5ad739 100644 --- a/catalog-ui/src/app/models/tosca-get-function.ts +++ b/catalog-ui/src/app/models/tosca-get-function.ts @@ -23,8 +23,9 @@ import {PropertySource} from "./property-source"; import {ToscaGetFunctionType} from "./tosca-get-function-type"; import {ToscaFunction} from "./tosca-function"; import {ToscaFunctionType} from "./tosca-function-type.enum"; +import {ToscaFunctionParameter} from "./tosca-function-parameter"; -export class ToscaGetFunction implements ToscaFunction { +export class ToscaGetFunction implements ToscaFunction, ToscaFunctionParameter { type: ToscaFunctionType; propertyUniqueId: string; propertyName: string; @@ -39,6 +40,8 @@ export class ToscaGetFunction implements ToscaFunction { if (!toscaGetFunction) { return; } + this.type = toscaGetFunction.type; + this.value = toscaGetFunction.value; this.propertyUniqueId = toscaGetFunction.propertyUniqueId; this.propertyName = toscaGetFunction.propertyName; this.propertySource = toscaGetFunction.propertySource; @@ -50,4 +53,38 @@ export class ToscaGetFunction implements ToscaFunction { } } + public buildValueString(): string { + return JSON.stringify(this.buildValueObject()); + } + + public buildValueObject(): Object { + if (this.functionType == ToscaGetFunctionType.GET_PROPERTY || this.functionType == ToscaGetFunctionType.GET_ATTRIBUTE) { + return this.buildFunctionValueWithPropertySource(); + } + if (this.functionType == ToscaGetFunctionType.GET_INPUT) { + return this.buildGetInputFunctionValue(); + } + return undefined; + } + + private buildGetInputFunctionValue(): Object { + if (this.propertyPathFromSource.length === 1) { + return {[this.functionType.toLowerCase()]: this.propertyPathFromSource[0]}; + } + return {[this.functionType.toLowerCase()]: this.propertyPathFromSource}; + } + + private buildFunctionValueWithPropertySource(): Object { + if (this.propertySource == PropertySource.SELF) { + return { + [this.functionType.toLowerCase()]: [PropertySource.SELF, ...this.propertyPathFromSource] + }; + } + if (this.propertySource == PropertySource.INSTANCE) { + return { + [this.functionType.toLowerCase()]: [this.sourceName, ...this.propertyPathFromSource] + }; + } + } + }
\ No newline at end of file diff --git a/catalog-ui/src/app/models/tosca-string-parameter.ts b/catalog-ui/src/app/models/tosca-string-parameter.ts index 0f7423582c..64f6676624 100644 --- a/catalog-ui/src/app/models/tosca-string-parameter.ts +++ b/catalog-ui/src/app/models/tosca-string-parameter.ts @@ -25,4 +25,15 @@ import {ToscaFunctionType} from "./tosca-function-type.enum"; export class ToscaStringParameter implements ToscaFunctionParameter { type: ToscaFunctionType = ToscaFunctionType.STRING; value: string; + + + constructor(toscaStringParameter?: ToscaStringParameter) { + if (toscaStringParameter) { + this.value = toscaStringParameter.value; + } + } + + buildValueObject(): Object { + return this.value; + } }
\ No newline at end of file diff --git a/catalog-ui/src/app/models/ui-models/constraint-object-ui.ts b/catalog-ui/src/app/models/ui-models/constraint-object-ui.ts new file mode 100644 index 0000000000..48cf2abdc6 --- /dev/null +++ b/catalog-ui/src/app/models/ui-models/constraint-object-ui.ts @@ -0,0 +1,26 @@ +import {FilterConstraint} from "../filter-constraint"; + +export class ConstraintObjectUI extends FilterConstraint { + isValidValue: boolean; + + constructor(input?: any) { + super(input); + if (input) { + this.isValidValue = input.isValidValue ? input.isValidValue : input.value !== ''; + } + } + + public updateValidity(isValidValue: boolean) { + this.isValidValue = isValidValue; + } + + public isValidRule() { + const isValidValue = this.isStatic() ? this.isValidValue : true; + return this.servicePropertyName != null && this.servicePropertyName !== '' + && this.value != null && this.value !== '' && isValidValue; + } + + private isStatic() { + return this.sourceName === 'static'; + } +}
\ No newline at end of file diff --git a/catalog-ui/src/app/models/yaml-function.ts b/catalog-ui/src/app/models/yaml-function.ts index e80d783424..e992d6bf47 100644 --- a/catalog-ui/src/app/models/yaml-function.ts +++ b/catalog-ui/src/app/models/yaml-function.ts @@ -22,6 +22,7 @@ import {ToscaFunction} from "./tosca-function"; import {ToscaFunctionType} from "./tosca-function-type.enum"; import {ToscaFunctionParameter} from "./tosca-function-parameter"; +import * as jsYaml from 'js-yaml'; export class YamlFunction implements ToscaFunction, ToscaFunctionParameter { type = ToscaFunctionType.YAML; @@ -34,4 +35,12 @@ export class YamlFunction implements ToscaFunction, ToscaFunctionParameter { this.value = yamlFunction.value; } + public buildValueObject(): Object { + return jsYaml.load(this.value); + } + + public buildValueString(): string { + return this.value; + } + }
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.html b/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.html index 213210cc7d..f0430ff1cd 100644 --- a/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.html +++ b/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.html @@ -23,11 +23,8 @@ <div class="filter-details" [ngClass]="{'readonly': readonly}"> <div class="filter-desc" (click)="!readonly && onSelectNodeFilterCapability(capabilities, i)" tooltips - tooltip="{{capability.capabilityName + ' : ' + - capability.servicePropertyName + ' ' + getSymbol(capability.constraintOperator) + ' ' - + (capability.value | json)}}"> - {{capability.capabilityName + ' : ' + capability.servicePropertyName + ' ' + getSymbol(capability.constraintOperator) - + ' ' + (capability.value | json)}} + tooltip="{{constraintCapabilityLabels[i]}}"> + {{constraintCapabilityLabels[i]}} </div> <span *ngIf="!readonly" class="sprite-new delete-btn delete-icon" (click)="openDeleteModal(capabilities, i)" @@ -56,10 +53,8 @@ <div class="filter-details" [ngClass]="{'readonly': readonly}"> <div class="filter-desc" (click)="!readonly && onSelectNodeFilter(properties, i)" tooltips - tooltip="{{property.servicePropertyName + ' ' + getSymbol(property.constraintOperator) + ' ' - + (property.value | json)}}"> - {{property.servicePropertyName + ' ' + getSymbol(property.constraintOperator) - + ' ' + (property.value | json)}} + tooltip="{{constraintPropertyLabels[i]}}"> + {{constraintPropertyLabels[i]}} </div> <span *ngIf="!readonly" class="sprite-new delete-btn delete-icon" (click)="openDeleteModal(properties, i)" diff --git a/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.ts b/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.ts index 54f9e1f091..04c7a3a03b 100644 --- a/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.ts +++ b/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.ts @@ -13,77 +13,31 @@ * or implied. See the License for the specific language governing * permissions and limitations under the License. */ -import {Component, ComponentRef, EventEmitter, Input, Output} from '@angular/core'; +import {Component, ComponentRef, EventEmitter, Input, OnChanges, OnInit, Output} from '@angular/core'; +import {ButtonModel, ComponentInstance, InputBEModel, ModalModel, PropertyBEModel, PropertyModel,} from 'app/models'; +import {ModalComponent} from 'app/ng2/components/ui/modal/modal.component'; +import {ServiceDependenciesEditorComponent} from 'app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component'; +import {ModalService} from 'app/ng2/services/modal.service'; +import {ComponentGenericResponse} from 'app/ng2/services/responses/component-generic-response'; +import {TranslateService} from 'app/ng2/shared/translator/translate.service'; +import {ComponentMetadata} from '../../../../models/component-metadata'; +import {ServiceInstanceObject} from '../../../../models/service-instance-properties-and-interfaces'; +import {TopologyTemplateService} from '../../../services/component-services/topology-template.service'; import { - ButtonModel, - ComponentInstance, - InputBEModel, - ModalModel, - PropertyBEModel, - PropertyModel, -} from 'app/models'; -import { ModalComponent } from 'app/ng2/components/ui/modal/modal.component'; -import { ServiceDependenciesEditorComponent } from 'app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component'; -import { ModalService } from 'app/ng2/services/modal.service'; -import { ComponentGenericResponse } from 'app/ng2/services/responses/component-generic-response'; -import { TranslateService } from 'app/ng2/shared/translator/translate.service'; -import { ComponentMetadata } from '../../../../models/component-metadata'; -import { ServiceInstanceObject } from '../../../../models/service-instance-properties-and-interfaces'; -import { TopologyTemplateService } from '../../../services/component-services/topology-template.service'; -import {CapabilitiesFilterPropertiesEditorComponent} from "../../../pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component"; -import { CapabilitiesConstraintObjectUI} from "../capabilities-constraint/capabilities-constraint.component"; + CapabilitiesFilterPropertiesEditorComponent +} from "../../../pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component"; +import {CapabilityFilterConstraintUI} from "../../../../models/capability-filter-constraint"; import {ToscaFilterConstraintType} from "../../../../models/tosca-filter-constraint-type.enum"; import {CompositionService} from "../../../pages/composition/composition.service"; +import {FilterConstraint} from "app/models/filter-constraint"; +import {ConstraintObjectUI} from "../../../../models/ui-models/constraint-object-ui"; +import {FilterConstraintHelper, OPERATOR_TYPES} from "../../../../utils/filter-constraint-helper"; -export class ConstraintObject { - servicePropertyName: string; - constraintOperator: string; - sourceType: string; - sourceName: string; - value: string; - - constructor(input?: any) { - if (input) { - this.servicePropertyName = input.servicePropertyName; - this.constraintOperator = input.constraintOperator; - this.sourceType = input.sourceType; - this.sourceName = input.sourceName; - this.value = input.value; - } - } +export enum SourceType { + STATIC = 'static', + TOSCA_FUNCTION = 'tosca_function' } -// tslint:disable-next-line:max-classes-per-file -export class ConstraintObjectUI extends ConstraintObject{ - isValidValue: boolean; - - constructor(input?: any) { - super(input); - if (input) { - this.isValidValue = input.isValidValue ? input.isValidValue : input.value !== ''; - } - } - - public updateValidity(isValidValue: boolean) { - this.isValidValue = isValidValue; - } - - public isValidRule(isStatic) { - const isValidValue = isStatic ? this.isValidValue : true; - return this.servicePropertyName != null && this.servicePropertyName !== '' - && this.value != null && this.value !== '' && isValidValue; - } -} - -export const OPERATOR_TYPES = { - EQUAL: 'equal', - GREATER_THAN: 'greater_than', - LESS_THAN: 'less_than', - GREATER_OR_EQUAL: 'greater_or_equal', - LESS_OR_EQUAL: 'less_or_equal' -}; - -// tslint:disable-next-line:max-classes-per-file class I18nTexts { static removeDirectiveModalTitle: string; static removeDirectiveModalText: string; @@ -124,7 +78,6 @@ class I18nTexts { } } -// tslint:disable-next-line:max-classes-per-file @Component({ selector: 'service-dependencies', templateUrl: './service-dependencies.component.html', @@ -132,48 +85,49 @@ class I18nTexts { providers: [ModalService, TranslateService] }) -export class ServiceDependenciesComponent { +export class ServiceDependenciesComponent implements OnInit, OnChanges { modalInstance: ComponentRef<ModalComponent>; isDependent: boolean; isLoading: boolean; parentServiceInputs: InputBEModel[] = []; parentServiceProperties: PropertyBEModel[] = []; - constraintProperties: ConstraintObject[] = []; - constraintCapabilities: CapabilitiesConstraintObjectUI[] = []; + constraintProperties: FilterConstraint[] = []; + constraintPropertyLabels: string[] = []; + constraintCapabilities: CapabilityFilterConstraintUI[] = []; + constraintCapabilityLabels: string[] = []; operatorTypes: any[]; capabilities: string = ToscaFilterConstraintType.CAPABILITIES; properties: string = ToscaFilterConstraintType.PROPERTIES; - private componentInstancesConstraints: ConstraintObject[] = []; + private componentInstancesConstraints: FilterConstraint[] = []; isEditable: boolean; @Input() readonly: boolean; @Input() compositeService: ComponentMetadata; @Input() currentServiceInstance: ComponentInstance; @Input() selectedInstanceSiblings: ServiceInstanceObject[]; - @Input() selectedInstanceConstraints: ConstraintObject[] = []; + @Input() selectedInstanceConstraints: FilterConstraint[] = []; @Input() selectedInstanceProperties: PropertyBEModel[] = []; - @Output() updateRulesListEvent: EventEmitter<ConstraintObject[]> = new EventEmitter<ConstraintObject[]>(); - @Output() updateNodeFilterProperties: EventEmitter<ConstraintObject[]> = new EventEmitter<ConstraintObject[]>(); - @Output() updateNodeFilterCapabilities: EventEmitter<CapabilitiesConstraintObjectUI[]> = new EventEmitter<CapabilitiesConstraintObjectUI[]>(); + @Input() componentInstanceCapabilitiesMap: Map<string, PropertyModel[]>; + @Output() updateRulesListEvent: EventEmitter<FilterConstraint[]> = new EventEmitter<FilterConstraint[]>(); + @Output() updateNodeFilterProperties: EventEmitter<FilterConstraint[]> = new EventEmitter<FilterConstraint[]>(); + @Output() updateNodeFilterCapabilities: EventEmitter<CapabilityFilterConstraintUI[]> = new EventEmitter<CapabilityFilterConstraintUI[]>(); @Output() loadRulesListEvent:EventEmitter<any> = new EventEmitter(); @Output() dependencyStatus = new EventEmitter<boolean>(); - @Input() componentInstanceCapabilitiesMap: Map<string, PropertyModel[]>; - constructor(private topologyTemplateService: TopologyTemplateService, private modalServiceNg2: ModalService, private translateService: TranslateService, private compositionService: CompositionService) { } - ngOnInit() { + ngOnInit(): void { this.isLoading = false; this.operatorTypes = [ - {label: '>', value: OPERATOR_TYPES.GREATER_THAN}, - {label: '<', value: OPERATOR_TYPES.LESS_THAN}, - {label: '=', value: OPERATOR_TYPES.EQUAL}, - {label: '>=', value: OPERATOR_TYPES.GREATER_OR_EQUAL}, - {label: '<=', value: OPERATOR_TYPES.LESS_OR_EQUAL} + {label: FilterConstraintHelper.convertToSymbol(OPERATOR_TYPES.GREATER_THAN), value: OPERATOR_TYPES.GREATER_THAN}, + {label: FilterConstraintHelper.convertToSymbol(OPERATOR_TYPES.LESS_THAN), value: OPERATOR_TYPES.LESS_THAN}, + {label: FilterConstraintHelper.convertToSymbol(OPERATOR_TYPES.EQUAL), value: OPERATOR_TYPES.EQUAL}, + {label: FilterConstraintHelper.convertToSymbol(OPERATOR_TYPES.GREATER_OR_EQUAL), value: OPERATOR_TYPES.GREATER_OR_EQUAL}, + {label: FilterConstraintHelper.convertToSymbol(OPERATOR_TYPES.LESS_OR_EQUAL), value: OPERATOR_TYPES.LESS_OR_EQUAL} ]; this.topologyTemplateService.getComponentInputsWithProperties(this.compositeService.componentType, this.compositeService.uniqueId) .subscribe((result: ComponentGenericResponse) => { @@ -186,7 +140,7 @@ export class ServiceDependenciesComponent { }); } - ngOnChanges(changes) { + ngOnChanges(changes): void { if (changes.currentServiceInstance) { this.currentServiceInstance = changes.currentServiceInstance.currentValue; this.isDependent = this.currentServiceInstance.isDependent(); @@ -210,27 +164,19 @@ export class ServiceDependenciesComponent { return this.modalServiceNg2.createCustomModal(modalModel); } - public openUpdateDependencyModal = (): ComponentRef<ModalComponent> => { - const actionButton: ButtonModel = new ButtonModel(I18nTexts.modalApprove, 'blue', this.onUncheckDependency); - const cancelButton: ButtonModel = new ButtonModel(I18nTexts.modalCancel, 'grey', this.onCloseRemoveDependencyModal); - const modalModel: ModalModel = new ModalModel('sm', I18nTexts.updateDirectiveModalTitle, - I18nTexts.updateDirectiveModalText, [actionButton, cancelButton]); - return this.modalServiceNg2.createCustomModal(modalModel); - } - private loadNodeFilter = (): void => { this.topologyTemplateService.getServiceFilterConstraints(this.compositeService.componentType, this.compositeService.uniqueId).subscribe((response) => { if (response.nodeFilterforNode && response.nodeFilterforNode[this.currentServiceInstance.uniqueId]) { this.componentInstancesConstraints = response.nodeFilterforNode; - const nodeFilterPropertiesResponse: ConstraintObject[] = response.nodeFilterforNode[this.currentServiceInstance.uniqueId].properties; - this.constraintProperties = nodeFilterPropertiesResponse; - const nodeFilterCapabilitiesResponse: CapabilitiesConstraintObjectUI[] = response.nodeFilterforNode[this.currentServiceInstance.uniqueId].capabilities; - this.constraintCapabilities = nodeFilterCapabilitiesResponse; + this.constraintProperties = response.nodeFilterforNode[this.currentServiceInstance.uniqueId].properties; + this.buildConstraintPropertyLabels(); + this.constraintCapabilities = response.nodeFilterforNode[this.currentServiceInstance.uniqueId].capabilities; + this.buildCapabilityFilterConstraintLabels(); } }); } - onUncheckDependency = () => { + onUncheckDependency = (): void => { this.modalServiceNg2.closeCurrentModal(); this.isLoading = true; const isDepOrig = this.isDependent; @@ -239,36 +185,40 @@ export class ServiceDependenciesComponent { this.updateComponentInstance(isDepOrig, rulesListOrig); } - onCloseRemoveDependencyModal = () => { + onCloseRemoveDependencyModal = (): void => { this.isDependent = true; this.modalServiceNg2.closeCurrentModal(); } - onAddDirectives(directives: string[]) { + onAddDirectives(directives: string[]): void { this.isEditable = false; this.setDirectiveValue(directives); const rulesListOrig = this.componentInstancesConstraints; this.constraintProperties = []; + this.constraintPropertyLabels = []; this.constraintCapabilities = []; + this.constraintCapabilityLabels = []; this.loadNodeFilter(); this.updateComponentInstance(this.isDependent, rulesListOrig); } - private onRemoveDirective() { + private onRemoveDirective(): void { this.openRemoveDependencyModal().instance.open(); this.constraintProperties = []; + this.constraintPropertyLabels = []; this.constraintCapabilities = []; + this.constraintCapabilityLabels = []; } - private onEditDirectives() { + private onEditDirectives(): void { this.isEditable = true; } - private setDirectiveValue(newDirectiveValues: string[]) { + private setDirectiveValue(newDirectiveValues: string[]): void { this.currentServiceInstance.setDirectiveValue(newDirectiveValues); } - updateComponentInstance(isDependentOrigVal: boolean, rulesListOrig: ConstraintObject[]) { + updateComponentInstance(isDependentOrigVal: boolean, rulesListOrig: FilterConstraint[]): void { this.isLoading = true; this.topologyTemplateService.updateComponentInstance(this.compositeService.uniqueId, this.compositeService.componentType, @@ -288,11 +238,11 @@ export class ServiceDependenciesComponent { this.isDependent = isDependentOrigVal; this.componentInstancesConstraints = rulesListOrig; this.isLoading = false; - console.log('An error has occurred.'); + console.error('An error has occurred.', err); }); } - onAddNodeFilter = () => { + onAddNodeFilter = (): void => { if (!this.selectedInstanceProperties) { this.modalServiceNg2.openAlertModal(I18nTexts.validateNodePropertiesTxt, I18nTexts.validateNodePropertiesMsg); } else { @@ -317,7 +267,7 @@ export class ServiceDependenciesComponent { } } - onAddNodeFilterCapabilities = () => { + onAddNodeFilterCapabilities = (): void => { if (this.componentInstanceCapabilitiesMap.size == 0) { this.modalServiceNg2.openAlertModal(I18nTexts.validateCapabilitiesTxt, I18nTexts.validateCapabilitiesMsg); } else { @@ -342,12 +292,12 @@ export class ServiceDependenciesComponent { } } - createNodeFilter = (constraintType: string) => { + createNodeFilter = (constraintType: string): void => { this.isLoading = true; this.topologyTemplateService.createServiceFilterConstraints( this.compositeService.uniqueId, this.currentServiceInstance.uniqueId, - new ConstraintObject(this.modalInstance.instance.dynamicContent.instance.currentRule), + new FilterConstraint(this.modalInstance.instance.dynamicContent.instance.currentRule), this.compositeService.componentType, constraintType ).subscribe( (response) => { @@ -359,12 +309,12 @@ export class ServiceDependenciesComponent { this.modalServiceNg2.closeCurrentModal(); } - createNodeFilterCapabilities = (constraintType: string) => { + createNodeFilterCapabilities = (constraintType: string): void => { this.isLoading = true; this.topologyTemplateService.createServiceFilterCapabilitiesConstraints( this.compositeService.uniqueId, this.currentServiceInstance.uniqueId, - new CapabilitiesConstraintObjectUI(this.modalInstance.instance.dynamicContent.instance.currentRule), + new CapabilityFilterConstraintUI(this.modalInstance.instance.dynamicContent.instance.currentRule), this.compositeService.componentType, constraintType ).subscribe( (response) => { @@ -376,7 +326,7 @@ export class ServiceDependenciesComponent { this.modalServiceNg2.closeCurrentModal(); } - onSelectNodeFilterCapability(constraintType: string, index: number) { + onSelectNodeFilterCapability(constraintType: string, index: number): void { const cancelButton: ButtonModel = new ButtonModel(I18nTexts.modalCancel, 'outline white', this.modalServiceNg2.closeCurrentModal); const saveButton: ButtonModel = new ButtonModel(I18nTexts.modalSave, 'blue', () => this.updateNodeFilterCapability(constraintType, index), this.getDisabled); const modalModel: ModalModel = new ModalModel('l', I18nTexts.updateNodeFilterTxt, '', [saveButton, cancelButton], 'standard'); @@ -387,7 +337,7 @@ export class ServiceDependenciesComponent { CapabilitiesFilterPropertiesEditorComponent, { serviceRuleIndex: index, - serviceRules: _.map(this.constraintCapabilities, (rule) => new CapabilitiesConstraintObjectUI(rule)), + serviceRules: _.map(this.constraintCapabilities, (rule) => new CapabilityFilterConstraintUI(rule)), currentServiceName: this.currentServiceInstance.name, operatorTypes: this.operatorTypes, compositeServiceName: this.compositeService.name, @@ -400,7 +350,7 @@ export class ServiceDependenciesComponent { this.modalInstance.instance.open(); } - onSelectNodeFilter(constraintType: string, index: number) { + onSelectNodeFilter(constraintType: string, index: number): void { const cancelButton: ButtonModel = new ButtonModel(I18nTexts.modalCancel, 'outline white', this.modalServiceNg2.closeCurrentModal); const saveButton: ButtonModel = new ButtonModel(I18nTexts.modalSave, 'blue', () => this.updateNodeFilter(constraintType, index), this.getDisabled); const modalModel: ModalModel = new ModalModel('l', I18nTexts.updateNodeFilterTxt, '', [saveButton, cancelButton], 'standard'); @@ -410,7 +360,7 @@ export class ServiceDependenciesComponent { ServiceDependenciesEditorComponent, { serviceRuleIndex: index, - serviceRules: _.map(this.constraintProperties, (rule) => new ConstraintObjectUI(rule)), + serviceRules: this.constraintProperties.map(rule => new ConstraintObjectUI(rule)), currentServiceName: this.currentServiceInstance.name, operatorTypes: this.operatorTypes, compositeServiceName: this.compositeService.name, @@ -427,12 +377,12 @@ export class ServiceDependenciesComponent { return !this.modalInstance.instance.dynamicContent.instance.checkFormValidForSubmit(); } - updateNodeFilter = (constraintType: string, index: number) => { + updateNodeFilter = (constraintType: string, index: number): void => { this.isLoading = true; this.topologyTemplateService.updateServiceFilterConstraints( this.compositeService.uniqueId, this.currentServiceInstance.uniqueId, - new ConstraintObject(this.modalInstance.instance.dynamicContent.instance.currentRule), + new FilterConstraint(this.modalInstance.instance.dynamicContent.instance.currentRule), this.compositeService.componentType, constraintType, index @@ -445,12 +395,12 @@ export class ServiceDependenciesComponent { this.modalServiceNg2.closeCurrentModal(); } - updateNodeFilterCapability= (constraintType: string, index: number) => { + updateNodeFilterCapability = (constraintType: string, index: number): void => { this.isLoading = true; this.topologyTemplateService.updateServiceFilterCapabilitiesConstraint( this.compositeService.uniqueId, this.currentServiceInstance.uniqueId, - new CapabilitiesConstraintObjectUI(this.modalInstance.instance.dynamicContent.instance.currentRule), + new CapabilityFilterConstraintUI(this.modalInstance.instance.dynamicContent.instance.currentRule), this.compositeService.componentType, constraintType, index @@ -463,17 +413,7 @@ export class ServiceDependenciesComponent { this.modalServiceNg2.closeCurrentModal(); } - getSymbol(constraintOperator) { - switch (constraintOperator) { - case OPERATOR_TYPES.LESS_THAN: return '<'; - case OPERATOR_TYPES.EQUAL: return '='; - case OPERATOR_TYPES.GREATER_THAN: return '>'; - case OPERATOR_TYPES.GREATER_OR_EQUAL: return '>='; - case OPERATOR_TYPES.LESS_OR_EQUAL: return '<='; - } - } - - onDeleteNodeFilter = (constraintType: string, index: number) => { + onDeleteNodeFilter = (constraintType: string, index: number): void => { this.isLoading = true; this.topologyTemplateService.deleteServiceFilterConstraints( this.compositeService.uniqueId, @@ -494,15 +434,37 @@ export class ServiceDependenciesComponent { if (this.properties === constraintType) { this.updateNodeFilterProperties.emit(response.properties); this.constraintProperties = response.properties; + this.buildConstraintPropertyLabels(); } else { this.updateNodeFilterCapabilities.emit(response.capabilities); this.constraintCapabilities = response.capabilities; + this.buildCapabilityFilterConstraintLabels(); } } - openDeleteModal = (constraintType: string, index: number) => { + openDeleteModal = (constraintType: string, index: number): void => { this.modalServiceNg2.createActionModal(I18nTexts.deleteNodeFilterTxt, I18nTexts.deleteNodeFilterMsg, I18nTexts.modalDelete, () => this.onDeleteNodeFilter(constraintType, index), I18nTexts.modalCancel).instance.open(); } + private buildConstraintPropertyLabels(): void { + this.constraintPropertyLabels = []; + if (!this.constraintProperties) { + return; + } + this.constraintProperties.forEach( + constraint => this.constraintPropertyLabels.push(FilterConstraintHelper.buildFilterConstraintLabel(constraint)) + ) + } + + private buildCapabilityFilterConstraintLabels(): void { + this.constraintCapabilityLabels = []; + if (!this.constraintCapabilities) { + return; + } + this.constraintCapabilities.forEach( + constraint => this.constraintCapabilityLabels.push(FilterConstraintHelper.buildFilterConstraintLabel(constraint)) + ) + } + } diff --git a/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.html b/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.html index 81fc5b48ee..6e57de50ea 100644 --- a/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.html +++ b/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.html @@ -30,11 +30,8 @@ <div class="rule-details" [ngClass]="{'readonly': readonly}"> <div class="rule-desc" (click)="!readonly && onSelectSubstitutionFilter(PROPERTIES, i)" tooltips - tooltip="{{property.servicePropertyName + ' ' + getSymbol(property.constraintOperator) + ' ' - + (property.sourceName ? property.sourceName + ':' : '') + property.value}}"> - {{property.servicePropertyName + ' ' + getSymbol(property.constraintOperator) - + ' ' - + (property.sourceName ? property.sourceName + ':' : '') + property.value}} + tooltip="{{constraintPropertyLabels[i]}}"> + {{constraintPropertyLabels[i]}} </div> <span *ngIf="!readonly" class="sprite-new delete-btn delete-icon" (click)="openDeleteModal(PROPERTIES, i)" diff --git a/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.ts b/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.ts index 7671d653e4..53563e07a2 100644 --- a/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.ts +++ b/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.ts @@ -17,14 +17,8 @@ * ============LICENSE_END========================================================= */ -import {Component, ComponentRef, EventEmitter, Input, Output} from '@angular/core'; -import { - ButtonModel, - ComponentInstance, - InputBEModel, - ModalModel, - PropertyBEModel, -} from 'app/models'; +import {Component, ComponentRef, EventEmitter, Input, OnChanges, OnInit, Output} from '@angular/core'; +import {ButtonModel, ComponentInstance, InputBEModel, ModalModel, PropertyBEModel,} from 'app/models'; import {ModalComponent} from 'app/ng2/components/ui/modal/modal.component'; import {ServiceDependenciesEditorComponent} from 'app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component'; import {ModalService} from 'app/ng2/services/modal.service'; @@ -32,51 +26,9 @@ import {TranslateService} from 'app/ng2/shared/translator/translate.service'; import {ComponentMetadata} from '../../../../models/component-metadata'; import {TopologyTemplateService} from '../../../services/component-services/topology-template.service'; import {ToscaFilterConstraintType} from "../../../../models/tosca-filter-constraint-type.enum"; - -export class ConstraintObject { - servicePropertyName: string; - constraintOperator: string; - sourceType: string; - sourceName: string; - value: string; - - constructor(input?: any) { - if (input) { - this.servicePropertyName = input.servicePropertyName; - this.constraintOperator = input.constraintOperator; - this.sourceType = input.sourceType; - this.sourceName = input.sourceName; - this.value = input.value; - } - } -} - -export class ConstraintObjectUI extends ConstraintObject { - isValidValue: boolean; - - constructor(input?: any) { - super(input); - if (input) { - this.isValidValue = input.isValidValue ? input.isValidValue : input.value !== ''; - } - } - - public updateValidity(isValidValue: boolean) { - this.isValidValue = isValidValue; - } - - public isValidRule(isStatic) { - const isValidValue = isStatic ? this.isValidValue : true; - return this.servicePropertyName != null && this.servicePropertyName !== '' - && this.value != null && this.value !== '' && isValidValue; - } -} - -export const OPERATOR_TYPES = { - EQUAL: 'equal', - GREATER_THAN: 'greater_than', - LESS_THAN: 'less_than' -}; +import {FilterConstraint} from "app/models/filter-constraint"; +import {ConstraintObjectUI} from "../../../../models/ui-models/constraint-object-ui"; +import {FilterConstraintHelper, OPERATOR_TYPES} from "../../../../utils/filter-constraint-helper"; class I18nTexts { static addSubstitutionFilterTxt: string; @@ -108,34 +60,37 @@ class I18nTexts { providers: [ModalService, TranslateService] }) -export class SubstitutionFilterComponent { +export class SubstitutionFilterComponent implements OnInit, OnChanges { modalInstance: ComponentRef<ModalComponent>; isLoading: boolean; operatorTypes: any[]; - constraintProperties: ConstraintObject[] = []; + constraintProperties: FilterConstraint[] = []; + constraintPropertyLabels: string[] = []; PROPERTIES: string = ToscaFilterConstraintType.PROPERTIES; @Input() readonly: boolean; @Input() compositeService: ComponentMetadata; @Input() currentServiceInstance: ComponentInstance; - @Input() selectedInstanceConstraints: ConstraintObject[] = []; + @Input() selectedInstanceConstraints: FilterConstraint[] = []; @Input() selectedInstanceProperties: PropertyBEModel[] = []; @Input() parentServiceProperties: PropertyBEModel[] = []; @Input() parentServiceInputs: InputBEModel[] = []; - @Output() updateSubstitutionFilterProperties: EventEmitter<ConstraintObject[]> = new EventEmitter<ConstraintObject[]>(); - @Output() updateConstraintListEvent: EventEmitter<ConstraintObject[]> = new EventEmitter<ConstraintObject[]>(); + @Output() updateSubstitutionFilterProperties: EventEmitter<FilterConstraint[]> = new EventEmitter<FilterConstraint[]>(); + @Output() updateConstraintListEvent: EventEmitter<FilterConstraint[]> = new EventEmitter<FilterConstraint[]>(); @Output() loadConstraintListEvent: EventEmitter<any> = new EventEmitter(); @Output() hasSubstitutionFilter = new EventEmitter<boolean>(); constructor(private topologyTemplateService: TopologyTemplateService, private modalServiceNg2: ModalService, private translateService: TranslateService) { } - ngOnInit() { + ngOnInit(): void { this.isLoading = false; this.operatorTypes = [ - {label: '>', value: OPERATOR_TYPES.GREATER_THAN}, - {label: '<', value: OPERATOR_TYPES.LESS_THAN}, - {label: '=', value: OPERATOR_TYPES.EQUAL} + {label: FilterConstraintHelper.convertToSymbol(OPERATOR_TYPES.GREATER_THAN), value: OPERATOR_TYPES.GREATER_THAN}, + {label: FilterConstraintHelper.convertToSymbol(OPERATOR_TYPES.LESS_THAN), value: OPERATOR_TYPES.LESS_THAN}, + {label: FilterConstraintHelper.convertToSymbol(OPERATOR_TYPES.EQUAL), value: OPERATOR_TYPES.EQUAL}, + {label: FilterConstraintHelper.convertToSymbol(OPERATOR_TYPES.GREATER_OR_EQUAL), value: OPERATOR_TYPES.GREATER_OR_EQUAL}, + {label: FilterConstraintHelper.convertToSymbol(OPERATOR_TYPES.LESS_OR_EQUAL), value: OPERATOR_TYPES.LESS_OR_EQUAL} ]; this.loadSubstitutionFilter(); this.translateService.languageChangedObservable.subscribe((lang) => { @@ -143,7 +98,7 @@ export class SubstitutionFilterComponent { }); } - ngOnChanges(changes) { + ngOnChanges(changes): void { if (changes.compositeService) { this.compositeService = changes.compositeService.currentValue; } @@ -158,11 +113,12 @@ export class SubstitutionFilterComponent { .subscribe((response) => { if(response.substitutionFilters) { this.constraintProperties = response.substitutionFilters.properties; + this.buildConstraintPropertyLabels(); } }); } - onAddSubstitutionFilter = (constraintType: string) => { + onAddSubstitutionFilter = (constraintType: string): void => { const cancelButton: ButtonModel = new ButtonModel(I18nTexts.modalCancel, 'outline white', this.modalServiceNg2.closeCurrentModal); const saveButton: ButtonModel = new ButtonModel(I18nTexts.modalCreate, 'blue', () => this.createSubstitutionFilter(constraintType), this.getDisabled); const modalModel: ModalModel = new ModalModel('l', I18nTexts.addSubstitutionFilterTxt, '', [saveButton, cancelButton], 'standard'); @@ -182,8 +138,8 @@ export class SubstitutionFilterComponent { this.modalInstance.instance.open(); } - createSubstitutionFilter = (constraintType: string) => { - const newSubstitutionFilter: ConstraintObject = new ConstraintObject(this.modalInstance.instance.dynamicContent.instance.currentRule); + createSubstitutionFilter = (constraintType: string): void => { + const newSubstitutionFilter: FilterConstraint = new FilterConstraint(this.modalInstance.instance.dynamicContent.instance.currentRule); this.isLoading = true; this.topologyTemplateService.createSubstitutionFilterConstraints( this.compositeService.uniqueId, @@ -194,7 +150,7 @@ export class SubstitutionFilterComponent { this.emitEventOnChanges(constraintType, response); this.isLoading = false; }, (err) => { - console.error("Failed to Create Substitution Filter on the component with id: ", this.compositeService.uniqueId); + console.error(`Failed to Create Substitution Filter on the component with id: ${this.compositeService.uniqueId}`, err); this.isLoading = false; }); this.modalServiceNg2.closeCurrentModal(); @@ -202,7 +158,7 @@ export class SubstitutionFilterComponent { onSelectSubstitutionFilter(constraintType: string, index: number) { const cancelButton: ButtonModel = new ButtonModel(I18nTexts.modalCancel, 'outline white', this.modalServiceNg2.closeCurrentModal); - const updateButton: ButtonModel = new ButtonModel(I18nTexts.modalSave, 'blue', () => this.updateSubstitutionFilter(constraintType), this.getDisabled); + const updateButton: ButtonModel = new ButtonModel(I18nTexts.modalSave, 'blue', () => this.updateSubstitutionFilter(constraintType, index), this.getDisabled); const modalModel: ModalModel = new ModalModel('l', I18nTexts.updateSubstitutionFilterTxt, '', [updateButton, cancelButton], 'standard'); this.modalInstance = this.modalServiceNg2.createCustomModal(modalModel); this.modalServiceNg2.addDynamicContentToModal( @@ -222,25 +178,26 @@ export class SubstitutionFilterComponent { this.modalInstance.instance.open(); } - updateSubstitutionFilter = (constraintType: string): void => { - const constraintToUpdate: ConstraintObject[] = this.modalInstance.instance.dynamicContent.instance.serviceRulesList.map((rule) => new ConstraintObject(rule)); + updateSubstitutionFilter(constraintType: string, index: number): void { + const constraintToUpdate: FilterConstraint = this.modalInstance.instance.dynamicContent.instance.currentRule; this.isLoading = true; - this.topologyTemplateService.updateSubstitutionFilterConstraints( + this.topologyTemplateService.updateSubstitutionFilterConstraint( this.compositeService.uniqueId, constraintToUpdate, this.compositeService.componentType, - constraintType + constraintType, + index ).subscribe((response) => { this.emitEventOnChanges(constraintType, response); this.isLoading = false; - }, () => { - console.error("Failed to Update Substitution Filter on the component with id: ", this.compositeService.uniqueId); + }, (error) => { + console.error("Failed to Update Substitution Filter on the component with id: ", this.compositeService.uniqueId, error); this.isLoading = false; }); this.modalServiceNg2.closeCurrentModal(); } - onDeleteSubstitutionFilter = (constraintType: string, index: number) => { + onDeleteSubstitutionFilter = (constraintType: string, index: number): void => { this.isLoading = true; this.topologyTemplateService.deleteSubstitutionFilterConstraints( this.compositeService.uniqueId, @@ -262,26 +219,27 @@ export class SubstitutionFilterComponent { return !this.modalInstance.instance.dynamicContent.instance.checkFormValidForSubmit(); } - getSymbol(constraintOperator) { - switch (constraintOperator) { - case OPERATOR_TYPES.LESS_THAN: - return '<'; - case OPERATOR_TYPES.EQUAL: - return '='; - case OPERATOR_TYPES.GREATER_THAN: - return '>'; - } - } - - openDeleteModal = (constraintType: string, index: number) => { + openDeleteModal = (constraintType: string, index: number): void => { this.modalServiceNg2.createActionModal(I18nTexts.deleteSubstitutionFilterTxt, I18nTexts.deleteSubstitutionFilterMsg, I18nTexts.modalDelete, () => this.onDeleteSubstitutionFilter(constraintType, index), I18nTexts.modalCancel).instance.open(); } - private emitEventOnChanges(constraintType: string, response) { - if (ToscaFilterConstraintType.PROPERTIES === constraintType) { - this.updateSubstitutionFilterProperties.emit(response.properties); - this.constraintProperties = response.properties; - } + private emitEventOnChanges(constraintType: string, response): void { + if (ToscaFilterConstraintType.PROPERTIES === constraintType) { + this.updateSubstitutionFilterProperties.emit(response.properties); + this.constraintProperties = response.properties; + this.buildConstraintPropertyLabels(); + } + } + + private buildConstraintPropertyLabels(): void { + this.constraintPropertyLabels = []; + if (!this.constraintProperties) { + return; + } + this.constraintProperties.forEach( + constraint => this.constraintPropertyLabels.push(FilterConstraintHelper.buildFilterConstraintLabel(constraint)) + ) } + } diff --git a/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.ts b/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.ts index 7e3bc69835..b59591bd06 100644 --- a/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.ts +++ b/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.ts @@ -21,12 +21,12 @@ import {Component} from '@angular/core'; import {InputBEModel, PropertyBEModel, PropertyModel} from 'app/models'; -import {OPERATOR_TYPES} from 'app/ng2/components/logic/service-dependencies/service-dependencies.component'; import {DropdownValue} from 'app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component'; import {ServiceServiceNg2} from 'app/ng2/services/component-services/service.service'; import {PROPERTY_DATA} from 'app/utils'; import {ServiceInstanceObject} from '../../../../models/service-instance-properties-and-interfaces'; -import {CapabilitiesConstraintObjectUI} from "../../../components/logic/capabilities-constraint/capabilities-constraint.component"; +import {CapabilityFilterConstraintUI} from "../../../../models/capability-filter-constraint"; +import {OPERATOR_TYPES} from "../../../../utils/filter-constraint-helper"; export class UIDropDownSourceTypesElement extends DropdownValue { options: any[]; @@ -53,7 +53,7 @@ export class CapabilitiesFilterPropertiesEditorComponent { input: { serviceRuleIndex: number, - serviceRules: CapabilitiesConstraintObjectUI[], + serviceRules: CapabilityFilterConstraintUI[], compositeServiceName: string, currentServiceName: string, parentServiceInputs: InputBEModel[], @@ -66,12 +66,12 @@ export class CapabilitiesFilterPropertiesEditorComponent { selectedServiceProperties: PropertyBEModel[]; operatorTypes: DropdownValue[]; sourceTypes: UIDropDownSourceTypesElement[] = []; - currentRule: CapabilitiesConstraintObjectUI; + currentRule: CapabilityFilterConstraintUI; currentIndex: number; listOfValuesToAssign: DropdownValue[]; listOfSourceOptions: PropertyBEModel[]; assignedValueLabel: string; - serviceRulesList: CapabilitiesConstraintObjectUI[]; + serviceRulesList: CapabilityFilterConstraintUI[]; capabilitiesNames: string[]; selectedPropertiesByCapabilityName: Array<PropertyModel>; @@ -92,7 +92,7 @@ export class CapabilitiesFilterPropertiesEditorComponent { this.serviceRulesList = this.input.serviceRules; this.currentRule = this.serviceRulesList && this.input.serviceRuleIndex >= 0 ? this.serviceRulesList[this.input.serviceRuleIndex] : - new CapabilitiesConstraintObjectUI({ + new CapabilityFilterConstraintUI({ capabilityName: this.SOURCE_TYPES.CAPABILITY_NAME.value, sourceName: this.SOURCE_TYPES.STATIC.value, sourceType: this.SOURCE_TYPES.STATIC.value, value: '', diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/service-dependencies-tab/service-dependencies-tab.component.ts b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/service-dependencies-tab/service-dependencies-tab.component.ts index f844dfae4c..ce1a43dd3b 100644 --- a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/service-dependencies-tab/service-dependencies-tab.component.ts +++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/service-dependencies-tab/service-dependencies-tab.component.ts @@ -11,13 +11,13 @@ import {DEPENDENCY_EVENTS} from 'app/utils/constants'; import {ComponentMetadata} from '../../../../../../models/component-metadata'; import {ServiceInstanceObject} from '../../../../../../models/service-instance-properties-and-interfaces'; import {EventListenerService} from '../../../../../../services/event-listener-service'; -import {ConstraintObject} from '../../../../../components/logic/service-dependencies/service-dependencies.component'; import {TopologyTemplateService} from '../../../../../services/component-services/topology-template.service'; import {ComponentGenericResponse} from '../../../../../services/responses/component-generic-response'; import {WorkspaceService} from '../../../../workspace/workspace.service'; import {SelectedComponentType} from '../../../common/store/graph.actions'; import {CompositionService} from '../../../composition.service'; -import {CapabilitiesConstraintObject} from "../../../../../components/logic/capabilities-constraint/capabilities-constraint.component"; +import {CapabilityFilterConstraint} from "../../../../../../models/capability-filter-constraint"; +import {FilterConstraint} from "../../../../../../models/filter-constraint"; @Component({ selector: 'service-dependencies-tab', @@ -29,7 +29,7 @@ export class ServiceDependenciesTabComponent { selectedInstanceSiblings: ServiceInstanceObject[]; componentInstancesConstraints: any[]; - selectedInstanceConstraints: ConstraintObject[]; + selectedInstanceConstraints: FilterConstraint[]; selectedInstanceProperties: PropertyBEModel[]; componentInstanceProperties: PropertiesGroup; componentInstanceCapabilityProperties: CapabilitiesGroup; @@ -68,12 +68,12 @@ export class ServiceDependenciesTabComponent { this.eventListenerService.notifyObservers(DEPENDENCY_EVENTS.ON_DEPENDENCY_CHANGE, isChecked); } - public updateSelectedInstanceConstraints = (constraintsList:Array<ConstraintObject>):void => { + public updateSelectedInstanceConstraints = (constraintsList:Array<FilterConstraint>):void => { this.componentInstancesConstraints[this.component.uniqueId].properties = constraintsList; this.selectedInstanceConstraints = this.componentInstancesConstraints[this.component.uniqueId].properties; } - public updateSelectedInstanceCapabilitiesConstraints = (constraintsList:Array<CapabilitiesConstraintObject>):void => { + public updateSelectedInstanceCapabilitiesConstraints = (constraintsList:Array<CapabilityFilterConstraint>):void => { this.componentInstancesConstraints[this.component.uniqueId].capabilities = constraintsList; this.selectedInstanceConstraints = this.componentInstancesConstraints[this.component.uniqueId].capabilities; } diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/substitution-filter-tab/substitution-filter-tab.component.ts b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/substitution-filter-tab/substitution-filter-tab.component.ts index bf8d1e43b1..ac497ee98e 100644 --- a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/substitution-filter-tab/substitution-filter-tab.component.ts +++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/substitution-filter-tab/substitution-filter-tab.component.ts @@ -17,24 +17,19 @@ * ============LICENSE_END========================================================= */ -import { Component, Input } from '@angular/core'; -import { Store } from '@ngxs/store'; -import { - Component as TopologyTemplate, - FullComponentInstance, InputBEModel, - PropertiesGroup, - PropertyBEModel, -} from 'app/models'; -import { SUBSTITUTION_FILTER_EVENTS } from 'app/utils/constants'; -import { ComponentMetadata } from '../../../../../../models/component-metadata'; -import { ServiceInstanceObject } from '../../../../../../models/service-instance-properties-and-interfaces'; -import { EventListenerService } from '../../../../../../services/event-listener-service'; -import { ConstraintObject } from '../../../../../components/logic/service-dependencies/service-dependencies.component'; -import { TopologyTemplateService } from '../../../../../services/component-services/topology-template.service'; -import { ComponentGenericResponse } from '../../../../../services/responses/component-generic-response'; -import { WorkspaceService } from '../../../../workspace/workspace.service'; -import { SelectedComponentType } from '../../../common/store/graph.actions'; -import { CompositionService } from '../../../composition.service'; +import {Component, Input} from '@angular/core'; +import {Store} from '@ngxs/store'; +import {Component as TopologyTemplate, FullComponentInstance, InputBEModel, PropertiesGroup, PropertyBEModel,} from 'app/models'; +import {SUBSTITUTION_FILTER_EVENTS} from 'app/utils/constants'; +import {ComponentMetadata} from '../../../../../../models/component-metadata'; +import {ServiceInstanceObject} from '../../../../../../models/service-instance-properties-and-interfaces'; +import {EventListenerService} from '../../../../../../services/event-listener-service'; +import {TopologyTemplateService} from '../../../../../services/component-services/topology-template.service'; +import {ComponentGenericResponse} from '../../../../../services/responses/component-generic-response'; +import {WorkspaceService} from '../../../../workspace/workspace.service'; +import {SelectedComponentType} from '../../../common/store/graph.actions'; +import {CompositionService} from '../../../composition.service'; +import {FilterConstraint} from "../../../../../../models/filter-constraint"; @Component({ selector: 'substitution-filter-tab', @@ -46,7 +41,7 @@ export class SubstitutionFilterTabComponent { selectedInstanceSiblings: ServiceInstanceObject[]; componentInstancesConstraints: any[]; - selectedInstanceConstraints: ConstraintObject[]; + selectedInstanceConstraints: FilterConstraint[]; parentServiceProperties: PropertyBEModel[]; parentServiceInputs: InputBEModel[]; componentInstanceProperties: PropertiesGroup; @@ -80,7 +75,7 @@ export class SubstitutionFilterTabComponent { this.eventListenerService.notifyObservers(SUBSTITUTION_FILTER_EVENTS.ON_SUBSTITUTION_FILTER_CHANGE, isChecked); } - public updateSelectedInstanceConstraints = (constraintsList:Array<ConstraintObject>):void => { + public updateSelectedInstanceConstraints = (constraintsList:Array<FilterConstraint>):void => { this.componentInstancesConstraints[this.component.uniqueId].properties = constraintsList; this.selectedInstanceConstraints = this.componentInstancesConstraints[this.component.uniqueId].properties; } diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/services/properties.utils.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/services/properties.utils.ts index 753cb6afe0..747de7c00f 100644 --- a/catalog-ui/src/app/ng2/pages/properties-assignment/services/properties.utils.ts +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/services/properties.utils.ts @@ -19,11 +19,20 @@ */ import * as _ from "lodash"; -import { Injectable } from '@angular/core'; -import { DataTypeModel, PropertyFEModel, PropertyBEModel, InstanceBePropertiesMap, InstanceFePropertiesMap, DerivedFEProperty, DerivedPropertyType, InputFEModel} from "app/models"; -import { DataTypeService } from "app/ng2/services/data-type.service"; -import { PropertiesService } from "app/ng2/services/properties.service"; -import { PROPERTY_TYPES, PROPERTY_DATA } from "app/utils"; +import {Injectable} from '@angular/core'; +import { + DataTypeModel, + DerivedFEProperty, + DerivedPropertyType, + InputFEModel, + InstanceBePropertiesMap, + InstanceFePropertiesMap, + PropertyBEModel, + PropertyFEModel +} from "app/models"; +import {DataTypeService} from "app/ng2/services/data-type.service"; +import {PropertiesService} from "app/ng2/services/properties.service"; +import {PROPERTY_TYPES} from "app/utils"; import { SubPropertyToscaFunction } from "app/models/sub-property-tosca-function"; @Injectable() @@ -139,7 +148,7 @@ export class PropertiesUtils { Object.keys(nestedValue).forEach((keyNested) => { property.flattenedChildren.push(...this.createListOrMapChildren(lastCreatedChild, keyNested, nestedValue[keyNested])); }); - }; + } }); } else if (property.derivedDataType === DerivedPropertyType.COMPLEX) { property.flattenedChildren = this.createFlattenedChildren(property.type, property.name); diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-concat-function/tosca-concat-function.component.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-concat-function/tosca-concat-function.component.ts index d808c284a8..ef45211ea0 100644 --- a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-concat-function/tosca-concat-function.component.ts +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-concat-function/tosca-concat-function.component.ts @@ -8,6 +8,7 @@ import {PropertyBEModel} from "../../../../../models/properties-inputs/property- import {PROPERTY_TYPES} from "../../../../../utils/constants"; import {InstanceFeDetails} from "../../../../../models/instance-fe-details"; import {ToscaFunctionValidationEvent} from "../tosca-function.component"; +import {ToscaFunction} from "../../../../../models/tosca-function"; @Component({ selector: 'app-tosca-concat-function', @@ -30,7 +31,6 @@ export class ToscaConcatFunctionComponent implements OnInit { parameters: ToscaFunctionParameter[] = []; propertyInputList: Array<PropertyBEModel> = []; - stringProperty: PropertyBEModel STRING_FUNCTION_TYPE = ToscaFunctionType.STRING @@ -44,7 +44,7 @@ export class ToscaConcatFunctionComponent implements OnInit { this.initForm(); } - private initForm() { + private initForm(): void { this.formGroup.valueChanges.subscribe(() => { this.onValidityChange.emit({ isValid: this.formGroup.valid, @@ -57,12 +57,13 @@ export class ToscaConcatFunctionComponent implements OnInit { if (!this.toscaConcatFunction) { return; } - if (this.toscaConcatFunction.parameters) { this.parameters = Array.from(this.toscaConcatFunction.parameters); for (const parameter of this.parameters) { if (parameter.type !== PROPERTY_TYPES.STRING) { - this.propertyInputList.push(this.createStringProperty(parameter)); + const propertyBEModel = this.createStringProperty(parameter.value); + propertyBEModel.toscaFunction = <ToscaFunction> parameter; + this.propertyInputList.push(propertyBEModel); this.concatParameterFormArray.push( new FormControl(parameter, [Validators.required, Validators.minLength(1)]) ); @@ -92,7 +93,7 @@ export class ToscaConcatFunctionComponent implements OnInit { return toscaConcatFunction1; } - addFunction() { + addFunction(): void { this.propertyInputList.push(this.createStringProperty()); this.parameters.push({} as ToscaFunctionParameter); this.concatParameterFormArray.push( @@ -100,32 +101,30 @@ export class ToscaConcatFunctionComponent implements OnInit { ); } - addStringParameter() { - this.parameters.push({ - type: ToscaFunctionType.STRING, - value: '' - }); + addStringParameter(): void { + const toscaStringParameter = new ToscaStringParameter(); + toscaStringParameter.value = '' + this.parameters.push(toscaStringParameter); this.propertyInputList.push(undefined); this.concatParameterFormArray.push( new FormControl('', [Validators.required, Validators.minLength(1)]) ); } - removeParameter(position) { + removeParameter(position): void { this.propertyInputList.splice(position, 1); this.parameters.splice(position, 1); this.concatParameterFormArray.removeAt(position); } - createStringProperty(toscaFunctionParameter?: ToscaFunctionParameter) { + createStringProperty(value?: any): PropertyBEModel { const property = new PropertyBEModel(); property.type = PROPERTY_TYPES.STRING; - property.toscaFunction = toscaFunctionParameter ? toscaFunctionParameter : undefined; - property.value = toscaFunctionParameter ? toscaFunctionParameter.value : undefined; + property.value = value ? value : undefined; return property; } - onFunctionValidityChange(event: ToscaFunctionValidationEvent, index: number) { + onFunctionValidityChange(event: ToscaFunctionValidationEvent, index: number): void { if (event.isValid && event.toscaFunction) { this.concatParameterFormArray.controls[index].setValue(event.toscaFunction) } else { diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.html b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.html index f93973cb16..8ee253e5dc 100644 --- a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.html +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.html @@ -21,7 +21,7 @@ <div class="w-sdc-form" [formGroup]="formGroup"> <div class="i-sdc-form-item"> <label class="i-sdc-form-label">{{'TOSCA_FUNCTION_LABEL' | translate}}</label> - <select formControlName="toscaFunctionType"> + <select formControlName="toscaFunctionType" (change)="onFunctionTypeChange()"> <option *ngFor="let toscaFunction of toscaFunctions" [ngValue]="toscaFunction">{{toscaFunction | lowercase}}</option> </select> diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.ts index 70df4eaced..e40a4d6e1e 100644 --- a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.ts +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.ts @@ -17,7 +17,7 @@ * ============LICENSE_END========================================================= */ -import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; +import {Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges} from '@angular/core'; import {ComponentMetadata, PropertyBEModel, PropertyDeclareAPIModel} from 'app/models'; import {TopologyTemplateService} from "../../../services/component-services/topology-template.service"; import {WorkspaceService} from "../../workspace/workspace.service"; @@ -31,13 +31,15 @@ import {ToscaFunction} from "../../../../models/tosca-function"; import {ToscaConcatFunctionValidationEvent} from "./tosca-concat-function/tosca-concat-function.component"; import {PROPERTY_TYPES} from "../../../../utils/constants"; import {YamlFunctionValidationEvent} from "./yaml-function/yaml-function.component"; +import {ToscaConcatFunction} from "../../../../models/tosca-concat-function"; +import {YamlFunction} from "../../../../models/yaml-function"; @Component({ selector: 'tosca-function', templateUrl: './tosca-function.component.html', styleUrls: ['./tosca-function.component.less'], }) -export class ToscaFunctionComponent implements OnInit { +export class ToscaFunctionComponent implements OnInit, OnChanges { @Input() property: PropertyBEModel; @Input() componentInstanceMap: Map<string, InstanceFeDetails> = new Map<string, InstanceFeDetails>(); @@ -81,11 +83,21 @@ export class ToscaFunctionComponent implements OnInit { this.isInitialized = true; } - private validate() { + ngOnChanges(changes: SimpleChanges): void { + if (changes.property) { + this.resetForm(); + this.toscaFunction = this.property.toscaFunction ? this.property.toscaFunction : undefined; + this.initToscaFunction(); + this.loadToscaFunctions(); + this.emitValidityChange(); + } + } + + private validate(): boolean { return (!this.toscaFunctionForm.value && !this.toscaFunctionTypeForm.value) || this.formGroup.valid; } - private initToscaFunction() { + private initToscaFunction(): void { if (this.property instanceof PropertyDeclareAPIModel && this.property.subPropertyToscaFunctions && (<PropertyDeclareAPIModel> this.property).propertiesName){ let propertiesPath = (<PropertyDeclareAPIModel> this.property).propertiesName.split("#"); if (propertiesPath.length > 1){ @@ -100,7 +112,7 @@ export class ToscaFunctionComponent implements OnInit { return; } } - + if (!this.property.isToscaFunction()) { return; } @@ -113,6 +125,7 @@ export class ToscaFunctionComponent implements OnInit { } private loadToscaFunctions(): void { + this.toscaFunctions = []; this.toscaFunctions.push(ToscaFunctionType.GET_ATTRIBUTE); this.toscaFunctions.push(ToscaFunctionType.GET_INPUT); this.toscaFunctions.push(ToscaFunctionType.GET_PROPERTY); @@ -151,7 +164,7 @@ export class ToscaFunctionComponent implements OnInit { return this.formGroup.get('toscaFunctionType').value === ToscaFunctionType.YAML; } - onClearValues() { + onClearValues(): void { this.resetForm(); } @@ -159,7 +172,7 @@ export class ToscaFunctionComponent implements OnInit { return this.allowClear && this.toscaFunctionTypeForm.value; } - onConcatFunctionValidityChange(validationEvent: ToscaConcatFunctionValidationEvent) { + onConcatFunctionValidityChange(validationEvent: ToscaConcatFunctionValidationEvent): void { if (validationEvent.isValid) { this.toscaFunctionForm.setValue(validationEvent.toscaConcatFunction); } else { @@ -167,7 +180,7 @@ export class ToscaFunctionComponent implements OnInit { } } - onGetFunctionValidityChange(validationEvent: ToscaGetFunctionValidationEvent) { + onGetFunctionValidityChange(validationEvent: ToscaGetFunctionValidationEvent): void { if (validationEvent.isValid) { this.toscaFunctionForm.setValue(validationEvent.toscaGetFunction); } else { @@ -175,7 +188,7 @@ export class ToscaFunctionComponent implements OnInit { } } - onYamlFunctionValidityChange(validationEvent: YamlFunctionValidationEvent) { + onYamlFunctionValidityChange(validationEvent: YamlFunctionValidationEvent): void { if (validationEvent.isValid) { this.toscaFunctionForm.setValue(validationEvent.value); } else { @@ -183,14 +196,35 @@ export class ToscaFunctionComponent implements OnInit { } } - private emitValidityChange() { - const isValid = this.validate(); + onFunctionTypeChange(): void { + this.toscaFunction = undefined; + this.toscaFunctionForm.reset(); + } + + private emitValidityChange(): void { + const isValid: boolean = this.validate(); this.onValidityChange.emit({ isValid: isValid, - toscaFunction: isValid ? this.toscaFunctionForm.value : undefined + toscaFunction: isValid ? this.buildFunctionFromForm() : undefined }); } + private buildFunctionFromForm(): ToscaFunction { + if (!this.toscaFunctionTypeForm.value) { + return undefined; + } + if (this.isConcatSelected()) { + return new ToscaConcatFunction(this.toscaFunctionForm.value); + } + if (this.isGetFunctionSelected()) { + return new ToscaGetFunction(this.toscaFunctionForm.value); + } + if (this.isYamlFunctionSelected()) { + return new YamlFunction(this.toscaFunctionForm.value); + } + + console.error(`Function ${this.toscaFunctionTypeForm.value} not supported`); + } } export class ToscaFunctionValidationEvent { diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.module.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.module.ts index 19cf2fb260..bcf10728f8 100644 --- a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.module.ts +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.module.ts @@ -45,7 +45,9 @@ import { YamlFunctionComponent } from './yaml-function/yaml-function.component'; TranslateModule, SdcUiComponentsModule ], - exports: [], + exports: [ + ToscaFunctionComponent + ], entryComponents: [ ToscaFunctionComponent ], diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.ts index 1f658f968a..a32a4d0e45 100644 --- a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.ts +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.ts @@ -426,6 +426,7 @@ export class ToscaGetFunctionComponent implements OnInit, OnChanges { } onPropertySourceChange(): void { + this.selectedProperty.reset(); if (!this.functionType || !this.propertySource.valid) { return; } diff --git a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.html b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.html index 2765fcce25..4e6993a1e4 100644 --- a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.html +++ b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.html @@ -5,8 +5,8 @@ <div class="i-sdc-form-content"> <div class="rule-builder-content"> - <div class="i-sdc-form-item rule-input-field"> - <label class="i-sdc-form-label required">{{currentServiceName}} Property</label> + <div class="i-sdc-form-item rule-input-field property"> + <label class="i-sdc-form-label required">{{"PROPERTY_LABEL" | translate}}</label> <ui-element-dropdown class="i-sdc-form-select" data-tests-id="servicePropertyName" @@ -17,50 +17,61 @@ </div> <div class="i-sdc-form-item rule-input-field operator"> + <label class="i-sdc-form-label required">{{"OPERATOR_LABEL" | translate}}</label> <ui-element-dropdown class="i-sdc-form-select" data-tests-id="constraintOperator" [values]="operatorTypes" [(value)]="currentRule.constraintOperator"></ui-element-dropdown> </div> - - <div class="i-sdc-form-item rule-input-field"> - <label class="i-sdc-form-label required">Function Type</label> - <ui-element-dropdown class="i-sdc-form-select" data-tests-id="functionType" [values]="functionTypes" [(value)]="currentRule.sourceType" (elementChanged)="onSelectFunctionType($event.value)"></ui-element-dropdown> + </div> + <div class="rule-builder-content"> + <div class="i-sdc-form-item"> + <label class="i-sdc-form-label required">Value Type</label> + <input type="radio" name="sourceType" + data-tests-id="value-type-static" + [(ngModel)]="selectedSourceType" + [value]="SOURCE_TYPES.STATIC.value" + (ngModelChange)="onSourceTypeChange()"/> {{"VALUE_LABEL" | translate}} + <input type="radio" name="sourceType" + data-tests-id="value-type-tosca-function" + [(ngModel)]="selectedSourceType" + [value]="SOURCE_TYPES.TOSCA_FUNCTION.value" + (ngModelChange)="onSourceTypeChange()"/> {{"VALUE_EXPRESSION_LABEL" | translate}} </div> - - <div class="i-sdc-form-item rule-input-field" *ngIf="isPropertyFunctionSelected()"> - <label class="i-sdc-form-label required">Source</label> - <input class="i-sdc-form-select" data-tests-id="sourceType" [disabled]="true" [(value)]="currentRule.sourceName" type="text"> + </div> + <div class="rule-builder-content" *ngIf="isToscaFunctionSource() && selectedProperty"> + <div class="i-sdc-form-item rule-input-field"> + <tosca-function [property]="selectedProperty" + [componentInstanceMap]="componentInstanceMap" + [allowClear]="false" + (onValidityChange)="onToscaFunctionValidityChange($event)" + > + </tosca-function> </div> - - <div [ngClass]="isComplexListMapType() && isStaticSource() ? 'complex-input-field' : ''" - class="i-sdc-form-item rule-input-field"> - <label class="i-sdc-form-label required">{{assignedValueLabel}}</label> + </div> + <div *ngIf="isToscaFunctionSource() && !selectedProperty"> + {{"NODE_FILTER_SELECT_PROPERTY" | translate}} + </div> + <div class="rule-builder-content" *ngIf="isStaticSource()"> + <div class="i-sdc-form-item rule-input-field complex-input-field"> <dynamic-property - *ngIf="isStaticSource() && isComplexListMapType()" - [selectedPropertyId]="selectedPropertyObj.uniqueId" - [property]="selectedPropertyObj" - [expandedChildId]="selectedPropertyObj.expandedChildPropertyId ? - selectedPropertyObj.expandedChildPropertyId : selectedPropertyObj.name" + *ngIf="isComplexListMapType()" + [selectedPropertyId]="selectedProperty.uniqueId" + [property]="selectedProperty" + [expandedChildId]="selectedProperty.expandedChildPropertyId ? + selectedProperty.expandedChildPropertyId : selectedProperty.name" [canBeDeclared]="true" (propertyChanged)="updateComplexListMapTypeRuleValue()" - [rootProperty]="selectedPropertyObj" - (expandChild)="selectedPropertyObj.updateExpandedChildPropertyId($event)"> + [rootProperty]="selectedProperty" + (expandChild)="selectedProperty.updateExpandedChildPropertyId($event)"> </dynamic-property> <dynamic-element - *ngIf="isStaticSource() && !isComplexListMapType()" - [(value)]="currentRule.value" - class="rule-assigned-value" - data-tests-id="ruleAssignedValue" - (elementChanged)="onValueChange($event.isValid)" - [type]="selectedPropertyObj ? selectedPropertyObj.type : 'string'"> + *ngIf="!isComplexListMapType()" + [(value)]="currentRule.value" + class="rule-assigned-value" + data-tests-id="ruleAssignedValue" + (elementChanged)="onValueChange($event.isValid)" + [type]="selectedProperty ? selectedProperty.type : 'string'"> </dynamic-element> - <ui-element-dropdown *ngIf="!isStaticSource()" - class="i-sdc-form-select" - data-tests-id="ruleAssignedValue" - [(value)]="currentRule.value" - [values]="listOfValuesToAssign"> - </ui-element-dropdown> </div> </div> </div> </form> - </div> diff --git a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.less b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.less index b475ed2847..36772a2f96 100644 --- a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.less +++ b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.less @@ -29,7 +29,10 @@ } &.operator{ width: 55px; - flex: 0 1 auto; + flex: 1 0 auto; + } + &.property { + flex: 2; } &.assigned-value-field { margin-bottom: 10px; diff --git a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.ts b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.ts index eddebc999d..ba7a4946ca 100644 --- a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.ts +++ b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.ts @@ -13,42 +13,30 @@ * or implied. See the License for the specific language governing * permissions and limitations under the License. */ -import {Component} from '@angular/core'; +import {Component, OnInit} from '@angular/core'; import {InputBEModel, PropertyBEModel, PropertyFEModel} from 'app/models'; -import { - ConstraintObjectUI, - OPERATOR_TYPES -} from 'app/ng2/components/logic/service-dependencies/service-dependencies.component'; +import {SourceType} from 'app/ng2/components/logic/service-dependencies/service-dependencies.component'; import {DropdownValue} from 'app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component'; import {ServiceServiceNg2} from 'app/ng2/services/component-services/service.service'; import {PROPERTY_DATA} from 'app/utils'; import {ServiceInstanceObject} from '../../../models/service-instance-properties-and-interfaces'; -import { PropertiesUtils } from '../properties-assignment/services/properties.utils'; +import {PropertiesUtils} from '../properties-assignment/services/properties.utils'; +import {ToscaFunctionValidationEvent} from "../properties-assignment/tosca-function/tosca-function.component"; +import {InstanceFeDetails} from "../../../models/instance-fe-details"; +import {CompositionService} from "../composition/composition.service"; +import {ToscaGetFunction} from "../../../models/tosca-get-function"; +import {ToscaFunction} from "../../../models/tosca-function"; +import {ToscaFunctionType} from "../../../models/tosca-function-type.enum"; +import {ConstraintObjectUI} from "../../../models/ui-models/constraint-object-ui"; +import {OPERATOR_TYPES} from "../../../utils/filter-constraint-helper"; -export class UIDropDownSourceTypesElement extends DropdownValue { - options: any[]; - assignedLabel: string; - type: string; - - constructor(input?: any) { - super(input ? input.value || '' : "", input ? input.label || '' : ""); - if (input) { - this.options = input.options; - this.assignedLabel = input.assignedLabel; - this.type = input.type; - } - } -} - -// tslint:disable-next-line:max-classes-per-file @Component({ selector: 'service-dependencies-editor', templateUrl: './service-dependencies-editor.component.html', styleUrls: ['./service-dependencies-editor.component.less'], providers: [ServiceServiceNg2] }) - -export class ServiceDependenciesEditorComponent { +export class ServiceDependenciesEditorComponent implements OnInit { input: { serviceRuleIndex: number, @@ -61,139 +49,94 @@ export class ServiceDependenciesEditorComponent { operatorTypes: DropdownValue[], selectedInstanceSiblings: ServiceInstanceObject[] }; + //output + currentRule: ConstraintObjectUI; + currentServiceName: string; - selectedServiceProperties: PropertyBEModel[]; - selectedPropertyObj: PropertyFEModel; + selectedServiceProperties: PropertyBEModel[] = []; ddValueSelectedServicePropertiesNames: DropdownValue[]; operatorTypes: DropdownValue[]; - functionTypes: DropdownValue[]; - sourceTypes: UIDropDownSourceTypesElement[] = []; - currentRule: ConstraintObjectUI; currentIndex: number; - listOfValuesToAssign: DropdownValue[]; - listOfSourceOptions: PropertyBEModel[]; - assignedValueLabel: string; serviceRulesList: ConstraintObjectUI[]; + isLoading: false; + selectedProperty: PropertyFEModel; + selectedSourceType: string; + componentInstanceMap: Map<string, InstanceFeDetails> = new Map<string, InstanceFeDetails>(); SOURCE_TYPES = { - STATIC: {label: 'Static', value: 'static'}, - SERVICE_PROPERTY: {label: 'Service Property', value: 'property'}, - SERVICE_INPUT: {label: 'Service Input', value: 'service_input'} + STATIC: {label: 'Static', value: SourceType.STATIC}, + TOSCA_FUNCTION: {label: 'Tosca Function', value: SourceType.TOSCA_FUNCTION} }; - constructor(private propertiesUtils: PropertiesUtils) {} + constructor(private propertiesUtils: PropertiesUtils, private compositionService: CompositionService) {} - ngOnInit() { + ngOnInit(): void { this.currentIndex = this.input.serviceRuleIndex; this.serviceRulesList = this.input.serviceRules; - this.initFunctionTypes(); - this.initCurrentRule(); + if (this.input.selectedInstanceProperties) { + this.selectedServiceProperties = this.input.selectedInstanceProperties; + } this.currentServiceName = this.input.currentServiceName; this.operatorTypes = this.input.operatorTypes; - this.selectedServiceProperties = this.input.selectedInstanceProperties; - this.ddValueSelectedServicePropertiesNames = _.map(this.input.selectedInstanceProperties, (prop) => new DropdownValue(prop.name, prop.name)); - if (this.SOURCE_TYPES.STATIC.value !== this.currentRule.sourceType) { - this.loadSourceTypesData(); + if (this.compositionService.componentInstances) { + this.compositionService.componentInstances.forEach(value => { + this.componentInstanceMap.set(value.uniqueId, <InstanceFeDetails>{ + name: value.name + }); + }); } + this.initCurrentRule(); + this.initSelectedSourceType(); + this.selectedProperty = new PropertyFEModel(this.selectedServiceProperties.find(property => property.name === this.currentRule.servicePropertyName)); + this.selectedProperty.toscaFunction = undefined; + this.selectedProperty.value = undefined; + this.ddValueSelectedServicePropertiesNames = _.map(this.input.selectedInstanceProperties, (prop) => new DropdownValue(prop.name, prop.name)); this.syncRuleData(); - } - - private initCurrentRule() { - this.currentRule = this.serviceRulesList && this.input.serviceRuleIndex >= 0 ? - this.serviceRulesList[this.input.serviceRuleIndex] : - new ConstraintObjectUI({ - sourceName: this.SOURCE_TYPES.STATIC.value, - sourceType: this.SOURCE_TYPES.STATIC.value, - value: '', - constraintOperator: OPERATOR_TYPES.EQUAL - }); - if (this.currentRule && this.currentRule.sourceType === this.SOURCE_TYPES.STATIC.value){ - this.sourceTypes.push({ - label: this.SOURCE_TYPES.STATIC.label, - value: this.SOURCE_TYPES.STATIC.value, - assignedLabel: this.SOURCE_TYPES.STATIC.value, - type: this.SOURCE_TYPES.STATIC.value, - options: []}); + if (this.isValueToscaFunction(this.currentRule.value)) { + this.selectedProperty.toscaFunction = this.currentRule.value; } } - private initFunctionTypes() { - this.functionTypes = [ - {label: this.SOURCE_TYPES.STATIC.label, value: this.SOURCE_TYPES.STATIC.value}, - {label: this.SOURCE_TYPES.SERVICE_PROPERTY.label, value: this.SOURCE_TYPES.SERVICE_PROPERTY.value}, - {label: this.SOURCE_TYPES.SERVICE_INPUT.label, value: this.SOURCE_TYPES.SERVICE_INPUT.value}]; - } - - onServicePropertyChanged() { - if(this.SOURCE_TYPES.SERVICE_INPUT.value === this.currentRule.sourceType || this.SOURCE_TYPES.SERVICE_PROPERTY.value === this.currentRule.sourceType){ - this.currentRule.sourceName = "SELF"; + private initSelectedSourceType(): void { + if (!this.currentRule.sourceType || this.currentRule.sourceType === SourceType.STATIC) { + this.selectedSourceType = SourceType.STATIC; } else { - this.currentRule.sourceName = ""; + this.selectedSourceType = SourceType.TOSCA_FUNCTION; } - this.updateSelectedPropertyObj(); - this.updateOperatorTypesList(); - this.updateSourceTypesRelatedValues(); - this.currentRule.value = ""; - } - - onSelectFunctionType(value: any) { - this.currentRule.sourceName = ""; - this.listOfValuesToAssign = []; - this.currentRule.sourceType = value; - this.loadSourceTypesData(); - this.updateSourceTypesRelatedValues(); } - private loadSourceTypesData() { - const SELF = "SELF"; - if (this.SOURCE_TYPES.SERVICE_INPUT.value === this.currentRule.sourceType || this.SOURCE_TYPES.SERVICE_PROPERTY.value === this.currentRule.sourceType) { - this.currentRule.sourceName = SELF; - } - this.sourceTypes = []; - this.sourceTypes.push({ - label: SELF, - value: SELF, - assignedLabel: this.currentRule.sourceType == this.SOURCE_TYPES.SERVICE_PROPERTY.value - ? this.SOURCE_TYPES.SERVICE_PROPERTY.label : this.SOURCE_TYPES.SERVICE_INPUT.label, - type: this.currentRule.sourceType == this.SOURCE_TYPES.SERVICE_PROPERTY.value - ? this.SOURCE_TYPES.SERVICE_PROPERTY.value : this.SOURCE_TYPES.SERVICE_INPUT.value, - options: this.loadSourceTypeBySelectedFunction().get(this.currentRule.sourceType) - }); - - if (this.currentRule.sourceType !== this.SOURCE_TYPES.SERVICE_INPUT.value) { - if (this.input.selectedInstanceSiblings && this.isPropertyFunctionSelected) { - _.forEach(this.input.selectedInstanceSiblings, (sib) => - this.sourceTypes.push({ - label: sib.name, - value: sib.name, - options: sib.properties || [], - assignedLabel: this.SOURCE_TYPES.SERVICE_PROPERTY.label, - type: this.SOURCE_TYPES.SERVICE_PROPERTY.value - }) - ); - } + private initCurrentRule(): void { + if (this.serviceRulesList && this.input.serviceRuleIndex >= 0) { + this.currentRule = new ConstraintObjectUI(this.serviceRulesList[this.input.serviceRuleIndex]); + } else { + this.currentRule = new ConstraintObjectUI({ + sourceName: SourceType.STATIC, + sourceType: SourceType.STATIC, + value: '', + constraintOperator: OPERATOR_TYPES.EQUAL + }); } } - loadSourceTypeBySelectedFunction = (): any => { - let parentDataMap = new Map(); - parentDataMap.set(this.SOURCE_TYPES.SERVICE_PROPERTY.value, this.input.parentServiceProperties); - parentDataMap.set(this.SOURCE_TYPES.SERVICE_INPUT.value , this.input.parentServiceInputs); - return parentDataMap; + onServicePropertyChanged(): void { + this.currentRule.sourceName = undefined; + this.currentRule.value = undefined; + this.selectedProperty = undefined; + this.updateSelectedProperty(); + this.updateOperatorTypesList(); } - syncRuleData() { - if (!this.currentRule.sourceName || this.currentRule.sourceType === this.SOURCE_TYPES.STATIC.value) { - this.currentRule.sourceName = this.SOURCE_TYPES.STATIC.value; - this.currentRule.sourceType = this.SOURCE_TYPES.STATIC.value; + syncRuleData(): void { + if (!this.currentRule.sourceName || this.currentRule.sourceType === SourceType.STATIC) { + this.currentRule.sourceName = SourceType.STATIC; + this.currentRule.sourceType = SourceType.STATIC; } - this.updateSelectedPropertyObj(); + this.initSelectedProperty(); this.updateOperatorTypesList(); - this.updateSourceTypesRelatedValues(); } - updateOperatorTypesList() { - if (this.selectedPropertyObj && PROPERTY_DATA.SIMPLE_TYPES_COMPARABLE.indexOf(this.selectedPropertyObj.type) === -1) { + updateOperatorTypesList(): void { + if (this.selectedProperty && PROPERTY_DATA.SIMPLE_TYPES_COMPARABLE.indexOf(this.selectedProperty.type) === -1) { this.operatorTypes = [{label: '=', value: OPERATOR_TYPES.EQUAL}]; this.currentRule.constraintOperator = OPERATOR_TYPES.EQUAL; } else { @@ -201,84 +144,95 @@ export class ServiceDependenciesEditorComponent { } } - updateSourceTypesRelatedValues() { - if (this.currentRule.sourceName) { - const selectedSourceType: UIDropDownSourceTypesElement = this.sourceTypes.find( - (t) => t.value === this.currentRule.sourceName && t.type === this.currentRule.sourceType - ); - if (selectedSourceType) { - this.listOfSourceOptions = []; - this.listOfSourceOptions = selectedSourceType.options || []; - this.assignedValueLabel = selectedSourceType.assignedLabel || this.SOURCE_TYPES.STATIC.label; - this.filterOptionsByType(); - } - } + onValueChange(isValidValue:any): void { + this.currentRule.updateValidity(isValidValue); } - onChangePage(newIndex:any) { - if (newIndex >= 0 && newIndex < this.input.serviceRules.length) { - this.currentIndex = newIndex; - this.currentRule = this.serviceRulesList[newIndex]; - this.syncRuleData(); - } + checkFormValidForSubmit(): boolean { + return this.currentRule.isValidRule(); } - filterOptionsByType() { - if (!this.selectedPropertyObj) { - this.listOfValuesToAssign = []; + initSelectedProperty(): void { + if (!this.currentRule.servicePropertyName) { + this.selectedProperty = undefined; return; } - this.listOfValuesToAssign = this.listOfSourceOptions.reduce((result, op: PropertyBEModel) => { - if (op.type === this.selectedPropertyObj.type && (!op.schemaType || op.schemaType === this.selectedPropertyObj.schemaType)) { - result.push(new DropdownValue(op.name, op.name)); - } - return result; - }, []); - } - onValueChange(isValidValue:any) { - this.currentRule.updateValidity(isValidValue); + const newProperty = new PropertyFEModel(this.selectedServiceProperties.find(property => property.name === this.currentRule.servicePropertyName)); + newProperty.value = undefined; + newProperty.toscaFunction = undefined; + if (typeof this.currentRule.value === 'string') { + newProperty.value = this.currentRule.value; + } else if (this.isValueToscaFunction(newProperty.value)) { + newProperty.toscaFunction = this.currentRule.value; + newProperty.value = (<ToscaFunction>this.currentRule.value).buildValueString(); + } else { + newProperty.value = JSON.stringify(this.currentRule.value); + } + this.propertiesUtils.initValueObjectRef(newProperty); + this.selectedProperty = newProperty; } - checkFormValidForSubmit() { - if (!this.serviceRulesList) { // for create modal - const isStatic = this.currentRule.sourceName === this.SOURCE_TYPES.STATIC.value; - return this.currentRule.isValidRule(isStatic); + updateSelectedProperty(): void { + this.selectedProperty = undefined; + if (!this.currentRule.servicePropertyName) { + return; + } + + const newProperty = new PropertyFEModel(this.selectedServiceProperties.find(property => property.name === this.currentRule.servicePropertyName)); + newProperty.value = undefined; + newProperty.toscaFunction = undefined; + if (this.isValueToscaFunction(newProperty.value)) { + newProperty.toscaFunction = this.currentRule.value; } - // for update all rules - return this.serviceRulesList.every((rule) => rule.isValidRule(rule.sourceName === this.SOURCE_TYPES.STATIC.value)); + this.propertiesUtils.initValueObjectRef(newProperty); + this.selectedProperty = newProperty; } - updateSelectedPropertyObj(): void { - this.selectedPropertyObj = null; - if (this.currentRule.servicePropertyName) { - let newProp = new PropertyFEModel(_.find(this.selectedServiceProperties, (prop) => prop.name === this.currentRule.servicePropertyName)); - newProp.value = JSON.stringify(this.currentRule.value); - this.propertiesUtils.initValueObjectRef(newProp); - console.log("TEST" + newProp.value); - setTimeout(() => { - this.selectedPropertyObj = newProp}) - this.selectedPropertyObj = newProp; - } + isValueToscaFunction(value: any): boolean { + return value instanceof Object && 'type' in value && (<any>Object).values(ToscaFunctionType).includes(value.type); } isStaticSource(): boolean { - return this.currentRule.sourceType === this.SOURCE_TYPES.STATIC.value + return this.selectedSourceType === SourceType.STATIC } - isPropertyFunctionSelected(): boolean { - return this.currentRule.sourceType === this.SOURCE_TYPES.SERVICE_PROPERTY.value; + isToscaFunctionSource(): boolean { + return this.selectedSourceType === SourceType.TOSCA_FUNCTION } isComplexListMapType(): boolean { - return this.selectedPropertyObj && this.selectedPropertyObj.derivedDataType > 0; + return this.selectedProperty && this.selectedProperty.derivedDataType > 0; } updateComplexListMapTypeRuleValue(): void { - let value = PropertyFEModel.cleanValueObj(this.selectedPropertyObj.valueObj); - this.currentRule.value = JSON.stringify(value); - this.onValueChange(this.selectedPropertyObj.valueObjIsValid); + this.currentRule.value = PropertyFEModel.cleanValueObj(this.selectedProperty.valueObj); + this.onValueChange(this.selectedProperty.valueObjIsValid); + } + + onToscaFunctionValidityChange(validationEvent: ToscaFunctionValidationEvent): void { + if (validationEvent.isValid && validationEvent.toscaFunction) { + this.currentRule.value = validationEvent.toscaFunction; + this.currentRule.sourceType = validationEvent.toscaFunction.type + if (validationEvent.toscaFunction instanceof ToscaGetFunction) { + this.currentRule.sourceName = validationEvent.toscaFunction.sourceName; + } + } else { + this.currentRule.updateValidity(false); + this.currentRule.value = undefined; + this.currentRule.sourceType = undefined; + this.currentRule.sourceName = undefined; + } + } + + onSourceTypeChange(): void { + this.currentRule.value = undefined; + this.currentRule.sourceType = this.selectedSourceType; + if (this.isStaticSource()) { + this.currentRule.sourceName = SourceType.STATIC; + } + this.updateSelectedProperty(); } } diff --git a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.module.ts b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.module.ts index cfa466ffa3..d5104c803f 100644 --- a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.module.ts +++ b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.module.ts @@ -5,6 +5,8 @@ import { FormElementsModule } from 'app/ng2/components/ui/form-components/form-e import { UiElementsModule } from 'app/ng2/components/ui/ui-elements.module'; import { ServiceDependenciesEditorComponent } from './service-dependencies-editor.component'; import { PropertyTableModule } from 'app/ng2/components/logic/properties-table/property-table.module'; +import {TranslateModule} from "../../shared/translator/translate.module"; +import {ToscaFunctionModule} from "../properties-assignment/tosca-function/tosca-function.module"; @NgModule({ declarations: [ @@ -15,7 +17,9 @@ import { PropertyTableModule } from 'app/ng2/components/logic/properties-table/p FormsModule, FormElementsModule, UiElementsModule, - PropertyTableModule + PropertyTableModule, + TranslateModule, + ToscaFunctionModule ], exports: [], entryComponents: [ diff --git a/catalog-ui/src/app/ng2/services/component-services/component.service.ts b/catalog-ui/src/app/ng2/services/component-services/component.service.ts index c9bb4d59f5..450e66ead2 100644 --- a/catalog-ui/src/app/ng2/services/component-services/component.service.ts +++ b/catalog-ui/src/app/ng2/services/component-services/component.service.ts @@ -44,15 +44,13 @@ import {HttpClient, HttpHeaders, HttpParams} from "@angular/common/http"; import {BEOperationModel, InterfaceModel} from "../../../models/operation"; import {PropertyBEModel} from "../../../models/properties-inputs/property-be-model"; import {PolicyInstance} from "../../../models/graph/zones/policy-instance"; -import { - ConstraintObject -} from "../../components/logic/service-dependencies/service-dependencies.component"; import {OutputBEModel} from "app/models/attributes-outputs/output-be-model"; import {HttpHelperService} from '../http-hepler.service'; import { BEInterfaceOperationModel, InterfaceOperationModel } from "../../../models/interfaceOperation"; +import {FilterConstraint} from "../../../models/filter-constraint"; /* PLEASE DO NOT USE THIS SERVICE IN ANGULAR2! Use the topology-template.service instead @@ -474,11 +472,11 @@ export class ComponentServiceNg2 { return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [SERVICE_FIELDS.NODE_FILTER]); } - createServiceFilterConstraints(component: Component, componentInstance: ComponentInstance, constraint: ConstraintObject): Observable<any> { + createServiceFilterConstraints(component: Component, componentInstance: ComponentInstance, constraint: FilterConstraint): Observable<any> { return this.http.post<any>(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/resourceInstances/' + componentInstance.uniqueId + '/nodeFilter', constraint); } - updateServiceFilterConstraints(component: Component, componentInstance: ComponentInstance, constraints: ConstraintObject[]): Observable<any> { + updateServiceFilterConstraints(component: Component, componentInstance: ComponentInstance, constraints: FilterConstraint[]): Observable<any> { return this.http.put<any>(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/resourceInstances/' + componentInstance.uniqueId + '/nodeFilter/', constraints); } diff --git a/catalog-ui/src/app/ng2/services/component-services/topology-template.service.ts b/catalog-ui/src/app/ng2/services/component-services/topology-template.service.ts index c497e013b4..5f6f074f5e 100644 --- a/catalog-ui/src/app/ng2/services/component-services/topology-template.service.ts +++ b/catalog-ui/src/app/ng2/services/component-services/topology-template.service.ts @@ -54,14 +54,14 @@ import {ServiceGenericResponse} from "../responses/service-generic-response"; import {HttpClient, HttpHeaders, HttpParams} from "@angular/common/http"; import {HttpHelperService} from "../http-hepler.service"; import {ConsumptionInput} from "../../components/logic/service-consumption/service-consumption.component"; -import {ConstraintObject} from "../../components/logic/service-dependencies/service-dependencies.component"; import {PolicyInstance} from "../../../models/graph/zones/policy-instance"; import {PropertyBEModel} from "../../../models/properties-inputs/property-be-model"; import {map} from "rxjs/operators"; -import {CapabilitiesConstraintObject} from "../../components/logic/capabilities-constraint/capabilities-constraint.component"; +import {CapabilityFilterConstraint} from "../../../models/capability-filter-constraint"; import {BEInterfaceOperationModel, InterfaceOperationModel} from "../../../models/interfaceOperation"; import {AttributeBEModel} from "../../../models/attributes-outputs/attribute-be-model"; import {InstanceAttributesAPIMap} from "../../../models/attributes-outputs/attribute-fe-map"; +import {FilterConstraint} from "../../../models/filter-constraint"; /* we need to use this service from now, we will remove component.service when we finish remove the angular1. The service is duplicated since we can not use downgrades service with NGXS*/ @@ -477,19 +477,19 @@ export class TopologyTemplateService { [COMPONENT_FIELDS.COMPONENT_CAPABILITIES, COMPONENT_FIELDS.COMPONENT_CAPABILITIES_PROPERTIES]); } - createServiceFilterConstraints(componentMetaDataId: string, componentInstanceId: string, constraint: ConstraintObject, componentType: string, constraintType: string): Observable<any> { + createServiceFilterConstraints(componentMetaDataId: string, componentInstanceId: string, constraint: FilterConstraint, componentType: string, constraintType: string): Observable<any> { return this.http.post<any>(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/componentInstance/' + componentInstanceId + '/' + constraintType + '/nodeFilter', constraint); } - createServiceFilterCapabilitiesConstraints(componentMetaDataId: string, componentInstanceId: string, constraint: CapabilitiesConstraintObject, componentType: string, constraintType: string): Observable<any> { + createServiceFilterCapabilitiesConstraints(componentMetaDataId: string, componentInstanceId: string, constraint: CapabilityFilterConstraint, componentType: string, constraintType: string): Observable<any> { return this.http.post<any>(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/componentInstance/' + componentInstanceId + '/' + constraintType + '/nodeFilter', constraint); } - updateServiceFilterConstraints(componentMetaDataId: string, componentInstanceId: string, constraints: ConstraintObject, componentType: string, constraintType: string, constraintIndex: number):Observable<any>{ - return this.http.put<any>(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/componentInstance/' + componentInstanceId + '/' + constraintType + '/' + constraintIndex + '/nodeFilter', constraints) + updateServiceFilterConstraints(componentMetaDataId: string, componentInstanceId: string, constraint: FilterConstraint, componentType: string, constraintType: string, constraintIndex: number):Observable<any>{ + return this.http.put<any>(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/componentInstance/' + componentInstanceId + '/' + constraintType + '/' + constraintIndex + '/nodeFilter', constraint) } - updateServiceFilterCapabilitiesConstraint(componentMetaDataId: string, componentInstanceId: string, constraints: CapabilitiesConstraintObject, componentType: string, constraintType: string, constraintIndex: number):Observable<any>{ + updateServiceFilterCapabilitiesConstraint(componentMetaDataId: string, componentInstanceId: string, constraints: CapabilityFilterConstraint, componentType: string, constraintType: string, constraintIndex: number):Observable<any>{ return this.http.put<any>(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/componentInstance/' + componentInstanceId + '/' + constraintType + '/' + constraintIndex + '/nodeFilter', constraints) } @@ -501,12 +501,14 @@ export class TopologyTemplateService { return this.getComponentDataByFieldsName(componentType, componentId, [COMPONENT_FIELDS.COMPONENT_PROPERTIES, COMPONENT_FIELDS.COMPONENT_INPUTS]); } - createSubstitutionFilterConstraints(componentMetaDataId: string, constraint: ConstraintObject, componentType: string, constraintType: string): Observable<any> { + createSubstitutionFilterConstraints(componentMetaDataId: string, constraint: FilterConstraint, componentType: string, constraintType: string): Observable<any> { return this.http.post<any>(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/substitutionFilter/' + constraintType, constraint); } - updateSubstitutionFilterConstraints(componentMetaDataId: string, constraint: ConstraintObject[], componentType: string, constraintType: string): Observable<any>{ - return this.http.put<any>(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/substitutionFilter/' + constraintType, constraint); + updateSubstitutionFilterConstraint(componentId: string, constraint: FilterConstraint, componentType: string, constraintType: string, + index: number): Observable<any> { + const url = `${this.baseUrl}${this.getServerTypeUrl(componentType)}${componentId}/substitutionFilter/${constraintType}/${index}`; + return this.http.put<any>(url, constraint); } deleteSubstitutionFilterConstraints(componentMetaDataId: string, constraintIndex: number, componentType: string, constraintType: string): Observable<any>{ diff --git a/catalog-ui/src/app/utils/filter-constraint-helper.ts b/catalog-ui/src/app/utils/filter-constraint-helper.ts new file mode 100644 index 0000000000..bdb3f9ec7a --- /dev/null +++ b/catalog-ui/src/app/utils/filter-constraint-helper.ts @@ -0,0 +1,64 @@ +import {FilterConstraint} from "../models/filter-constraint"; +import {ToscaFunctionType} from "../models/tosca-function-type.enum"; +import {ToscaConcatFunction} from "../models/tosca-concat-function"; +import {ToscaGetFunction} from "../models/tosca-get-function"; +import {YamlFunction} from "../models/yaml-function"; +import {CapabilityFilterConstraint} from "../models/capability-filter-constraint"; + +export class FilterConstraintHelper { + + public static buildFilterConstraintLabel(constraint: FilterConstraint | CapabilityFilterConstraint): string { + let value; + if (this.isValueToscaFunction(constraint.value)) { + switch (constraint.value.type) { + case ToscaFunctionType.CONCAT: + value = new ToscaConcatFunction(constraint.value).buildValueString(); + break; + case ToscaFunctionType.GET_PROPERTY: + case ToscaFunctionType.GET_INPUT: + case ToscaFunctionType.GET_ATTRIBUTE: + value = new ToscaGetFunction(constraint.value).buildValueString(); + break; + case ToscaFunctionType.YAML: + value = new YamlFunction(constraint.value).buildValueString(); + break; + case ToscaFunctionType.STRING: + value = constraint.value.value; + break; + default: + value = JSON.stringify(constraint.value, null, 4); + } + } else { + value = JSON.stringify(constraint.value, null, 4); + } + if (constraint instanceof CapabilityFilterConstraint) { + return `${constraint.capabilityName}: ${constraint.servicePropertyName} ${this.convertToSymbol(constraint.constraintOperator)} ${value}`; + } + + return `${constraint.servicePropertyName} ${this.convertToSymbol(constraint.constraintOperator)} ${value}`; + } + + public static convertToSymbol(constraintOperator: string) { + switch (constraintOperator) { + case OPERATOR_TYPES.LESS_THAN: return '<'; + case OPERATOR_TYPES.EQUAL: return '='; + case OPERATOR_TYPES.GREATER_THAN: return '>'; + case OPERATOR_TYPES.GREATER_OR_EQUAL: return '>='; + case OPERATOR_TYPES.LESS_OR_EQUAL: return '<='; + } + } + + private static isValueToscaFunction(value: any): boolean { + return value instanceof Object && 'type' in value && (<any>Object).values(ToscaFunctionType).includes(value.type); + } + +} + +export const OPERATOR_TYPES = { + EQUAL: 'equal', + GREATER_THAN: 'greater_than', + LESS_THAN: 'less_than', + GREATER_OR_EQUAL: 'greater_or_equal', + LESS_OR_EQUAL: 'less_or_equal' +}; + diff --git a/catalog-ui/src/assets/languages/en_US.json b/catalog-ui/src/assets/languages/en_US.json index 2bb8d75b21..586717a03c 100644 --- a/catalog-ui/src/assets/languages/en_US.json +++ b/catalog-ui/src/assets/languages/en_US.json @@ -245,6 +245,7 @@ "COMPONENT_VIEW_DELETE_MODAL_TITLE": "Delete Component Confirmation", "COMPONENT_VIEW_DELETE_MODAL_TEXT": "All versions of this component will be permanently deleted. This action cannot be undone. Are you sure you want to proceed?", "=========== PROPERTY VIEW ===========": "", + "PROPERTY_LABEL": "Property", "PROPERTY_VIEW_DELETE_MODAL_TITLE": "Delete Property Confirmation", "PROPERTY_VIEW_DELETE_MODAL_TEXT": "Are you sure you want to delete '{{name}}'?", "PROPERTY_EDIT_PATTERN": "Invalid value.", @@ -486,6 +487,7 @@ "DIRECTIVES_AND_NODE_FILTER_REMOVE_TEXT": "Removing \"Directive Option\" will remove directives value and erase all the node filter. Are you sure you want to remove directives?", "DIRECTIVES_AND_NODE_FILTER_UPDATE_TITLE": "Update Directives", "DIRECTIVES_AND_NODE_FILTER_UPDATE_TEXT": "Changing \"Directive Option\" will remove directives value and erase all the node filter. Are you sure you want to update directives?", + "NODE_FILTER_SELECT_PROPERTY": "Please, select a property", "VALIDATE_CAPABILITIES_TXT": "Node Filter for Capabilities Properties", "VALIDATE_CAPABILITIES_MSG": "The selected Component Instance does not have any capability property", "VALIDATE_NODE_PROPERTIES_TXT": "Node Filter for Properties", @@ -560,5 +562,8 @@ "CAP_NAME": "Capability Name", "CAP_TYPE": "Capability Type", "CAP_DESCRIPTION": "Description", - "CAP_VALID_SOURCE": "Valid Sources" + "CAP_VALID_SOURCE": "Valid Sources", + "VALUE_LABEL": "Value", + "VALUE_EXPRESSION_LABEL": "Value Expression", + "OPERATOR_LABEL": "Operator" } diff --git a/common-be/pom.xml b/common-be/pom.xml index 7c0d5fd71c..176fdc5dc1 100644 --- a/common-be/pom.xml +++ b/common-be/pom.xml @@ -13,13 +13,17 @@ </parent> <dependencies> - <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>${jackson.version}</version> </dependency> <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-annotations</artifactId> + <version>${jackson-annotations.version}</version> + </dependency> + <dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>${minio.version}</version> diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/CINodeFilterDataDefinition.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/CINodeFilterDataDefinition.java index 22055e0620..bef9e52b8a 100644 --- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/CINodeFilterDataDefinition.java +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/CINodeFilterDataDefinition.java @@ -44,12 +44,12 @@ public class CINodeFilterDataDefinition extends ToscaDataDefinition implements S return getToscaPresentationValue(JsonPresentationFields.TOSCA_ID); } - public ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> getProperties() { - return (ListDataDefinition<RequirementNodeFilterPropertyDataDefinition>) getToscaPresentationValue( + public ListDataDefinition<PropertyFilterDataDefinition> getProperties() { + return (ListDataDefinition<PropertyFilterDataDefinition>) getToscaPresentationValue( JsonPresentationFields.PROPERTIES); } - public void setProperties(ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> properties) { + public void setProperties(ListDataDefinition<PropertyFilterDataDefinition> properties) { setToscaPresentationValue(JsonPresentationFields.PROPERTIES, properties); } diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/PropertyFilterConstraintDataDefinition.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/PropertyFilterConstraintDataDefinition.java new file mode 100644 index 0000000000..9284b530eb --- /dev/null +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/PropertyFilterConstraintDataDefinition.java @@ -0,0 +1,41 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.openecomp.sdc.be.datatypes.elements; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; +import org.openecomp.sdc.be.datatypes.enums.FilterValueType; +import org.openecomp.sdc.be.datatypes.enums.PropertyFilterTargetType; + +@Data +@NoArgsConstructor +@JsonDeserialize(using = PropertyFilterConstraintDataDefinitionJsonDeserializer.class) +public class PropertyFilterConstraintDataDefinition { + private String propertyName; + private String capabilityName; + private PropertyFilterTargetType targetType; + private ConstraintType operator; + private FilterValueType valueType; + private Object value; +} diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/PropertyFilterConstraintDataDefinitionJsonDeserializer.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/PropertyFilterConstraintDataDefinitionJsonDeserializer.java new file mode 100644 index 0000000000..a767133a4c --- /dev/null +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/PropertyFilterConstraintDataDefinitionJsonDeserializer.java @@ -0,0 +1,107 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.openecomp.sdc.be.datatypes.elements; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; +import org.openecomp.sdc.be.datatypes.enums.FilterValueType; +import org.openecomp.sdc.be.datatypes.enums.PropertyFilterTargetType; +import org.openecomp.sdc.be.utils.PropertyFilterConstraintDataDefinitionHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class PropertyFilterConstraintDataDefinitionJsonDeserializer extends StdDeserializer<PropertyFilterConstraintDataDefinition> { + + private static final Logger LOGGER = LoggerFactory.getLogger(PropertyFilterConstraintDataDefinitionJsonDeserializer.class); + private static final String COULD_NOT_PARSE_CLASS = "Could not parse {} value as {}"; + + public PropertyFilterConstraintDataDefinitionJsonDeserializer() { + this(null); + } + + public PropertyFilterConstraintDataDefinitionJsonDeserializer(Class<?> vc) { + super(vc); + } + + @Override + public PropertyFilterConstraintDataDefinition deserialize(final JsonParser jsonParser, final DeserializationContext context) throws IOException { + final JsonNode node = jsonParser.getCodec().readTree(jsonParser); + + if (node.isTextual()) { + return PropertyFilterConstraintDataDefinitionHelper.convertLegacyConstraint(node.asText()); + } + + final var propertyFilterConstraint = new PropertyFilterConstraintDataDefinition(); + if (node.get("propertyName") != null) { + propertyFilterConstraint.setPropertyName(node.get("propertyName").asText()); + } + if (node.get("capabilityName") != null) { + propertyFilterConstraint.setCapabilityName(node.get("capabilityName").asText()); + } + if (node.get("targetType") != null) { + propertyFilterConstraint.setTargetType(PropertyFilterTargetType.valueOf(node.get("targetType").asText())); + } + if (node.get("operator") != null) { + propertyFilterConstraint.setOperator(ConstraintType.valueOf(node.get("operator").asText())); + } + if (node.get("valueType") != null) { + propertyFilterConstraint.setValueType(FilterValueType.valueOf(node.get("valueType").asText())); + } + propertyFilterConstraint.setValue(deserializeValue(node.get("value"))); + + return propertyFilterConstraint; + } + + private Object deserializeValue(final JsonNode value) { + final ObjectMapper objectMapper = new ObjectMapper(); + try { + return objectMapper.treeToValue(value, ToscaFunction.class); + } catch (final Exception e) { + LOGGER.debug(COULD_NOT_PARSE_CLASS, PropertyFilterConstraintDataDefinition.class.getName(), ToscaFunction.class.getName(), e); + } + try { + return objectMapper.treeToValue(value, Map.class); + } catch (final Exception e) { + LOGGER.debug(COULD_NOT_PARSE_CLASS, PropertyFilterConstraintDataDefinition.class.getName(), Map.class.getName(), e); + } + try { + return objectMapper.treeToValue(value, List.class); + } catch (final Exception e) { + LOGGER.debug(COULD_NOT_PARSE_CLASS, PropertyFilterConstraintDataDefinition.class.getName(), List.class.getName(), e); + } + try { + return objectMapper.treeToValue(value, String.class); + } catch (final Exception e) { + LOGGER.debug(COULD_NOT_PARSE_CLASS, PropertyFilterConstraintDataDefinition.class.getName(), String.class.getName(), e); + } + + return null; + } + +} diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/RequirementNodeFilterPropertyDataDefinition.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/PropertyFilterDataDefinition.java index fff5dce9da..decdc6ea45 100644 --- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/RequirementNodeFilterPropertyDataDefinition.java +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/PropertyFilterDataDefinition.java @@ -15,19 +15,24 @@ */ package org.openecomp.sdc.be.datatypes.elements; -import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields; -import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition; - import java.io.Serializable; import java.util.List; +import org.apache.commons.collections4.CollectionUtils; +import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields; +import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition; -public class RequirementNodeFilterPropertyDataDefinition extends ToscaDataDefinition implements Serializable { +public class PropertyFilterDataDefinition extends ToscaDataDefinition implements Serializable { - public List<String> getConstraints() { - return (List<String>) getToscaPresentationValue(JsonPresentationFields.PROPERTY_FILTER_CONSTRAINT); + public List<PropertyFilterConstraintDataDefinition> getConstraints() { + final List<PropertyFilterConstraintDataDefinition> constraintList = + (List<PropertyFilterConstraintDataDefinition>) getToscaPresentationValue(JsonPresentationFields.PROPERTY_FILTER_CONSTRAINT); + if (CollectionUtils.isEmpty(constraintList)) { + return List.of(); + } + return constraintList; } - public void setConstraints(List<String> constraints) { + public void setConstraints(final List<PropertyFilterConstraintDataDefinition> constraints) { setToscaPresentationValue(JsonPresentationFields.PROPERTY_FILTER_CONSTRAINT, constraints); } @@ -38,4 +43,5 @@ public class RequirementNodeFilterPropertyDataDefinition extends ToscaDataDefini public void setName(String name) { setToscaPresentationValue(JsonPresentationFields.PROPERTY_FILTER_NAME, name); } + } diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/RequirementNodeFilterCapabilityDataDefinition.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/RequirementNodeFilterCapabilityDataDefinition.java index 34dc43760f..637bf5f646 100644 --- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/RequirementNodeFilterCapabilityDataDefinition.java +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/RequirementNodeFilterCapabilityDataDefinition.java @@ -37,12 +37,12 @@ public class RequirementNodeFilterCapabilityDataDefinition extends ToscaDataDefi setToscaPresentationValue(JsonPresentationFields.NAME, name); } - public ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> getProperties() { - return (ListDataDefinition<RequirementNodeFilterPropertyDataDefinition>) getToscaPresentationValue( + public ListDataDefinition<PropertyFilterDataDefinition> getProperties() { + return (ListDataDefinition<PropertyFilterDataDefinition>) getToscaPresentationValue( JsonPresentationFields.PROPERTIES); } - public void setProperties(ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> properties) { + public void setProperties(ListDataDefinition<PropertyFilterDataDefinition> properties) { setToscaPresentationValue(JsonPresentationFields.PROPERTIES, properties); } } diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/RequirementSubstitutionFilterCapabilityDataDefinition.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/RequirementSubstitutionFilterCapabilityDataDefinition.java index 242eb490ef..d5c1525f55 100644 --- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/RequirementSubstitutionFilterCapabilityDataDefinition.java +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/RequirementSubstitutionFilterCapabilityDataDefinition.java @@ -39,12 +39,12 @@ public class RequirementSubstitutionFilterCapabilityDataDefinition extends Tosca setToscaPresentationValue(JsonPresentationFields.NAME, name); } - public ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> getProperties() { - return (ListDataDefinition<RequirementNodeFilterPropertyDataDefinition>) getToscaPresentationValue( + public ListDataDefinition<PropertyFilterDataDefinition> getProperties() { + return (ListDataDefinition<PropertyFilterDataDefinition>) getToscaPresentationValue( JsonPresentationFields.PROPERTIES); } - public void setProperties(final ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> properties) { + public void setProperties(final ListDataDefinition<PropertyFilterDataDefinition> properties) { setToscaPresentationValue(JsonPresentationFields.PROPERTIES, properties); } } diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/SubstitutionFilterDataDefinition.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/SubstitutionFilterDataDefinition.java index beb5aac1d0..36c125a27b 100644 --- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/SubstitutionFilterDataDefinition.java +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/SubstitutionFilterDataDefinition.java @@ -46,12 +46,12 @@ public class SubstitutionFilterDataDefinition extends ToscaDataDefinition implem return getToscaPresentationValue(JsonPresentationFields.TOSCA_ID); } - public ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> getProperties() { - return (ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition>) getToscaPresentationValue( + public ListDataDefinition<SubstitutionFilterPropertyDataDefinition> getProperties() { + return (ListDataDefinition<SubstitutionFilterPropertyDataDefinition>) getToscaPresentationValue( JsonPresentationFields.PROPERTIES); } - public void setProperties(final ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> properties) { + public void setProperties(final ListDataDefinition<SubstitutionFilterPropertyDataDefinition> properties) { setToscaPresentationValue(JsonPresentationFields.PROPERTIES, properties); } diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/RequirementSubstitutionFilterPropertyDataDefinition.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/SubstitutionFilterPropertyDataDefinition.java index b1b53bb4ae..977c374712 100644 --- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/RequirementSubstitutionFilterPropertyDataDefinition.java +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/SubstitutionFilterPropertyDataDefinition.java @@ -20,24 +20,25 @@ package org.openecomp.sdc.be.datatypes.elements; import java.io.Serializable; import java.util.List; -import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields; import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition; -public class RequirementSubstitutionFilterPropertyDataDefinition extends ToscaDataDefinition implements Serializable { +public class SubstitutionFilterPropertyDataDefinition extends ToscaDataDefinition implements Serializable { - public List<String> getConstraints() { - return (List<String>) getToscaPresentationValue(JsonPresentationFields.PROPERTY_FILTER_CONSTRAINT); + private final PropertyFilterDataDefinition propertyFilterDataDefinition = new PropertyFilterDataDefinition(); + + public List<PropertyFilterConstraintDataDefinition> getConstraints() { + return propertyFilterDataDefinition.getConstraints(); } - public void setConstraints(final List<String> constraints) { - setToscaPresentationValue(JsonPresentationFields.PROPERTY_FILTER_CONSTRAINT, constraints); + public void setConstraints(final List<PropertyFilterConstraintDataDefinition> constraints) { + propertyFilterDataDefinition.setConstraints(constraints); } public String getName() { - return (String) getToscaPresentationValue(JsonPresentationFields.PROPERTY_FILTER_NAME); + return propertyFilterDataDefinition.getName(); } public void setName(final String name) { - setToscaPresentationValue(JsonPresentationFields.PROPERTY_FILTER_NAME, name); + propertyFilterDataDefinition.setName(name); } } diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunction.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunction.java index 40664a133c..81b4ec73a9 100644 --- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunction.java +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunction.java @@ -26,7 +26,25 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize; @JsonDeserialize(using = ToscaFunctionJsonDeserializer.class) public interface ToscaFunction { + /** + * Gets the function type. + * + * @return the function type. + */ ToscaFunctionType getType(); + + /** + * Builds the tosca function value as string. + * + * @return the function value as string + */ String getValue(); + /** + * Returns the value mapped as a JSON object. + * + * @return the value as JSON object. + */ + Object getJsonObjectValue(); + } diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunctionJsonDeserializer.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunctionJsonDeserializer.java index 363af1cdeb..c262699cc2 100644 --- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunctionJsonDeserializer.java +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunctionJsonDeserializer.java @@ -146,8 +146,11 @@ public class ToscaFunctionJsonDeserializer extends StdDeserializer<ToscaFunction final var toscaConcatFunction = new ToscaConcatFunction(); final List<ToscaFunctionParameter> functionParameterList = new ArrayList<>(); final JsonNode parametersNode = concatFunctionJsonNode.get("parameters"); + if (parametersNode == null) { + return toscaConcatFunction; + } if (!parametersNode.isArray()) { - throw context.instantiationException(List.class, ""); + throw context.instantiationException(List.class, "Expecting an array for the 'parameters' entry"); } for (final JsonNode parameterNode : parametersNode) { final JsonNode typeJsonNode = parameterNode.get("type"); diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunctionType.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunctionType.java index 4579ac2410..2636c4f6d7 100644 --- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunctionType.java +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunctionType.java @@ -25,6 +25,7 @@ import java.util.Arrays; import java.util.Optional; import lombok.AllArgsConstructor; import lombok.Getter; +import org.apache.commons.lang3.StringUtils; @AllArgsConstructor @Getter @@ -40,6 +41,9 @@ public enum ToscaFunctionType { private final String name; public static Optional<ToscaFunctionType> findType(final String functionType) { + if (StringUtils.isBlank(functionType)) { + return Optional.empty(); + } return Arrays.stream(values()).filter(toscaFunctionType -> toscaFunctionType.getName().equalsIgnoreCase(functionType)).findFirst(); } } diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaGetFunctionDataDefinition.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaGetFunctionDataDefinition.java index f19217e69c..4fe3f3ae13 100644 --- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaGetFunctionDataDefinition.java +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaGetFunctionDataDefinition.java @@ -21,6 +21,7 @@ package org.openecomp.sdc.be.datatypes.elements; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.google.gson.Gson; import java.util.ArrayList; import java.util.List; @@ -47,6 +48,7 @@ public class ToscaGetFunctionDataDefinition implements ToscaFunction, ToscaFunct //necessary for JSON conversions } + @JsonIgnore public boolean isSubProperty() { return propertyPathFromSource != null && propertyPathFromSource.size() > 1; } @@ -58,6 +60,7 @@ public class ToscaGetFunctionDataDefinition implements ToscaFunction, ToscaFunct return new Gson().toJson(getJsonObjectValue()); } + @JsonIgnore @Override public Object getJsonObjectValue() { if (functionType == null) { @@ -126,6 +129,7 @@ public class ToscaGetFunctionDataDefinition implements ToscaFunction, ToscaFunct } } + @JsonIgnore @Override public String getValue() { return this.generatePropertyValue(); diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/ConstraintType.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/ConstraintType.java new file mode 100644 index 0000000000..cef310ea01 --- /dev/null +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/ConstraintType.java @@ -0,0 +1,71 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.openecomp.sdc.be.datatypes.enums; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import lombok.Getter; + +@Getter +public enum ConstraintType { + EQUAL("equal"), + IN_RANGE("in_range", "inRange"), + GREATER_THAN("greater_than", "greaterThan"), + GREATER_OR_EQUAL("greater_or_equal", "greaterOrEqual"), + LESS_OR_EQUAL("less_or_equal", "lessOrEqual"), + LENGTH("length"), + MIN_LENGTH("min_length", "minLength"), + MAX_LENGTH("max_length", "maxLength"), + VALID_VALUES("valid_values", "validValues"), + LESS_THAN("less_than", "lessThan"), + SCHEMA("schema"); + + private static final Set<ConstraintType> comparableConstraints = Set.of(ConstraintType.GREATER_THAN, ConstraintType.LESS_THAN); + private final String type; + private final List<String> typeAlias; + + + ConstraintType(final String type, final String... typeAliases) { + this.type = type; + if (typeAliases == null) { + this.typeAlias = Collections.emptyList(); + } else { + this.typeAlias = Arrays.asList(typeAliases); + } + } + + public static Optional<ConstraintType> findByType(final String type) { + if (type == null) { + return Optional.empty(); + } + return Arrays.stream(ConstraintType.values()) + .filter(constraintType -> constraintType.getType().equals(type) || constraintType.getTypeAlias().contains(type)) + .findFirst(); + } + + public boolean isComparable() { + return comparableConstraints.contains(this); + } + +} diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/FilterValueType.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/FilterValueType.java new file mode 100644 index 0000000000..cacc4b1bac --- /dev/null +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/FilterValueType.java @@ -0,0 +1,53 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.openecomp.sdc.be.datatypes.enums; + +import java.util.Arrays; +import java.util.Optional; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.apache.commons.lang3.StringUtils; + +@AllArgsConstructor +@Getter +public enum FilterValueType { + STATIC("static", "static"), + GET_PROPERTY("get_property", "property"), + GET_INPUT("get_input", "service_input"), + GET_ATTRIBUTE("get_attribute", null), + YAML("yaml", null), + CONCAT("concat", null); + + private final String name; + private final String legacyName; + + public static Optional<FilterValueType> findByName(final String name) { + if (StringUtils.isEmpty(name)) { + return Optional.empty(); + } + return Arrays.stream(FilterValueType.values()).filter(filterValueType -> + filterValueType.getName().equalsIgnoreCase(name) || + (filterValueType.getLegacyName() != null && filterValueType.getLegacyName().equalsIgnoreCase(name)) + ).findFirst(); + } + +} diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/PropertyFilterTargetType.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/PropertyFilterTargetType.java new file mode 100644 index 0000000000..df472508fe --- /dev/null +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/PropertyFilterTargetType.java @@ -0,0 +1,26 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.openecomp.sdc.be.datatypes.enums; + +public enum PropertyFilterTargetType { + CAPABILITY, 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 new file mode 100644 index 0000000000..63c6781b94 --- /dev/null +++ b/common-be/src/main/java/org/openecomp/sdc/be/utils/PropertyFilterConstraintDataDefinitionHelper.java @@ -0,0 +1,198 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.openecomp.sdc.be.utils; + +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.openecomp.sdc.be.datatypes.elements.PropertyFilterConstraintDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ToscaConcatFunction; +import org.openecomp.sdc.be.datatypes.elements.ToscaFunction; +import org.openecomp.sdc.be.datatypes.elements.ToscaFunctionParameter; +import org.openecomp.sdc.be.datatypes.elements.ToscaFunctionType; +import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ToscaStringParameter; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; +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) +public class PropertyFilterConstraintDataDefinitionHelper { + + public static PropertyFilterConstraintDataDefinition convertLegacyConstraint(final String constraint) { + final var propertyFilterConstraint = new PropertyFilterConstraintDataDefinition(); + final Map<String, Object> constraintYaml = new Yaml().load(constraint); + final String propertyName = constraintYaml.keySet().iterator().next(); + propertyFilterConstraint.setPropertyName(propertyName); + final Map<String, Object> operatorYaml = (Map<String, Object>) constraintYaml.get(propertyName); + final String operator = operatorYaml.keySet().iterator().next(); + propertyFilterConstraint.setOperator(ConstraintType.findByType(operator).orElse(null)); + final Object valueYaml = operatorYaml.get(operator); + final Optional<ToscaFunction> toscaFunction = createToscaFunctionFromLegacyConstraintValue(valueYaml); + if (toscaFunction.isPresent()) { + propertyFilterConstraint.setValue(toscaFunction.get()); + } else { + propertyFilterConstraint.setValue(valueYaml); + } + propertyFilterConstraint.setValueType(detectValueType(valueYaml)); + propertyFilterConstraint.setTargetType(PropertyFilterTargetType.PROPERTY); + return propertyFilterConstraint; + } + + public static Optional<ToscaFunction> createToscaFunctionFromLegacyConstraintValue(final Object filterValue) { + if (!(filterValue instanceof Map)) { + return Optional.empty(); + } + final Map<?, ?> filterValueAsMap = (Map<?, ?>) filterValue; + final Set<?> keys = filterValueAsMap.keySet(); + if (keys.size() != 1) { + return Optional.empty(); + } + final Object toscaFunctionTypeObject = keys.iterator().next(); + if (!(toscaFunctionTypeObject instanceof String)) { + return Optional.empty(); + } + final ToscaFunctionType toscaFunctionType = ToscaFunctionType.findType((String) toscaFunctionTypeObject).orElse(null); + if (toscaFunctionType == null) { + return Optional.empty(); + } + switch (toscaFunctionType) { + case GET_INPUT: + return readLegacyGetInputConstraintValue(filterValueAsMap, toscaFunctionTypeObject); + case GET_ATTRIBUTE: + case GET_PROPERTY: + return readLegacyGetPropertyConstraintValue(filterValueAsMap, toscaFunctionTypeObject, toscaFunctionType); + case CONCAT: + return readLegacyConcatConstraintValue(filterValueAsMap, toscaFunctionTypeObject); + default: + return Optional.empty(); + } + } + + public static Optional<FilterValueType> convertFromToscaFunctionType(final ToscaFunctionType toscaFunctionType) { + return FilterValueType.findByName(toscaFunctionType.getName()); + } + + private static Optional<ToscaFunction> readLegacyConcatConstraintValue(Map<?, ?> filterValueAsMap, Object toscaFunctionType) { + final List<Object> concatValue; + try { + concatValue = (List<Object>) filterValueAsMap.get(toscaFunctionType); + } catch (final Exception ignored) { + return Optional.empty(); + } + if (concatValue.isEmpty()) { + return Optional.empty(); + } + final var toscaConcatFunction = new ToscaConcatFunction(); + for (Object parameter : concatValue) { + if (parameter instanceof String) { + final ToscaStringParameter toscaStringParameter = new ToscaStringParameter(); + toscaStringParameter.setValue((String) parameter); + toscaConcatFunction.addParameter(toscaStringParameter); + } else { + createToscaFunctionFromLegacyConstraintValue(parameter) + .ifPresent(toscaFunction -> toscaConcatFunction.addParameter((ToscaFunctionParameter) toscaFunction)); + } + } + return Optional.of(toscaConcatFunction); + } + + 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 List<String> getFunctionValue; + try { + getFunctionValue = (List<String>) filterValueAsMap.get(toscaFunctionType); + } catch (final Exception ignored) { + return Optional.of(toscaGetFunction); + } + 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)); + } + final List<String> propertyPathFromSource = getFunctionValue.subList(1, getFunctionValue.size()); + toscaGetFunction.setPropertyPathFromSource(propertyPathFromSource); + toscaGetFunction.setPropertyName(propertyPathFromSource.get(propertyPathFromSource.size() - 1)); + } + return Optional.of(toscaGetFunction); + } + + private static Optional<ToscaFunction> readLegacyGetInputConstraintValue(Map<?, ?> filterValueAsMap, Object toscaFunctionType) { + final var 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) { + try { + getFunctionValue = (List<String>) filterValueAsMap.get(toscaFunctionType); + } catch (final Exception ignored) { + return Optional.empty(); + } + } else { + return Optional.empty(); + } + + toscaGetFunction.setPropertyPathFromSource(getFunctionValue); + if (!getFunctionValue.isEmpty()) { + toscaGetFunction.setPropertyName(getFunctionValue.get(getFunctionValue.size() - 1)); + } + toscaGetFunction.setPropertySource(PropertySource.SELF); + return Optional.of(toscaGetFunction); + } + + private static FilterValueType detectValueType(final Object value) { + if (value instanceof Map) { + final Map<?, ?> valueAsMap = (Map<?, ?>) value; + if (valueAsMap.containsKey(ToscaFunctionType.CONCAT.getName())) { + return FilterValueType.CONCAT; + } + if (valueAsMap.containsKey(ToscaFunctionType.GET_ATTRIBUTE.getName())) { + return FilterValueType.GET_ATTRIBUTE; + } + if (valueAsMap.containsKey(ToscaFunctionType.GET_PROPERTY.getName())) { + return FilterValueType.GET_PROPERTY; + } + if (valueAsMap.containsKey(ToscaFunctionType.GET_INPUT.getName())) { + return FilterValueType.GET_INPUT; + } + } + + return FilterValueType.STATIC; + } + +} diff --git a/common-be/src/test/java/org/openecomp/sdc/be/datatypes/elements/PropertyFilterConstraintDataDefinitionJsonDeserializerTest.java b/common-be/src/test/java/org/openecomp/sdc/be/datatypes/elements/PropertyFilterConstraintDataDefinitionJsonDeserializerTest.java new file mode 100644 index 0000000000..d40c8f4862 --- /dev/null +++ b/common-be/src/test/java/org/openecomp/sdc/be/datatypes/elements/PropertyFilterConstraintDataDefinitionJsonDeserializerTest.java @@ -0,0 +1,101 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.openecomp.sdc.be.datatypes.elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; +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; + +class PropertyFilterConstraintDataDefinitionJsonDeserializerTest { + private static final Path TEST_RESOURCES_PATH = Path.of("src/test/resources/propertyFilterConstraintDataDefinitionDeserializer"); + + @Test + void testStaticPropertyFilter() throws IOException { + //given + final String propertyFilterAsString = Files.readString(TEST_RESOURCES_PATH.resolve("filter-constraint-static.json")); + //when + final PropertyFilterConstraintDataDefinition actualPropertyFilterConstraint = parseToscaFunction(propertyFilterAsString); + //then + assertEquals(FilterValueType.STATIC, actualPropertyFilterConstraint.getValueType()); + assertEquals(ConstraintType.EQUAL, actualPropertyFilterConstraint.getOperator()); + assertEquals(PropertyFilterTargetType.CAPABILITY, actualPropertyFilterConstraint.getTargetType()); + assertEquals("aCapability", actualPropertyFilterConstraint.getCapabilityName()); + assertEquals("aProperty", actualPropertyFilterConstraint.getPropertyName()); + assertEquals("aStaticValue", actualPropertyFilterConstraint.getValue()); + } + + @Test + void testGetInputToscaFunction() throws IOException { + //given + final String toscaGetInputFunction = Files.readString(TEST_RESOURCES_PATH.resolve("filter-constraint-get-input.json")); + //when + final PropertyFilterConstraintDataDefinition actualPropertyFilterConstraint = parseToscaFunction(toscaGetInputFunction); + //then + assertEquals(FilterValueType.GET_INPUT, actualPropertyFilterConstraint.getValueType()); + assertEquals(ConstraintType.GREATER_THAN, actualPropertyFilterConstraint.getOperator()); + assertEquals(PropertyFilterTargetType.PROPERTY, actualPropertyFilterConstraint.getTargetType()); + assertNull(actualPropertyFilterConstraint.getCapabilityName()); + assertEquals("aProperty", actualPropertyFilterConstraint.getPropertyName()); + assertTrue(actualPropertyFilterConstraint.getValue() instanceof ToscaGetFunctionDataDefinition); + final ToscaGetFunctionDataDefinition toscaGetFunction = (ToscaGetFunctionDataDefinition) actualPropertyFilterConstraint.getValue(); + assertEquals(ToscaFunctionType.GET_INPUT, toscaGetFunction.getType()); + assertEquals(ToscaGetFunctionType.GET_INPUT, toscaGetFunction.getFunctionType()); + assertEquals("aPropertyId", toscaGetFunction.getPropertyUniqueId()); + assertEquals("aProperty", toscaGetFunction.getPropertyName()); + assertEquals(PropertySource.SELF, toscaGetFunction.getPropertySource()); + assertEquals("aServiceId", toscaGetFunction.getSourceUniqueId()); + assertEquals("aService", toscaGetFunction.getSourceName()); + assertEquals(List.of("input", "subProperty"), toscaGetFunction.getPropertyPathFromSource()); + } + + @Test + void testLegacyPropertyFilter() throws IOException { + //given + final String legacyPropertyFilter = Files.readString(TEST_RESOURCES_PATH.resolve("filter-constraint-legacy.txt")); + //when + final PropertyFilterConstraintDataDefinition actualPropertyFilterConstraint = parseToscaFunction(legacyPropertyFilter); + //then + assertEquals(FilterValueType.STATIC, actualPropertyFilterConstraint.getValueType()); + assertEquals(ConstraintType.EQUAL, actualPropertyFilterConstraint.getOperator()); + assertEquals(PropertyFilterTargetType.PROPERTY, actualPropertyFilterConstraint.getTargetType()); + assertNull(actualPropertyFilterConstraint.getCapabilityName()); + assertEquals("propertyName", actualPropertyFilterConstraint.getPropertyName()); + assertEquals("aValue", actualPropertyFilterConstraint.getValue()); + } + + private PropertyFilterConstraintDataDefinition parseToscaFunction(final String propertyFilterConstraintAsJson) throws JsonProcessingException { + return new ObjectMapper().readValue(propertyFilterConstraintAsJson, PropertyFilterConstraintDataDefinition.class); + } +}
\ No newline at end of file diff --git a/common-be/src/test/java/org/openecomp/sdc/be/datatypes/enums/FilterValueTypeTest.java b/common-be/src/test/java/org/openecomp/sdc/be/datatypes/enums/FilterValueTypeTest.java new file mode 100644 index 0000000000..73df545468 --- /dev/null +++ b/common-be/src/test/java/org/openecomp/sdc/be/datatypes/enums/FilterValueTypeTest.java @@ -0,0 +1,75 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.openecomp.sdc.be.datatypes.enums; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class FilterValueTypeTest { + + @Test + void findByEmptyNameTest() { + assertTrue(FilterValueType.findByName(null).isEmpty()); + assertTrue(FilterValueType.findByName("").isEmpty()); + } + + @Test + void findByNameNotFoundTest() { + assertTrue(FilterValueType.findByName("thisNameDoesNotExist").isEmpty()); + } + + @ParameterizedTest(name = "{index}: {0} should be {1}") + @MethodSource("getValueTypeForFindByName") + void test(final String nameToFind, final FilterValueType filterValueType) { + final Optional<FilterValueType> actualFilterValueType = FilterValueType.findByName(nameToFind); + assertTrue(actualFilterValueType.isPresent()); + assertEquals(actualFilterValueType.get(), filterValueType); + } + + private static Stream<Arguments> getValueTypeForFindByName() { + final Stream<Arguments> allFilterValueTypeNameArguments = Arrays.stream(FilterValueType.values()) + .map(filterValueType -> Arguments.of(filterValueType.getName(), filterValueType)); + final Stream<Arguments> allFilterValueTypeNameIgnoreCaseArguments = Arrays.stream(FilterValueType.values()) + .map(filterValueType -> Arguments.of(filterValueType.getName().toUpperCase(), filterValueType)); + + final Stream<Arguments> legacyArguments = Stream.of( + Arguments.of(FilterValueType.GET_INPUT.getLegacyName(), FilterValueType.GET_INPUT), + Arguments.of(FilterValueType.GET_INPUT.getLegacyName().toUpperCase(), FilterValueType.GET_INPUT), + Arguments.of(FilterValueType.GET_PROPERTY.getLegacyName(), FilterValueType.GET_PROPERTY), + Arguments.of(FilterValueType.GET_PROPERTY.getLegacyName().toUpperCase(), FilterValueType.GET_PROPERTY) + ); + + return Stream.of(allFilterValueTypeNameIgnoreCaseArguments, allFilterValueTypeNameArguments, legacyArguments) + .reduce(Stream::concat) + .orElseGet(Stream::empty); + } + +}
\ No newline at end of file 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 new file mode 100644 index 0000000000..86548fa1d5 --- /dev/null +++ b/common-be/src/test/java/org/openecomp/sdc/be/utils/PropertyFilterConstraintDataDefinitionHelperTest.java @@ -0,0 +1,196 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.openecomp.sdc.be.utils; + +import static org.junit.jupiter.api.Assertions.*; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import org.junit.jupiter.api.Test; +import org.openecomp.sdc.be.datatypes.elements.PropertyFilterConstraintDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ToscaConcatFunction; +import org.openecomp.sdc.be.datatypes.elements.ToscaFunctionType; +import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ConstraintType; +import org.openecomp.sdc.be.datatypes.enums.FilterValueType; +import org.openecomp.sdc.be.datatypes.enums.PropertySource; +import org.openecomp.sdc.be.datatypes.tosca.ToscaGetFunctionType; + +class PropertyFilterConstraintDataDefinitionHelperTest { + + private static final Path RESOURCE_PATH = Path.of("src", "test", "resources", "nodeFilter", "constraints"); + + @Test + void convertLegacyConstraintGetInputTest() throws IOException { + final var propertyFilterConstraint = + PropertyFilterConstraintDataDefinitionHelper.convertLegacyConstraint(readConstraintFile("legacy-get_input.yaml")); + assertPropertyFilterConstraint(propertyFilterConstraint, "flavour_id", null, ConstraintType.GREATER_OR_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("inputName"), "inputName", null); + } + + @Test + void convertLegacyConstraintGetInputSubPathTest() throws IOException { + final PropertyFilterConstraintDataDefinition propertyFilterConstraint = + PropertyFilterConstraintDataDefinitionHelper.convertLegacyConstraint(readConstraintFile("legacy-get_input-subProperty.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("inputName", "inputSubProperty", "inputSubSubProperty"), "inputSubSubProperty", null); + } + + @Test + void convertLegacyConstraintGetPropertyFromInstanceTest() throws IOException { + final PropertyFilterConstraintDataDefinition propertyFilterConstraint = + PropertyFilterConstraintDataDefinitionHelper.convertLegacyConstraint(readConstraintFile("legacy-get_property-from-instance.yaml")); + assertPropertyFilterConstraint(propertyFilterConstraint, "flavour_id", null, ConstraintType.EQUAL, FilterValueType.GET_PROPERTY); + assertTrue(propertyFilterConstraint.getValue() instanceof ToscaGetFunctionDataDefinition); + final var toscaGetFunction = (ToscaGetFunctionDataDefinition) propertyFilterConstraint.getValue(); + assertToscaGetFunction(toscaGetFunction, ToscaFunctionType.GET_PROPERTY, ToscaGetFunctionType.GET_PROPERTY, PropertySource.INSTANCE, + List.of("property", "subProperty"), "subProperty", "Instance Name"); + } + + @Test + void convertLegacyConstraintGetAttributeFromInstanceTest() throws IOException { + final PropertyFilterConstraintDataDefinition propertyFilterConstraint = + PropertyFilterConstraintDataDefinitionHelper.convertLegacyConstraint(readConstraintFile("legacy-get_attribute-from-instance.yaml")); + assertPropertyFilterConstraint(propertyFilterConstraint, "flavour_id", null, ConstraintType.EQUAL, FilterValueType.GET_ATTRIBUTE); + assertTrue(propertyFilterConstraint.getValue() instanceof ToscaGetFunctionDataDefinition); + final var toscaGetFunction = (ToscaGetFunctionDataDefinition) propertyFilterConstraint.getValue(); + assertToscaGetFunction(toscaGetFunction, ToscaFunctionType.GET_ATTRIBUTE, ToscaGetFunctionType.GET_ATTRIBUTE, PropertySource.INSTANCE, + List.of("property", "subProperty"), "subProperty", "Instance Name"); + } + + + @Test + void convertLegacyConstraintGetPropertyFromSelfTest() throws IOException { + final PropertyFilterConstraintDataDefinition propertyFilterConstraint = + PropertyFilterConstraintDataDefinitionHelper.convertLegacyConstraint(readConstraintFile("legacy-get_property-from-self.yaml")); + assertPropertyFilterConstraint(propertyFilterConstraint, "flavour_id", null, ConstraintType.EQUAL, FilterValueType.GET_PROPERTY); + assertTrue(propertyFilterConstraint.getValue() instanceof ToscaGetFunctionDataDefinition); + final var toscaGetFunction = (ToscaGetFunctionDataDefinition) propertyFilterConstraint.getValue(); + assertToscaGetFunction(toscaGetFunction, ToscaFunctionType.GET_PROPERTY, ToscaGetFunctionType.GET_PROPERTY, PropertySource.SELF, + List.of("property", "subProperty"), "subProperty", null); + } + + @Test + void convertLegacyConstraintGetAttributeFromSelfTest() throws IOException { + final PropertyFilterConstraintDataDefinition propertyFilterConstraint = + PropertyFilterConstraintDataDefinitionHelper.convertLegacyConstraint(readConstraintFile("legacy-get_attribute-from-self.yaml")); + assertPropertyFilterConstraint(propertyFilterConstraint, "flavour_id", null, ConstraintType.EQUAL, FilterValueType.GET_ATTRIBUTE); + assertTrue(propertyFilterConstraint.getValue() instanceof ToscaGetFunctionDataDefinition); + final var toscaGetFunction = (ToscaGetFunctionDataDefinition) propertyFilterConstraint.getValue(); + assertToscaGetFunction(toscaGetFunction, ToscaFunctionType.GET_ATTRIBUTE, ToscaGetFunctionType.GET_ATTRIBUTE, PropertySource.SELF, + List.of("property", "subProperty"), "subProperty", null); + } + + @Test + void convertLegacyConstraintStaticTest() throws IOException { + final PropertyFilterConstraintDataDefinition propertyFilterConstraint = + PropertyFilterConstraintDataDefinitionHelper.convertLegacyConstraint(readConstraintFile("legacy-static.yaml")); + assertPropertyFilterConstraint(propertyFilterConstraint, "vnf_profile", null, ConstraintType.EQUAL, FilterValueType.STATIC); + assertTrue(propertyFilterConstraint.getValue() instanceof Map); + final Map<String, Object> value = (Map<String, Object>) propertyFilterConstraint.getValue(); + assertEquals("1", value.get("instantiation_level")); + assertEquals(1, value.get("max_number_of_instances")); + assertEquals(1, value.get("min_number_of_instances")); + } + + @Test + void convertLegacyConstraintConcatTest() throws IOException { + final PropertyFilterConstraintDataDefinition propertyFilterConstraint = + PropertyFilterConstraintDataDefinitionHelper.convertLegacyConstraint(readConstraintFile("concat.yaml")); + assertPropertyFilterConstraint(propertyFilterConstraint, "descriptor_id", null, ConstraintType.EQUAL, FilterValueType.CONCAT); + assertTrue(propertyFilterConstraint.getValue() instanceof ToscaConcatFunction); + final ToscaConcatFunction toscaConcatFunction = (ToscaConcatFunction) propertyFilterConstraint.getValue(); + assertEquals(3, toscaConcatFunction.getParameters().size()); + assertEquals(ToscaFunctionType.STRING, toscaConcatFunction.getParameters().get(0).getType()); + assertEquals("aString", toscaConcatFunction.getParameters().get(0).getValue()); + assertEquals(ToscaFunctionType.GET_INPUT, toscaConcatFunction.getParameters().get(1).getType()); + assertEquals(ToscaFunctionType.STRING, toscaConcatFunction.getParameters().get(2).getType()); + assertEquals("anotherString", toscaConcatFunction.getParameters().get(2).getValue()); + } + + private static void assertPropertyFilterConstraint(final PropertyFilterConstraintDataDefinition propertyFilterConstraint, + final String propertyName, final String capabilityName, final ConstraintType constraintType, + final FilterValueType filterValueType) { + assertEquals(propertyName, propertyFilterConstraint.getPropertyName()); + assertEquals(capabilityName, propertyFilterConstraint.getCapabilityName()); + assertEquals(constraintType, propertyFilterConstraint.getOperator()); + assertEquals(filterValueType, propertyFilterConstraint.getValueType()); + } + + private void assertToscaGetFunction(final ToscaGetFunctionDataDefinition actualToscaGetFunction, + final ToscaFunctionType expectedToscaFunctionType, final ToscaGetFunctionType expectedToscaFunctionGetType, + final PropertySource expectedPropertySource, final List<String> expectedPropertyPathFromSource, + final String expectedPropertyName, final String expectedSourceName) { + assertEquals(expectedToscaFunctionType, actualToscaGetFunction.getType()); + assertEquals(expectedToscaFunctionGetType, actualToscaGetFunction.getFunctionType()); + assertEquals(expectedPropertySource, actualToscaGetFunction.getPropertySource()); + assertEquals(expectedPropertyPathFromSource, actualToscaGetFunction.getPropertyPathFromSource()); + assertEquals(expectedPropertyName, actualToscaGetFunction.getPropertyName()); + assertEquals(expectedSourceName, actualToscaGetFunction.getSourceName()); + assertNull(actualToscaGetFunction.getPropertyUniqueId()); + assertNull(actualToscaGetFunction.getSourceUniqueId()); + } + + @Test + void convertFromToscaFunctionTypeTest() { + Optional<FilterValueType> filterValueType = + PropertyFilterConstraintDataDefinitionHelper.convertFromToscaFunctionType(ToscaFunctionType.GET_PROPERTY); + assertTrue(filterValueType.isPresent()); + assertEquals(FilterValueType.GET_PROPERTY, filterValueType.get()); + + filterValueType = + PropertyFilterConstraintDataDefinitionHelper.convertFromToscaFunctionType(ToscaFunctionType.GET_INPUT); + assertTrue(filterValueType.isPresent()); + assertEquals(FilterValueType.GET_INPUT, filterValueType.get()); + + filterValueType = + PropertyFilterConstraintDataDefinitionHelper.convertFromToscaFunctionType(ToscaFunctionType.GET_ATTRIBUTE); + assertTrue(filterValueType.isPresent()); + assertEquals(FilterValueType.GET_ATTRIBUTE, filterValueType.get()); + + filterValueType = + PropertyFilterConstraintDataDefinitionHelper.convertFromToscaFunctionType(ToscaFunctionType.YAML); + assertTrue(filterValueType.isPresent()); + assertEquals(FilterValueType.YAML, filterValueType.get()); + + filterValueType = + PropertyFilterConstraintDataDefinitionHelper.convertFromToscaFunctionType(ToscaFunctionType.CONCAT); + assertTrue(filterValueType.isPresent()); + assertEquals(FilterValueType.CONCAT, filterValueType.get()); + + assertTrue(PropertyFilterConstraintDataDefinitionHelper.convertFromToscaFunctionType(ToscaFunctionType.STRING).isEmpty()); + } + + private String readConstraintFile(final String fileName) throws IOException { + return Files.readString(RESOURCE_PATH.resolve(fileName)); + } +}
\ No newline at end of file diff --git a/common-be/src/test/resources/nodeFilter/constraints/concat.yaml b/common-be/src/test/resources/nodeFilter/constraints/concat.yaml new file mode 100644 index 0000000000..28f6aadec7 --- /dev/null +++ b/common-be/src/test/resources/nodeFilter/constraints/concat.yaml @@ -0,0 +1,8 @@ +descriptor_id: + equal: + concat: + - aString + - get_input: + - vnfProfileInput + - instantiation_level + - anotherString
\ No newline at end of file diff --git a/common-be/src/test/resources/nodeFilter/constraints/legacy-get_attribute-from-instance.yaml b/common-be/src/test/resources/nodeFilter/constraints/legacy-get_attribute-from-instance.yaml new file mode 100644 index 0000000000..039c4aeacc --- /dev/null +++ b/common-be/src/test/resources/nodeFilter/constraints/legacy-get_attribute-from-instance.yaml @@ -0,0 +1,6 @@ +flavour_id: + equal: + get_attribute: + - Instance Name + - property + - subProperty
\ No newline at end of file diff --git a/common-be/src/test/resources/nodeFilter/constraints/legacy-get_attribute-from-self.yaml b/common-be/src/test/resources/nodeFilter/constraints/legacy-get_attribute-from-self.yaml new file mode 100644 index 0000000000..3afd65d19f --- /dev/null +++ b/common-be/src/test/resources/nodeFilter/constraints/legacy-get_attribute-from-self.yaml @@ -0,0 +1,6 @@ +flavour_id: + equal: + get_attribute: + - SELF + - property + - subProperty
\ No newline at end of file diff --git a/common-be/src/test/resources/nodeFilter/constraints/legacy-get_input-subProperty.yaml b/common-be/src/test/resources/nodeFilter/constraints/legacy-get_input-subProperty.yaml new file mode 100644 index 0000000000..ba9bc3ac74 --- /dev/null +++ b/common-be/src/test/resources/nodeFilter/constraints/legacy-get_input-subProperty.yaml @@ -0,0 +1,6 @@ +flavour_id: + equal: + get_input: + - inputName + - inputSubProperty + - inputSubSubProperty
\ No newline at end of file diff --git a/common-be/src/test/resources/nodeFilter/constraints/legacy-get_input.yaml b/common-be/src/test/resources/nodeFilter/constraints/legacy-get_input.yaml new file mode 100644 index 0000000000..4b17734e86 --- /dev/null +++ b/common-be/src/test/resources/nodeFilter/constraints/legacy-get_input.yaml @@ -0,0 +1,4 @@ +flavour_id: + greater_or_equal: + get_input: + - inputName
\ No newline at end of file diff --git a/common-be/src/test/resources/nodeFilter/constraints/legacy-get_property-from-instance.yaml b/common-be/src/test/resources/nodeFilter/constraints/legacy-get_property-from-instance.yaml new file mode 100644 index 0000000000..67772d1666 --- /dev/null +++ b/common-be/src/test/resources/nodeFilter/constraints/legacy-get_property-from-instance.yaml @@ -0,0 +1,6 @@ +flavour_id: + equal: + get_property: + - Instance Name + - property + - subProperty
\ No newline at end of file diff --git a/common-be/src/test/resources/nodeFilter/constraints/legacy-get_property-from-self.yaml b/common-be/src/test/resources/nodeFilter/constraints/legacy-get_property-from-self.yaml new file mode 100644 index 0000000000..89c78d1a3b --- /dev/null +++ b/common-be/src/test/resources/nodeFilter/constraints/legacy-get_property-from-self.yaml @@ -0,0 +1,6 @@ +flavour_id: + equal: + get_property: + - SELF + - property + - subProperty
\ No newline at end of file diff --git a/common-be/src/test/resources/nodeFilter/constraints/legacy-static.yaml b/common-be/src/test/resources/nodeFilter/constraints/legacy-static.yaml new file mode 100644 index 0000000000..783316fff7 --- /dev/null +++ b/common-be/src/test/resources/nodeFilter/constraints/legacy-static.yaml @@ -0,0 +1,5 @@ +vnf_profile: + equal: + instantiation_level: '1' + max_number_of_instances: 1 + min_number_of_instances: 1
\ No newline at end of file diff --git a/common-be/src/test/resources/propertyFilterConstraintDataDefinitionDeserializer/filter-constraint-get-input.json b/common-be/src/test/resources/propertyFilterConstraintDataDefinitionDeserializer/filter-constraint-get-input.json new file mode 100644 index 0000000000..3ceee51804 --- /dev/null +++ b/common-be/src/test/resources/propertyFilterConstraintDataDefinitionDeserializer/filter-constraint-get-input.json @@ -0,0 +1,16 @@ +{ + "propertyName": "aProperty", + "targetType": "PROPERTY", + "operator": "GREATER_THAN", + "valueType": "GET_INPUT", + "value": { + "type": "GET_INPUT", + "functionType": "GET_INPUT", + "propertyName": "aProperty", + "propertyUniqueId": "aPropertyId", + "propertySource": "SELF", + "sourceName": "aService", + "sourceUniqueId": "aServiceId", + "propertyPathFromSource": ["input", "subProperty"] + } +}
\ No newline at end of file diff --git a/common-be/src/test/resources/propertyFilterConstraintDataDefinitionDeserializer/filter-constraint-legacy.txt b/common-be/src/test/resources/propertyFilterConstraintDataDefinitionDeserializer/filter-constraint-legacy.txt new file mode 100644 index 0000000000..925c878d5f --- /dev/null +++ b/common-be/src/test/resources/propertyFilterConstraintDataDefinitionDeserializer/filter-constraint-legacy.txt @@ -0,0 +1 @@ +"{ \"propertyName\": { \"equal\": \"aValue\" } }"
\ No newline at end of file diff --git a/common-be/src/test/resources/propertyFilterConstraintDataDefinitionDeserializer/filter-constraint-static.json b/common-be/src/test/resources/propertyFilterConstraintDataDefinitionDeserializer/filter-constraint-static.json new file mode 100644 index 0000000000..4faee8ab1a --- /dev/null +++ b/common-be/src/test/resources/propertyFilterConstraintDataDefinitionDeserializer/filter-constraint-static.json @@ -0,0 +1,8 @@ +{ + "propertyName": "aProperty", + "capabilityName": "aCapability", + "targetType": "CAPABILITY", + "operator": "EQUAL", + "valueType": "STATIC", + "value": "aStaticValue" +}
\ No newline at end of file diff --git a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ServiceDependenciesEditor.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ServiceDependenciesEditor.java index aba5f74063..f5f58582ec 100644 --- a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ServiceDependenciesEditor.java +++ b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ServiceDependenciesEditor.java @@ -62,8 +62,7 @@ public class ServiceDependenciesEditor extends AbstractPageObject { properties.selectByVisibleText(property.getName()); final Select logicalOperator = new Select(webDriver.findElement(By.xpath(XpathSelector.CONSTRAINT_OPERATOR.xPath))); logicalOperator.selectByVisibleText(property.getLogicalOperator().getOperator()); - final Select functionType = new Select(webDriver.findElement(By.xpath(XpathSelector.FUNCTION_TYPE.xPath))); - functionType.selectByVisibleText(property.getSource()); + findElement(XpathSelector.VALUE_TYPE_STATIC.getXPath()).click(); try { addRuleAssignedValue(property); } catch (Exception e) { @@ -123,8 +122,8 @@ public class ServiceDependenciesEditor extends AbstractPageObject { SERVICE_DEPENDENCIES_EDITOR("//service-dependencies-editor"), SERVICE_PROPERTY_NAME("//*[@data-tests-id='servicePropertyName']/select"), CONSTRAINT_OPERATOR("//*[@data-tests-id='constraintOperator']/select"), - FUNCTION_TYPE("//*[@data-tests-id='functionType']/select"), - SOURCE_TYPE("//*[@data-tests-id='sourceType']/select"), + VALUE_TYPE_STATIC("//*[@data-tests-id='value-type-static']"), + VALUE_TYPE_TOSCA_FUNCTION("//*[@data-tests-id='value-type-tosca-function']"), RULE_ASSIGNED_VALUE("//*[@data-tests-id='ruleAssignedValue']//*[self::input or self::select]"), RULE_ASSIGNED_VALUE_ADD_TO_LIST("//a[@data-tests-id = 'add-to-list-%s']"), RULE_ASSIGNED_LIST_VALUE("//*[@data-tests-id='value-prop-%s.%d']"), |